Car*_*ine 2 c scanf return-value
我很抱歉这样做的问题(因为互联网上有这么多关于此问题),但我不得不问这个问题:
练习涉及从带有学生列表的文件中读取(记录包含:姓名,姓氏和序列号).我已经创建了文档并由13行组成,但是当我在终端上写入时./a.out,输出是这种类型的13行的列表:(null) (null) (null)
代码是:
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#define EOF (-1)
#define BUF 100
typedef struct stud{
char *surname;
char *name;
char *serial;
} student;
int main(void){
FILE *fd;
int n = BUF;
int k = 0;
int i = 0;
int ret;
char *s = malloc(BUF * sizeof(char));
if((fd = fopen("registry_office_students.txt","r")) == NULL){
perror("error opening file");
return -1;
}
while(fgets(s,n,fd)!=NULL){
k++;
}
student *a = malloc(k*sizeof(student));
rewind(fd);
ret = fscanf(fd, "%s, %s, %s", a[i].surname, a[i].name, a[i].serial);
while(fscanf(fd, "%s, %s, %s", a[i].surname, a[i].name, a[i].serial) == ret){
i++;
}
for(i=0;i<k;i++){
printf("%s, %s, %s \n", a[i].surname, a[i].name, a[i].serial);
}
fclose(fd);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我再次道歉并希望得到适当的回应,谢谢.
fscanf(3)with %s不会为字符串分配任何内存.该字符串应该已经存在.
至少,替换
ret = fscanf(fd, "%s, %s, %s",
a[i].surname, a[i].name, a[i].serial);
Run Code Online (Sandbox Code Playgroud)
喜欢的东西
{
char surname[48];
char name[64];
char serial[32];
memset (surname, 0, sizeof(surname));
memset (name, 0, sizeof(name));
memset (serial, 0, sizeof(serial));
memset (a+i, 0, sizeof(struct stud));
ret = fscanf(fd, "%47s, %63s, %31s", surname, name, serial);
if (ret==3) {
a[i].surname = strdup(surname);
if (!a[i].surname)
{ perror("strdup surname"); exit(EXIT_FAILURE); }
a[i].name = strdup(name);
if (!a[i].name)
{ perror("strdup name"); exit(EXIT_FAILURE); }
a[i].serial = strdup(serial);
if (!a[i].serial)
{ perror("strdup serial"); exit(EXIT_FAILURE); }
}
}
Run Code Online (Sandbox Code Playgroud)
请注意,我在阅读之前清理内存.我明确给出格式的字符串大小fscanf.我正在复制测试 strdup读取字符串到堆.
实际上,我相信你的方法可能是错的.您可能决定每个学生应该在一行上,您将使用getline(3)阅读并使用sscanf(3)进行解析(可能%n会有用!)或者可能strtok (或"手动"使用isalpha)
请阅读更多关于C编程的资料,然后编译所有警告和调试信息(gcc -Wall -g),学习使用调试器(gdb)和内存泄漏检测器(valgrind).