被覆盖的字符串数组

时间:2014-08-05 15:48:38

标签: c string parsing iteration key-value

我有一个程序试图获取包含以下内容的文本文件并将其提供给我的其他程序。

Bruce, Wayne
Bruce, Banner
Princess, Diana
Austin, Powers

这是我的C代码。它试图获取文件中的行数,解析以逗号分隔的键和值,并将它们全部放在字符串列表中。最后,它试图遍历字符串列表并将其打印出来。这个输出只是Austin Powers一次又一次。我不确定问题是我是如何将字符串附加到列表中的,或者我是如何阅读它们的。

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

int main(){
    char* fileName = "Example.txt";
    FILE *fp = fopen(fileName, "r");
    char line[512];
    char * keyname = (char*)(malloc(sizeof(char)*80));
    char * val = (char*)(malloc(sizeof(char)*80));
    int i = 0;
    int ch, lines;

    while(!feof(fp)){
        ch = fgetc(fp);
        if(ch == '\n'){ //counts how many lines there are
            lines++;
        }
    }
    rewind(fp);

    char* targets[lines*2];

    while (fgets(line, sizeof(line), fp)){
        strtok(line,"\n");
        sscanf(line, "%[^','], %[^',']%s\n", keyname, val);
        targets[i] = keyname;
        targets[i+1] = val;
        i+=2;
    }
    int q = 0;

    while (q!=i){
        printf("%s\n", targets[q]);
        q++;
    }

    return 0;
}

2 个答案:

答案 0 :(得分:4)

问题在于两行:

targets[i] = keyname;
targets[i+1] = val;

这些不会复制字符串 - 它们只复制它们指向的任何内存的地址。因此,在while循环结束时,每对target元素指向相同的两个块。

要制作字符串的副本,您必须使用strdup(如果提供),或使用strlenmallocstrcpy自行实施

另外,正如@mch所提到的,你永远不会初始化lines,所以当可能为零时,它也可能是任何垃圾值(这可能会导致char* targets[lines*2];失败)。

答案 1 :(得分:1)

首先打开文件。在while循环中,检查条件以找到\ n或EOF以结束循环。在循环中,如果您获得除字母数字以外的任何内容,则将令牌分开并将其存储在字符串数组中。遇到\ n或EOF时增加计数。更好地使用do {} while(ch!= EOF);