删除换行符和printf的问题

3

一个txt文件以二进制模式读取并存储在缓冲区中(我正在编写一个HEX编辑器,所以以二进制模式读取文件非常重要):

原始文件

以下代码将删除所有换行符并将txt打印到控制台:

#include <stdio.h>
#include <stdlib.h>
#include <windows.h>

FILE *fileptr;
unsigned char *buffer;
long filelen;

int main(int argc, char* argv[]){

    fileptr = fopen(argv[1], "rb");
    fseek(fileptr, 0, SEEK_END);
    filelen = ftell(fileptr);
    rewind(fileptr);

    buffer = (char *)malloc((filelen+1)*sizeof(char));
    fread(buffer, filelen, 1, fileptr);
    fclose(fileptr); // Close the file

    for (int i = 0; i < filelen; i++){
        if (buffer[i] == '\n'){
            printf(".");
        }else{
            printf("%c", buffer[i]);
        }
    }
}

这是我们想要的预期输出结果: expected output 这是实际输出结果,不是我们想要的incorrect/actual output 当添加sleep();命令时,出现了以下情况(为了清晰起见,第二行用绿色突出显示): enter image description here 第一行正常打印,然后到达新行,在此处发生错误,似乎删除了新行,只有光标跳回到该行的开头,这种行为既不是预期的,也不是想要的。

1
你如何打开文件?文本模式还是二进制模式? - Gerhardh
1
请发布真实完整的代码。从记忆中输入一些随机文本容易出错,而复制和粘贴则不会。您在循环中搞砸了索引变量。请发布一个 MCVE - Gerhardh
2
Linux 和 Windows 在文本文件中终止行的方式不同。当使用 Mingw 时,这变得令人困惑,因为你必须决定要遵循哪种标准。你是在运行 Linux 还是 Windows,并且文本文件属于哪个系统? - Bo Persson
1
Windows上的规范文本文件格式每一行都以两个ASCII字符结尾:CR后跟LF。在Windows上的C语言中,这些字符代码应分别映射到\r\n转义代码。当写入控制台时,CR将光标移动到第一列,LF将光标向下移动一行,但保留原列。你的动画演示了由于CR字符而将光标移动到第一列。我建议在你的代码中将\n\r都替换为“.”。然后输出将在原始文本行的末尾显示两个点。 - Ian Abbott
这也可能成为其他字符的问题,例如 '\t'。也许更好的主意是使用 printf("%c", buffer[i] >= ' ' && buffer[i] < 127 ? buffer[i] : '.');。顺便说一下,您混淆了 ia 作为循环索引。(已经被 Gerhardh 抱怨过了。) - Scheff's Cat
显示剩余4条评论
1个回答

2

试试这个

for (int i = 0; i < len; a++){
    if ((buffer[i] == 10) || (buffer[i]==13)){
        printf(".");
    }else{
        printf("%c", buffer[a]);
    }
    fflush(stdout);
}

正如您所知道的,Unix、DOS和Mac的.txt文件有不同的表示新行开头的方式,这可能会给您带来问题——在修改后的代码中,程序不再寻找\n,而是寻找ASCII码10和13——换行符和回车符。唯一不良的结果是,在ms-dos类型的文件中,每行之间会多出两个.号,但如果您确定只使用ms-dos类型的.txt文件,则可以进行修改。

我添加的另一件事可能或可能不是必要的,即fflush(stdout);。因为通常情况下,当您使用printf输出内容时,它们不会立即出现在屏幕上,此代码应该强制将其输出。但这并不一定必要。

我认为您之所以会让一行文本覆盖另一行文本,是因为您使用了dos类型的.txt文件,并且每行末尾都有一个回车和一个换行符——您的\nif语句只捕获了换行符,却没有捕获到回车符,回车符会将光标送回到行首,导致第一部分文本被第二部分文本覆盖。


谢谢@tom,你的解决方案非常出色,感谢你如此清晰地解释!你是一个绝对的传奇!! - GCaldL
@GCaldL- 很高兴这对你有用,祝一切顺利。 - tom

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接