При чтении строк данных из файла вы хотите использовать строчно-ориентированную функцию ввода , такую как fgets()
или POSIX getline()
. Это гарантирует, что при каждом чтении будет потребляться полная строка ввода. В противном случае при поиске шаблона, такого как строка, за которой следует целое число, частичное чтение, скорее всего, приведет к ложным совпадениям в зависимости от того, какие части строки остаются непрочитанными во входном буфере.
После чтения каждой строки в буфер, вы можете просто проанализировать необходимую информацию из каждой строки, используя sscanf()
вместо вашей попытки как читать, так и анализировать с помощью fscanf()
.
Собирая все вместе, читать совсем не проблема и выделите из файла только имя и номер учащегося, например,
#include <stdio.h>
#include <stdlib.h>
#define NAMC 50 /* if you need a constant, #define one (or more) */
#define MAXC 1024
typedef struct { /* struct for student name and number */
char name[NAMC];
int no;
} student;
int cmpstd (const void *a, const void *b) /* qsort descending by student.no */
{
const student *pa = a, *pb = b;
return (pa->no < pb->no) - (pa->no > pb->no);
}
int main (int argc, char **argv) {
student std[NAMC]; /* array of student */
char buf[MAXC]; /* buffer to hold line */
int n = 0; /* student 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 (n < NAMC && fgets (buf, MAXC, fp)) { /* limit to array sz, read line */
student tmp; /* temporary struct for student */
/* parse name and number from line, validating return */
if (sscanf (buf, "%s %d", tmp.name, &tmp.no) == 2)
std[n++] = tmp; /* add to array */
}
if (fp != stdin) /* close file if not stdin */
fclose (fp);
qsort (std, n, sizeof *std, cmpstd); /* sort by student.no descending */
for (int i = 0; i < n; i++) /* output results */
printf ("%-10s %d\n", std[i].name, std[i].no);
}
Пример использования / вывода
С вашим входным файлом в dat/prefixedstd.txt
вы получите следующее:
$ ./bin/read_prefixstd dat/prefixedstd.txt
asdas 8
asdas 7
asdsa 6
andrea 5
asd 4
asd 1
asdsad 1
asdas 0
asd 0
Посмотрите все и дайте мне знать, если у вас возникнут дополнительные вопросы.