Это файл:
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
выход LINE 20 был потерян! (на самом деле я нашел isis в строке выходов 2 (так подключено), но если я прокомментирую СТРОКУ 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
Ага? есть ли какая-то проблема в bash wsl??
@SupportUkraine Да, я уверен. И если я скопирую этот код в Windows и запущу его, результат будет правильным. (первоначально запускался в версии gcc 11.4.0 (WSL Ubuntu 11.4.0-1ubuntu1~22.04))
Ваш файл был отредактирован в Windows, и в нем все еще есть символы \r. Попробуйте посмотреть, что произойдет, если вы напечатаете строку с \r, а затем еще одну строку.
@D yh Кажется, система хранит в буфере также символ возврата каретки cr.
Входной текстовый файл представляет собой файл DOS, строки которого заканчиваются последовательностью \r\n. Вам необходимо преобразовать его в стандартный текстовый файл Unix, строки которого заканчиваются на \n и без символа \r. Для этого существуют различные утилиты, например dos2unix, которые вы можете установить. Достаточно мощные текстовые редакторы также могут это сделать. Все, что вам действительно нужно сделать, это удалить из файла все символы \r.
Если вы используете buffer[strcspn(buffer, "\r\n")] = 0; для удаления концов строк, это безопасно и подходит для всех вариантов.





DOS и Windows сохраняют "\r\n" как символ новой строки (в Unix и Linux это "\n").
Кажется, ваш входной файл закодирован в формате DOS. Итак, вы заменяете "\n", но "\r" остается в строке.
Когда вы printf("\r"), курсор перемещается в первый столбец текущей строки. Таким образом, вы записываете первые символы предыдущей напечатанной строки.
На самом деле такое поведение "\r" весьма полезно во многих сценариях. Например, мы можем создать простые индикаторы выполнения в нашем коде C:
#include <stdio.h>
#include <stdlib.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");
return EXIT_SUCCESS;
}
Вывод представляет собой индикатор выполнения:
50.0% =========================
Мне нравятся твои ответы, ты даже рассказал мне, как использовать эту функцию. большое спасибо.
я пробовал
fflush(stdout);