Для начала вам нужно просмотреть Почему while (! Feof (file)) всегда неверно?
При чтении строк данных из файла используйте Линейно-ориентированная функция ввода, такая как fgets()
или POSIX getline()
для чтения всей строки в буфер, а затем синтаксический анализ необходимых значений из буфера.Это обеспечивает два основных преимущества:
, которые вы можете независимо проверить:
a.чтение данных из файла;и
б.парсинг значений из строки.
то, что остается во входном буфере, не зависит от используемого спецификатора формата scanf
.(целая строка всегда используется, поэтому вы всегда готовы читать с начала следующей строки для вашего следующего ввода)
Каждый раз, когда вы читаете из файла, просто укажитебуфер достаточного размера при использовании fgets
(не экономьте на размере буфера!).POSIX getline
автоматически выделит необходимое пространство.Затем используйте sscanf
, чтобы проанализировать любую информацию, необходимую из строки (или strtok
или strsep
или любую другую функцию, которая вам нравится, чтобы найти определенную точку в буфере).
Если вы не анализируете информацию и вам нужна вся строка, просто обрежьте '\n'
от конца буфера, перезаписав его nul-символом .strcspn
предоставляет простой метод или используйте strlen
, чтобы получить длину, а затем перезаписать последний символ.
В вашем случае вам просто нужно обработать первую строку иначе, чем остальные строки - так что оставьтесчетчик строк инициализируется нулем в начале.Если ваш счетчик строк равен нулю, то анализируйте 3-целочисленные значения из строки, в противном случае сделайте все, что вам нужно, с последующими строками (ниже они просто выводятся вместе с номером строки)
В целом,может сделать что-то похожее на:
#include <stdio.h>
#include <string.h>
#define MAXC 1024 /* don't skimp on buffer size */
int main (int argc, char **argv) {
char buf[MAXC]; /* buffer to hold each line */
int n, s, d; /* your int variables */
size_t ndx = 0; /* line counter */
/* 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;
}
while (fgets (buf, MAXC, fp)) { /* read each line into buf */
if (!ndx) { /* if 1st line, parse into n, s, d */
if (sscanf (buf, "%d %d %d", &n, &s, &d) == 3)
printf ("line[%2zu] - n: %d s: %d d: %d\n",
ndx + 1, n, s, d);
else { /* if parse fails - handle error */
fputs ("error: invalid format - line 1.\n", stderr);
return 1;
}
}
else { /* for all subsequent lines */
buf[strcspn(buf, "\r\n")] = 0; /* trim '\n' from buf */
printf ("line[%2zu] : %s\n", ndx + 1, buf);
}
ndx++; /* increment line counter */
}
if (fp != stdin) fclose (fp); /* close file if not stdin */
return 0;
}
Пример использования / Вывод
Используя ваш входной файл, вы получите следующее:
$ ./bin/rdline1_3int dat/line1_3int.txt
line[ 1] - n: 8 s: 3 d: 5
line[ 2] : mary
line[ 3] : tom
line[ 4] : jane
line[ 5] : joe
line[ 6] : dave
line[ 7] : judy
line[ 8] : fred
line[ 9] : bill
line[10] : jane
line[11] : jones
line[12] : judy
line[13] : mary
line[14] : judy
line[15] : fred
line[16] : joe
line[17] : dave