C语言 为什么在while循环中出现分段错误?

cwxwcias  于 2022-12-02  发布在  其他
关注(0)|答案(1)|浏览(170)

我的程序将把数据从txt读入我的结构。

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

typedef struct competitor
{
    int id;
    char* name;
    char* nationality;
    char* sex;
    double weight;
    char* event;
}competitor;

int sportolok_beolvas(char* filename, competitor* array)
{
    FILE* file = fopen(filename, "r"); 
    int n = 0; 

    while(fscanf(file, "%d %s %s %s %lf %s", &array[n].id, array[n].name, array[n].nationality, array[n].sex, &array[n].weight, array[n].event) == 6)
    {
        ++n;
    }
    fclose(file);

    return n;
}

int main()
{
    competitor* array;
    int i = sportolok_beolvas("sportolok.txt", array);
    printf("%d", i);
    return 0;
}

这个函数是根据我以前的项目做的,这个项目使用的函数几乎是一样的。把文件读入到我的结构中。我不明白它有什么问题。

roejwanj

roejwanj1#

一个字符串实际上是一个字符数组,结尾是一个空终止符。
可以使用普通数组创建字符串,如

char str[] = "foo";

或者,您可以使用指针并动态分配内存,例如

char *str = malloc(4);
strcpy(str, "foo");

这两个例子几乎是等价的(数组和指针之间有一些重要的区别,但我们先把这些放在一边)。这两个例子都创建了一个有三个字符的字符串(加上空终止符)。
但是,如果您有

char *str;
strcpy(str, "foo");

那么你就有了 * 未定义的行为 *,因为指针str没有指向任何地方。
回到代码中,字符串最简单的解决方案是将它们从指针改为数组:

#define NAME_SIZE        20
#define NATIONALITY_SIZE 20
#define SEX_SIZE         10
#define EVENT_SIZE       20

typedef struct competitor
{
    int id;
    char name[NAME_SIZE];
    char nationality[NATIONALITY_SIZE];
    char sex[SEX_SIZE];
    double weight;
    char event[EVENT_SIZE];
}competitor;

至于competitor结构的数组,我建议您在循环中根据需要动态创建它,并根据需要重新分配。
读入单个已定义的competitor结构对象,并将其复制到当前数组元素中。
完成后,返回指向数组第一个元素的指针。
也许是这样的:

// Out dynamic "array", pointer to its first element
competitor *competitors = NULL;

// Current size of the competitor array
size_t current_size = 0;

// A structure object to store the data we read from the input
competitor current_competitor;

// Now the loop to read the data
while(fscanf(file, "%d %s %s %s %lf %s",
             &current_competitor.id,
             current_competitor.name,
             current_competitor.nationality,
             current_competitor.sex,
             &current_competitor.weight,
             current_competitor.event) == 6)
{
    // Reallocate the array, adding one new element (+1)
    // If the array doesn't exist, when competitors is NULL, create
    // an array with a single element
    competitor *new_array = realloc(competitors, sizeof *new_array * current_size + 1);

    // Check if the allocation succeeded or failed
    if (new_array == NULL)
    {
        // TODO: Report it
        exit(EXIT_FAILURE);
    }

    // Make the new array our actual array
    competitors = new_array;

    // Copy the the structure object we just have read, into the array
    competitors[current_size] = current_competitor;

    // And finally increase the size
    ++current_size;
}

After this, the `competitors` pointer will point to the first element of an array of `current_size` elements.

Exactly how to return these values (*both* needs to be returned) is left as an exercise for the reader.

相关问题