C,从文件读取,prinintg,语法错误标识符

C,Reading From File,Prinintg, Syntax Error identifier

提问人:Wael Jaber 提问时间:5/13/2022 最后编辑:Wael Jaber 更新时间:5/13/2022 访问量:62

问:

我正在尝试运行我的 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

我想要的 outfile 是:

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
c 语法错误

评论

0赞 Barmar 5/13/2022
请将完整的错误消息添加到问题中。
0赞 Barmar 5/13/2022
在定义 typedef 之前,您已经拥有。切换 和 typedef 的顺序。Student* arr;StudentUniversityStudent
0赞 Barmar 5/13/2022
%l不是有效的格式说明符。它应该是.%ld
0赞 Barmar 5/13/2022
当我编译你的代码时,我没有收到任何关于丢失的错误。}
0赞 Wael Jaber 5/13/2022
这是 C4700 未初始化的局部变量“uni”使用 Project8 的问题

答:

0赞 Mreos 5/13/2022 #1

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

评论

1赞 Barmar 5/13/2022
你需要更具体。显示哪些行有错误,以及如何重写它。
0赞 al366io 5/13/2022 #2

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

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];
1赞 Dave Meehan 5/13/2022 #3

语法错误

在 C Playground(可编辑)中,我收到以下错误:

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

在这里,在大学的定义中,您在定义学生之前引用了它。将“学生”的定义移至“大学”之前,它就会起作用。

以下错误都属于一起,解释如下:

/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 字符串,然后如果这是你预期的输出想要的,你会只想选择第一个元素(注意:C Playground 允许你上传包含测试输入文件的 ZIP,如果你想在那里尝试,请查看 cog 选项)。%cchar **ch%s

按值传递的参数

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

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

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

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

您还忘记复制名称。

如果没有输入文件,则应返回,否则将出现分段错误。exit()

除了外观之外,还有更多的东西,但希望这能带你走得更远,那时你可以回来。

这是一个更新的游乐场,可以解决逻辑错误。

评论

0赞 Wael Jaber 5/13/2022
首先,非常感谢您的完整解释,我真的理解我的错误,我愿意从中学习,我试图在 Visual Studio 中运行代码,我收到此错误运行时检查失败 #2 - 变量“ch”周围的堆栈已损坏。任何解释?我检查了CH是否正常
0赞 Dave Meehan 5/14/2022
它表明您正在覆盖变量、越界或类似变量。您将其定义为 ,并且该位置有 5 个字符。对于 C 字符串,需要允许终止 NULL 字符,因此应至少包含 6 个元素以避免越界。查看文档,了解如何指定每个说明符的最大宽度以避免此类损坏。chchar ch[5]input.textchfscanf