У вас большое количество мелких проблем для решения. Во-первых, если вы не используете несоответствующий компилятор, соответствующие объявления для main
являются int main (void)
и int main (int argc, char **argv)
(которые вы увидите написанными с эквивалентным char *argv[]
). См .: Стандарт C11 §5.1.2.2.1 Запуск программы p1 (черновик n1570) . См. Также: Что должно возвращать main () в C и C ++?
Далее c
должен иметь тип int
, а не тип char
, чтобы соответствовать EOF
, например,
int c, last = 0; /* c must be type int, not char to match EOF */
Не кодировать имена файлов жестко и не использовать magic-numbers . Либо передайте имя файла в качестве аргумента main()
, либо запросите его в вашей программе. Вы можете удобно взять имя файла для открытия или чтения из stdin
по default
с помощью троичного оператора следующим образом:
/* use filename provided as 1st argument (stdin by default) */
FILE *fp = argc > 1 ? fopen (argv[1], "r") : stdin;
Наконец, к вашему коду, так как вы хотите Префикс каждой строки с номером строки, вы должны вывести номер строки для первой строки Перед вы выводите символы для этой строки (и то же самое для каждой последующей строки). Вы можете сделать это, просто выдав сначала число (используя спецификатор преобразования "%06zu "
с модификаторами '0'
для вывода начальных нулей и ширина поля 6
в соответствии с указанным форматом). Также обратите внимание, что тип вашего счетчика ln
изменен с int
на size_t
, рекомендуемый тип для счетчиков в C (у вас не может быть отрицательного количества строк).
Соединяя это с использованием символа last
, чтобы разрешить проверку '\n'
перед выводом ваших символов, вы можете сделать:
#include <stdio.h>
int main (int argc, char **argv) {
int c, last = 0; /* c must be type int, not char to match EOF */
size_t ln = 1; /* use size_t for counters */
/* use filename provided as 1st argument (stdin by default) */
FILE *fp = argc > 1 ? fopen (argv[1], "r") : stdin;
if (!fp) { /* validate file open for reading */
perror ("file open failed");
return 1;
}
printf ("%06zu ", ln++); /* output line 1 number */
while ((c = getc(fp)) != EOF) { /* read each character */
if (last) /* test if last set */
putchar (last); /* output all characters */
if (last == '\n') /* test if last is newline */
printf ("%06zu ", ln++); /* output next line number */
last = c; /* set last to c */
}
putchar (last); /* output final character */
if (last != '\n') /* check POSIX eof */
putchar('\n'); /* tidy up with newline */
if (fp != stdin) /* close file if not stdin */
fclose (fp);
return 0;
}
( примечание: проверка if (last != '\n')
после выхода из цикла проверяет наличие строки POSIX, заканчивающейся на последней строке, и если нет, вы должны вручную вывести '\n'
, чтобы ваша программа совместима с POSIX)
Пример входного файла
$ cat ../dat/captnjack.txt
This is a tale
Of Captain Jack Sparrow
A Pirate So Brave
On the Seven Seas.
Пример использования / Вывод
$ ./bin/linenos ../dat/captnjack_noeol.txt
000001 This is a tale
000002 Of Captain Jack Sparrow
000003 A Pirate So Brave
000004 On the Seven Seas.
Посмотрите вещи и дайте мне знать, если у вас есть дополнительные вопросы.
( также обратите внимание: , если ваш компилятор не поддерживает спецификатор преобразования zu
для size_t
, удалите 'z'
и выведите его как значение без знака - VS10 или более ранние версии не поддерживают zu
)