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,看下面齿轮选项,如果你想在那里尝试的话)。
参数按值传递
在 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
循环是不必要的(它只会循环一次,它的目的是指向数组末尾的 'empty' 元素)。
这里要做的一件好事是获取指向最后一个元素的指针,然后使用它来简化逻辑。
Student *student = uni->arr[cnt-1];
strcpy(student->name, name);
//...
你也忘记复制名字了。
如果没有输入文件,您应该 exit()
而不是 return,否则您将遇到分段错误。
除了外观之外还有更多内容,但希望这能带您走得更远,然后您可以回来。
这里有一个 updated playground 就逻辑错误而言。
我正在尝试 运行 我的 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,看下面齿轮选项,如果你想在那里尝试的话)。
参数按值传递
在 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
循环是不必要的(它只会循环一次,它的目的是指向数组末尾的 'empty' 元素)。
这里要做的一件好事是获取指向最后一个元素的指针,然后使用它来简化逻辑。
Student *student = uni->arr[cnt-1];
strcpy(student->name, name);
//...
你也忘记复制名字了。
如果没有输入文件,您应该 exit()
而不是 return,否则您将遇到分段错误。
除了外观之外还有更多内容,但希望这能带您走得更远,然后您可以回来。
这里有一个 updated playground 就逻辑错误而言。