Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/64.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 热转换TXT文件到数组的结构分割错误?_C_Arrays_Struct_Segmentation Fault_Coredump - Fatal编程技术网

C 热转换TXT文件到数组的结构分割错误?

C 热转换TXT文件到数组的结构分割错误?,c,arrays,struct,segmentation-fault,coredump,C,Arrays,Struct,Segmentation Fault,Coredump,试图从文本文件中提取数据并将此数据放入数组 文件包含一定数量的行,每行都遵循相同的处理方式: Number FamilyName FirstName GPA 所需的数组是struct的数组 #include<stdio.h> #include<stdlib.h> #include<string.h> #define MAX 25 typedef struct ppl { int login; char *p_name; char

试图从文本文件中提取数据并将此数据放入数组

文件包含一定数量的行,每行都遵循相同的处理方式:

Number FamilyName FirstName GPA
所需的数组是struct的数组

#include<stdio.h>
#include<stdlib.h> 
#include<string.h>
#define MAX 25

typedef struct ppl {
    int login;
    char *p_name;
    char *p_surname;
}person;

int main(void)
{
    char *line = NULL;
    person *data=malloc(MAX*sizeof(person)); 
    float *gpa=malloc(MAX*sizeof(float)); 
    size_t length=0;

    FILE* txtfile;

    if ((txtfile=fopen("file.txt","r"))==NULL) return -1;

    int i=0;               // the counter for the for loop
    int buf_ID;            // buffer variable for the sscanf test
    char buf_name[256];    // same
    char buf_surname[256]; // same
    float buf_grade;       // same

    while ((read = getline(&line, &length,txtfile)) != -1 && i<MAX) 
    {
        if(sscanf(line,"%d %s %s%*s %f", &buf_ID, buf_name, buf_surname, &buf_grade)==4)
        {  
             data[i].login=buf_ID;
             data[i].p_name= malloc(strlen(buf_name)+1);
             strcpy(data[i].p_name, buf_name);
             data[i].p_surname= malloc(strlen(buf_surname)+1);
             strcpy(data[i].p_surname, buf_surname);
             gpa[i]=buf_grade;

             i++;
         }
     }                        

    int j;

    printf("ID | Name | Surname | GPA\n");

    for(j=0;j<i;j++)
    {
        printf("%d | %s | %s | %f\n", data[j].login, data[j].p_name, data[j].p_surname, gpa[j]);
    }
    fclose(txtfile);
    return 0;
}
#包括
#包括
#包括
#定义最大值25
类型定义结构ppl{
int登录;
char*p_名称;
char*p_姓;
}人;
内部主(空)
{
char*line=NULL;
人员*数据=malloc(最大*尺寸(人员));
float*gpa=malloc(最大*sizeof(float));
尺寸长度=0;
文件*txtfile;
if((txtfile=fopen(“file.txt”,“r”))==NULL)返回-1;
int i=0;//for循环的计数器
int buf_ID;//sscanf测试的缓冲区变量
char buf_name[256];//相同
char buf_姓氏[256];//相同
浮动buf_等级;//相同

虽然((read=getline(&line,&length,txtfile))!=-1&&i我看到您现在为数组分配了内存。很好

现在,关于
char*
buffers
buf_name
等。例如,最好在这里进行静态分配

char buf_name[256];
您将重新使用这个缓冲区,所以静态分配是可以的


下一步:

查找getline函数: 并检查所有参数是否正确


现在,使用调试器将程序单步执行到
sscanf
。单步执行并检查
sscanf
是否正确读取了变量(使用调试器是学习C语言的一个重要部分)

下一件事是问问你自己,你的一组人是否拥有它所需要的全部内存。如果没有,你将如何分配这些内存


您已经使用malloc分配了一个person数组。每个person都有一些与之相关联的数据。这些数据包括基本类型和复合类型。基本类型是int、float、double和char。复合类型包括许多这些类型。字符串是复合类型,因为它包含多个char

因此,数组中的人有与其关联的字符串数据作为指针,但指针没有与其关联的内存。您需要分配内存来保存字符串数据。您的数据->p_name=malloc(MAX*100);`不正确

对于您读取的每个人,您应该分配字符串内存来保存
sscanf
放入固定大小缓冲区的字符串数据:

data[i].p_name= malloc(strlen(buf_name)+1);
strcpy(data[i].p_name, buf_name);
其他字符串数据也是如此。(当然,这是在循环中完成的!)

注意:对于基本类型,数据由编译器分配;对于复合类型,必须分配内存

注意:C中的字符串以空字符结尾。因此所需的内存比字符串的长度多一个

第二个
sscanf
在你的循环中做了什么??

最后,复制ID:

data[i].login= buf_id;
请注意,您没有将等级存储在person中,
gpa
没有分配内存(因此您可以再次获得seg故障)


您的程序现在将在没有seg故障的情况下运行。但您的循环不正确:

您有一个for循环,该循环正好循环25次;在该循环中,您有一个while循环,该循环读取数据并将其放入persons中。但是persons的索引仅在for循环中更新,而不在while循环中更新。一旦读取了最后一行数据,while循环停止,for循环的下一次迭代开始。但是,没有更多的数据

因此,您需要另一种类型的循环,一种最多循环25次的循环(因为您没有超过25次的人),并且在没有更多数据的情况下停止

for循环可以很好,while循环也可以很好。但不是两者都可以。你能想出这两种变体吗


您的程序现在运行。最后一点:“清理!”删除不再需要的内容,确保代码正确缩进和格式化,并添加一个循环来打印数组,以便您可以检查并查看它是否正确运行


希望您在开发此程序时玩得开心。

@PaulOgilvie我需要在数组声明中还是在if(sscanf)中分配内存loop?@PaulOgilvie确实是个家庭作业,但我的辩护是,在我的讲座中,我们还没有学习过文件和用C语言处理它们。我是在谷歌上收集信息的。@Irisde@PaulOgilvie正如您所说,我添加了“if((txtfile=fopen(“file.txt”,“r”))==NULL)返回-1和为我的person数组分配的内存:我需要最大乘以我的结构大小。但我仍然得到分段错误。@PaulOgilvie我试图调试代码。我收到了这样的消息:当我走到if(sscanf==4)时,表达式中的一个语法错误,靠近'if(sscanf(行),%d%s%s%*s%f',ID,name,姓氏和grade)==4')正常执行程序时,我得到:程序接收信号SIGSEGV,分段错误在../sysdeps/x86_64/multiarch/strlen-avx2.S:62../sysdeps/x86_64/multiarch/strlen-avx2.S:没有这样的文件或目录。我这样做了。仅此修改就不再有分段错误。但是当我尝试打印数组的一个值时(如数据(1))分段错误又回来了。一步一步。在它开始工作之前还有很多问题需要解决。你在getline上读过并检查过它的参数吗?我在帖子中忘记编辑它,但我将长度初始化为0。@Iris,情况如何?你现在可以跳过使用调试器。很抱歉,延迟了,我通过调试器得到了这个结果:#0 u strlen u avx2()在../sysdeps/x86_64/multiarch/strlen-avx2.S:62#1 0x00007FF7A649D2输入输出(str=0x0)在ioputs.c:35#2 0x0000555554AD6主输入输出()在tp1_exo1.c:54