这是文件:
this
is
a
sample
of
normal
words
当我尝试删除
\n
时,我发现 printf 没有打印任何内容。
这是我的c代码:
int main(int argc, char *argv[]) {
FILE *fp;
char buffer[64];
fp = fopen(argv[1], "r");
if (fp == NULL) {
fprintf(stderr, "File doesn't exist\n");
exit(1);
}
while (fgets(buffer, sizeof buffer, fp) != NULL) {
if (buffer[strlen(buffer) - 1] == '\n') {
printf(">> 1 >> %s", buffer); //!!! LINE 18 !!!
buffer[strlen(buffer) - 1] = '\0';
printf(">> 2 >> %s", buffer); //!!! LINE 20 !!!
}
}
fclose(fp);
exit(0);
}
这是输出:
>> 1 >> this
>> 1 >> isis
>> 1 >> as
>> 1 >> sample
>> 1 >> ofmple
>> 1 >> normal
>> 1 >> wordsl
第20行的输出丢失了! (事实上,我在输出的第 2 行中发现了
isis
(如此连线),但如果我注释第 18 行,输出将完全消失)
然后如果我将 LINE 20 从
printf(">> 2 >> %s", buffer);
替换为 printf(">> 2 >> %s\n", buffer);
输出变为:
>> 1 >> this
>> 2 >> this
>> 1 >> is
>> 2 >> is
>> 1 >> a
>> 2 >> a
>> 1 >> sample
>> 2 >> sample
>> 1 >> of
>> 2 >> of
>> 1 >> normal
>> 2 >> normal
>> 1 >> words
>> 2 >> words
printf 发生了什么?为什么如果没有
\n
printf 不打印任何内容。
WSL:gcc版本11.4.0(Ubuntu 11.4.0-1ubuntu1~22.04)
我发现如果我将这个c代码复制到windows并在cmd中运行它,输出是正确的:
>> 1 >> this
>> 2 >> this>> 1 >> is
>> 2 >> is>> 1 >> a
>> 2 >> a>> 1 >> sample
>> 2 >> sample>> 1 >> of
>> 2 >> of>> 1 >> normal
>> 2 >> normal>> 1 >> words
>> 2 >> words
啊哈? wsl的bash有问题吗?
DOS 和 Windows 将
"\r\n"
存储为换行符(在 Unix 和 Linux 中为 "\n"
)。
看来您的输入文件是以 DOS 格式编码的。因此,您替换了 "\n"
,但 "\r"
仍保留在字符串中。
当您
printf("\r")
时,会将光标移动到当前行的第一列。因此,请重写先前打印字符串的第一个字符。
实际上,
"\r"
的这种行为在很多场景下都是非常有用的。例如,我们可以在 C 代码中创建简单的进度条:
#include <stdio.h>
#include <unistd.h>
#define MAX 1500
int main()
{
for (int i = 1; i <= MAX; i++) {
float percent = 100 * i / (float) MAX;
printf("\r%5.1f%% ", percent);
for (int p = 0; p < percent/2; p++)
printf("=");
fflush(stdout);
usleep(10000);
}
printf(" [DONE] \n");
}