После каждой напечатанной строки есть 2 пустые строки - PullRequest
0 голосов
/ 10 июля 2020

Я пытаюсь создать функцию, которая при чтении из файла некоторых оценок с именами учащихся и печати оценок в порядке убывания. Это функция:

char studenteUN[50];
int punti;
int maxP = MAX_LNG;
int max = -1000;
int min = MAX_LNG;

FILE *ftemp = f;
while(fscanf(ftemp, "%s", studenteUN) != EOF){
  fscanf(ftemp, "%d", &punti);
  if(punti < min)
    min = punti;
}

while (maxP != min) {
  max = -1000;
  ftemp = muovi(f);
  while(fscanf(ftemp, "%s", studenteUN) != EOF){
    fscanf(ftemp, "%d", &punti);
    if(punti > max && punti < maxP)
      max = punti;
  }
  maxP = max;
  ftemp = muovi(f);
  while(fscanf(ftemp, "%s", studenteUN) != EOF){
    fscanf(ftemp, "%d", &punti);
    if(punti == max)
      printf("%s %d\n", studenteUN, punti);
  }
}

Te вывод следующий:

asdas 8


asdas 7


asdsa 6


andrea 5


asd 4


asd 1
asdsad 1


asdas 0
asd 0

Я не могу понять, почему это происходит. Я прочитал следующий файл:

2
1- askd a
   1- asd
   2- asd as
   3- asd as d
   4- asdas
   5- Non lo so.
1
2- asdsad asd as d
   1- asd a
   2- asd
   3- asd
   4- as df
   5- Non lo so.
2
andrea 5
asdsa 6
asdas 7
asd 1
asdas 0
asd 0
asdsad 1
asdas 8
asd 4

Функция muovi:

FILE *muovi(FILE *f){
 fseek(f, 0, SEEK_SET);
 char resultato[MAX_LNG];
 int nD;
 fscanf(f, "%d", &nD);
 printf("\n");
 for(int i = 0; i <= nD*7;i++)
  fgets(resultato, MAX_LNG, f);
 return f;
}

Ответы [ 2 ]

1 голос
/ 10 июля 2020

Я написал демонстрационный образец: он считывает ввод формы 'name grade':

student1 1
student2 7
student3 -4
student4 11
student5 1111
student6 -11111

И выводит:

student5 1111
student4 11
student2 7
student1 1
student3 -4
student6 -11111

Вот код, возможно вы можете придумать

#include <stdio.h>
#include <stdlib.h>

struct studs {
    int grade;
    char name[50];
};

int md_comparator(const void *v1, const void *v2)
{
    const struct studs *p1 = (struct studs *)v1;
    const struct studs *p2 = (struct studs *)v2;
    
    if (p1->grade < p2->grade)
        return 1;
    else if (p1->grade > p2->grade)
        return -1;
    else
        return 0;
}


int main()
{
    struct studs students[1000];
    struct studs temp;
    
    //read all students into students[] array
    int idx = 0;
    for (; fscanf(stdin, "%s %d", temp.name, &temp.grade) == 2; students[idx++] = temp)
        ;
    
    //sort descending, with the help of qsort and md_comparator function above
    qsort(students, idx, sizeof(students[0]), md_comparator);
    
    //print
    for (int i = 0; i < idx; i++)
        printf("%s %d\n", students[i].name, students[i].grade);
    
    return 0;
}
0 голосов
/ 10 июля 2020

При чтении строк данных из файла вы хотите использовать строчно-ориентированную функцию ввода , такую ​​как 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

Посмотрите все и дайте мне знать, если у вас возникнут дополнительные вопросы.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...