在结构C中存储文件中的整数数组

时间:2012-12-12 08:45:55

标签: c arrays io structure

我正在从文件到结构阅读并遇到问题。我有测试文件,其中第一个字母定义结构名称第二个数字告诉我它有多少个节点,其余的数字是节点。文件示例:

A 4 1 2 3 4
B 5 1 2 3 9 8 
C 3 1 2 3 

所以例如结构应该是这样的:name-> A; numberOfNodes-→4;节点 - > {1,2,3,4}。我保存每行的结构是:

struct mystruct{
char name[1];
int numberOfNodes;
int nodes[];
};

到目前为止我的功能:

lines = lineCount(courses); //calculates how many rows file has
struct courses course[lines];
co = fopen(courses, mode);
if(co == NULL){
    printf("Can't find the files.");
    exit(1);
}else{
    for(i = 0; i < lines; i++){
        fscanf(co, "%1s %d \n", &current, &id1); //Doesnt have any problems reading these two parameters;
        for(j = 0 ; j < id1; j++){ 
            fscanf(co, "%d", &course[i].nodes[j]); //Have no idea how to store array =/
        }
        strcpy(course[i].courseName, current);
        course[i].numberOfNodes = id1;
    }
}
编辑:我很抱歉让你们感到困惑,它只是很好地分配整数,但不输出相同的东西,它会输出这样的东西:

A 4 69 72 1 2
B 5 20 45 7 3 1 
C 3 2 45 1 

我认为这段代码没有做我想做的事情:

        for(j = 0 ; j < id1; j++){ 
            fscanf(co, "%d", &course[i].nodes[j]); //Have no idea how to store array =/
        }

非常感谢任何帮助!

4 个答案:

答案 0 :(得分:2)

您的代码不会为整数数组分配任何内存,int nodes[]被称为灵活数组成员它有它的用途而且它不是保留任何内存,你需要为nodes数组分配动态内存:

struct mystruct {
    char name[1];
    int numberOfNodes;
    int *nodes;
};
...
fscanf(co, "%c %d \n", &current, &id1);   
course[i].nodes = malloc(sizeof(int)*id1);

请注意,%1s格式说明符扫描1个字符的字符串,之后会添加一个空终止字节,因此您应该使用%c来只读一个字符。

注1:完成后不要忘记free()已分配的所有内存,例如

free(course[i].nodes);

注2:在C中分配内存的惯用方法是:

malloc(num_of_elements * sizeof *ptr_to_type); 

我没有在此处介绍以避免混淆,同时请注意我个人不喜欢投射malloc()的结果,这有一些很好的理由: Do I cast the result of malloc?

答案 1 :(得分:1)

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

struct mystruct {
    struct mystruct *next;
    char name; /* No need to dim array as name[1] */
    int numberOfNodes;
    int nodes[];
};

int main(void)
{
    /* Don't like VLA's, I used a list */
    struct mystruct *curr, *first = NULL, *prior = NULL;
    char s[256], *p;
    FILE *f;
    int i;

    /* Open (No need to count lines before) */
    f = fopen("data", "r");
    if (f == NULL) {
        perror("fopen");
        exit(EXIT_FAILURE);
    }
    /* Fill */
    while (fgets(s, sizeof(s), f) != NULL) {
        i = (int)strtol(&s[1], &p, 10);
        if (i == 0) continue; /* Skip blank or 0 node */
        /* Flexible array must be alloced with parent */
        curr = malloc((sizeof *curr) + (sizeof(int) * (size_t)i));
        curr->next = NULL;
        curr->name = s[0];
        curr->numberOfNodes = i;
        for (i = 0; i < curr->numberOfNodes; i++) {
            curr->nodes[i] = (int)strtol(p, &p, 10);
        }
        if (prior) {
            prior->next = curr;
        } else {
            first = curr;
        }
        prior = curr;
    }
    fclose(f);
    /* Print */
    curr = first;
    while (curr) {
        printf("%c %d", curr->name, curr->numberOfNodes);
        for (i = 0; i < curr->numberOfNodes; i++) {
            printf(" %d", curr->nodes[i]);
        }
        printf("\n");
        curr = curr->next;
    }
    /* Free */
    while (first) {
        curr = first->next;
        free(first);
        first = curr;
    }
    return 0;
}

答案 2 :(得分:0)

你的问题是你之前不知道有多少数字跟着这封信。 所以你可以说不超过1000或任何你发现“足够”的东西。或者您将此数字一个接一个地存储在一种链接结构中。如果你使用提供链表的例如库,那么后来要容易得多。其中一个例子就是油嘴滑舌。

如果要存储在数组中,则必须使用填充动态为数组分配空间。你需要一些malloc / realloc / free的组合。

存储数组的iteme可以在打印时完成 &amp; course [i] .nodes [j]会做,但当然你需要足够的空间来真正访问节点[j]

此致

答案 3 :(得分:-1)

如果您使用的是标准C / C ++,则需要在分配值之前初始化数组,并确保在fscanf()时获得正确的指针!

struct mystruct{
char name[1];
int numberOfNodes;
int* nodes;
};

然后在你的if:

的else部分
else{
    for(i = 0; i < lines; i++){
        fscanf(co, "%1s %d \n", &current, &id1); //Doesnt have any problems reading these two parameters;
        course[i].nodes = new int[id1]; //init array length of id1 value
        for(j = 0 ; j < id1; j++){ 
            int tempNode;
            fscanf(co, "%d", &tempNode); 
            course[i].nodes[j] = tempNode; //allocate the node value to the correct location. 
        }
        strcpy(course[i].courseName, current);
        course[i].numberOfNodes = id1;
    }

或者,您应该可以使用以下方法绕过临时值:

fscanf(co, "%d", &(course[i].nodes[j]));

但我认为有些编译器可能无法认为这是正确的。由于您的数据结构,使用临时值更好 - 我的意见。

最后不要忘记遍历course []向量和delete (course[i].nodes)

如果你想要纯C,你将需要使用malloc()这可能很难处理 - 好不像新的那样漂亮,删除。

无论如何,我建议使用STL向量进行更简单的内存管理,减轻指针分配的压力,并使用预定义的运算符函数 - push_back,pop_back,insert,使用优雅的数据管理(迭代,添加,删除),擦除。

http://www.cplusplus.com/reference/vector/vector/


我在某些代码中加了'()'来强调运算符的优先级。