提问人:Wael Jaber 提问时间:5/13/2022 最后编辑:Wael Jaber 更新时间:5/13/2022 访问量:62
C,从文件读取,prinintg,语法错误标识符
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
我想要的 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
答:
我认为大学结构中的结构构建存在一个指针问题 您需要重写指针。
评论
我建议你去看看你的编译器错误,它们有很多! 例如:
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(可编辑)中,我收到以下错误:
/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 选项)。%c
char **
ch
%s
按值传递的参数
在定义和实现中,你是按值传递的。这意味着该函数正在更新变量的副本,而不是传递的副本。因此,添加的任何内容都不会达到.readfile
outputfile
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
这里要做的一件好事是获取指向最后一个元素的指针,然后使用它来简化逻辑。
Student *student = uni->arr[cnt-1];
strcpy(student->name, name);
//...
您还忘记复制名称。
如果没有输入文件,则应返回,否则将出现分段错误。exit()
除了外观之外,还有更多的东西,但希望这能带你走得更远,那时你可以回来。
这是一个更新的游乐场,可以解决逻辑错误。
评论
ch
char ch[5]
input.text
ch
fscanf
评论
Student* arr;
Student
University
Student
%l
不是有效的格式说明符。它应该是.%ld
}