C、读取文件、打印、语法错误标识符

C,Reading From File,Prinintg, Syntax Error identifier

我正在尝试 运行 我的 C 代码。 但我遇到了一个问题,我真的很努力地想得到正确的东西,但我不知道问题出在哪里。 visual studio 告诉我什么,我有语法错误 也错过了“}” 但是我检查了每件事,如果结构有错误原因,它仍然会给我错误 请告诉我如何解决这个问题,但如果它能帮助我获得正确的想法 太感谢了。 这是我下面的代码。

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
typedef struct University
{
    Student* arr;
}University;
typedef struct Student
{
    char* name;
    long id;
    float grade;
    char labor[5];
    char finalg;

}Student;
int readfile(University uni);
void outputfile(University uni, int n);
int main()
{
    int n;
    University uni;
    n=readfile(uni);
    outputfile(uni, n);

    return 0;
}
int readfile(University uni)
{
    FILE* fp;
    char name[100], ch[5];
    long id;
    float grade;
    int cnt = 0, i, j;
    fp = fopen("input.txt", "rt");
    if (fp == NULL)
    {
        printf("ERROR: Cannot open input file.\n");
        return 1;
    }
    while (fscanf(fp, "%s %l %f %c", name, &id, &grade, &ch) > 0)
    {
        if (cnt == 0)
        {
            uni.arr = (Student*)malloc(1 * sizeof(Student));
            if (uni.arr == NULL)
            {
                printf("No Memory to allocation.\n");
                exit(1);
            }
            cnt++;
        }
        else if (cnt >= 1)
        {
            uni.arr = (Student*)realloc(uni.arr, (cnt + 1) * sizeof(Student));
            if (uni.arr == NULL)
            {
                printf("No Memory to allocation.\n");
                exit(1);
            }
            cnt++;
        }
        for (i = cnt - 1; i < cnt;i++)
        {
            uni.arr[i].name = (char*)malloc((strlen(name) + 1) * sizeof(char));
            if (uni.arr[i].name == NULL)
            {
                printf("No Memory to allocation.\n");
                exit(1);
            }
            uni.arr[i].id = id;
            uni.arr[i].grade = grade;
            for (j = 0;j < 5;j++)
                uni.arr[i].labor[j] = ch[j];
        }
    }
    return cnt;
}
void outputfile(University uni, int n)
{
    FILE* fo;
    int i,check,j;
    fo = fopen("outputfile.txt", "w");
    for (i = 0;i < n;i++)
    {
        check = 0;
        for (j = 0;j < 5;j++)
            if (uni.arr[i].labor[j] == 1)
                check++;
        if (check < 3)
            check = 0;
        else
            check = 1;
        fprintf(fo,"Student[%d]: %s %.2f %d", i+1,uni.arr[i].name,uni.arr[i].grade,check);
    }
}

输入文件是:

michel 123 90.1 11001
alex 234 92.3 10011
Linda 345 89.4 10001
Shoco 456 90.6 01001

我想要的输出文件是:

Student 1: michel 123 90.1 1
Student 2: alex 234 92.3 1
Student 3: Shoco 456 90.6 0
……………..
…………….
Student n: Shoco 456 90.6 0

我认为大学结构中的结构构建存在指针问题 您需要重写指针。

我建议你去看看你的编译器错误,有很多错误! 例如:

main.c:66:23: error: request for member ‘name’ in something not a structure or union
   66 |             uni.arr[i].name = (char*)malloc((strlen(name) + 1) * sizeof(char));
      |                       ^
main.c:67:27: error: request for member ‘name’ in something not a structure or union
   67 |             if (uni.arr[i].name == NULL)
      |                           ^
main.c:72:23: error: request for member ‘id’ in something not a structure or union
   72 |             uni.arr[i].id = id;
      |                       ^
main.c:73:23: error: request for member ‘grade’ in something not a structure or union
   73 |             uni.arr[i].grade = grade;
      |                       ^
main.c:75:27: error: request for member ‘labor’ in something not a structure or union
   75 |                 uni.arr[i].labor[j] = ch[j];

语法错误

在 C Playground (editable) 中出现以下错误:

/cplayground/code.cpp:7:5: error: unknown type name 'Student'
    Student* arr;
    ^

在这里,在 University 的定义中,您在定义 Student 之前引用它。将 Student 的定义移动到 University 之前,它将起作用。

以下错误均属同一类,解释如下:

/cplayground/code.cpp:42:29: warning: invalid conversion specifier ' ' [-Wformat-invalid-specifier]
    while (fscanf(fp, "%s %l %f %c", name, &id, &grade, &ch) > 0)
                         ~~~^
/cplayground/code.cpp:42:44: warning: format specifies type 'float *' but the argument has type 'long *' [-Wformat]
    while (fscanf(fp, "%s %l %f %c", name, &id, &grade, &ch) > 0)
                             ~~            ^~~
                             %ld
/cplayground/code.cpp:42:49: warning: format specifies type 'char *' but the argument has type 'float *' [-Wformat]
    while (fscanf(fp, "%s %l %f %c", name, &id, &grade, &ch) > 0)
                                ~~              ^~~~~~
                                %f

这些都与 %l 的使用有关,它不是一个完整的说明符。第一个错误告诉您这一点,另外两个是因为以下说明符和参数不同步。修复第一个错误,其余错误将消失。

最后:

/cplayground/code.cpp:42:57: warning: data argument not used by format string [-Wformat-extra-args]
    while (fscanf(fp, "%s %l %f %c", name, &id, &grade, &ch) > 0)
                      ~~~~~~~~~~~~~                     ^
4 warnings and 1 error generated.

此处您使用 %c 表示单个字符,但传递的是 char **ch 数组的地址)。我怀疑你想要 %s 作为 C 字符串,然后如果这是你想要的输出想要的,你将只想选择第一个元素(注意:C Playground 允许你上传包含测试输入文件的 ZIP,看下面齿轮选项,如果你想在那里尝试的话)。

参数按值传递

readfileoutputfile 的定义和实现中,您正在按值传递。这意味着该函数正在更新 uni 变量的副本,而不是传递的副本。因此 readfile 添加的任何内容都不会到达 outputfile.

int readfile(University uni);
void outputfile(University uni, int n);

您需要更改声明和实现以传递指针,因此:

int readfile(University *uni);
void outputfile(University *uni, int n);

然后,在这两个函数中,将 . 访问器更改为 -> 以取消引用指针。例如

uni->arr = (Student*)malloc(1 * sizeof(Student));
if (uni->arr == NULL)

逻辑错误

还有其他逻辑错误阻止它 运行 正确,但我会把它留给 OP。

值得注意的是,分配新学生后的 for 循环是不必要的(它只会循环一次,它的目的是指向数组末尾的 'empty' 元素)。

这里要做的一件好事是获取指向最后一个元素的指针,然后使用它来简化逻辑。

Student *student = uni->arr[cnt-1];
strcpy(student->name, name);
//...

你也忘记复制名字了。

如果没有输入文件,您应该 exit() 而不是 return,否则您将遇到分段错误。

除了外观之外还有更多内容,但希望这能带您走得更远,然后您可以回来。

这里有一个 updated playground 就逻辑错误而言。