2010-02-20 40 views
2

我试图填充数组从一个文件名:如何用C中的字符串填充数组?

Andrew 
Andy 
Bob 
Dan 
Derek 
Joe 
Pete 
Richy 
Steve 
Tyler 

这里是我写的功能...但程序崩溃时我运行它:

#include <stdio.h> 

main(){ 
    int i=0, size=10; 
    char fname[15]; 
    char** data; 
    char* name; 
    FILE* fp; 

    printf("Enter a filename to read names:\n"); 
    scanf("%s", fname); 

    fp = fopen(fname, "r"); 
    if(fp == NULL) 
    exit(); 

    data = (char**)malloc(sizeof(char**)*size); 

    while(!feof(fp)){ 
    fscanf(fp, "%s", name); 
    data[i] = (char*)malloc(sizeof(name)); 
    data[i] = name; 
    i++; 
    } 

    fclose(fp); 

    printf("\n\n"); 

    for(i=0; i<size; i++) 
    printf("%s ", data[i]); 

    free(data); 
} 

任何人都知道我做错了什么? 谢谢

回答

5

你有几个错误的位置:

1)你永远不分配内存,其中name将得到保存。你可以解决这个简单的使用:

char name[128]; 

然后,当你使用fscanf,你必须:

fscanf(fp, "%127s", name); // stores this in name correctly, now... 

2)你不恰当的data[i]分配空间:

data[i] = (char*)malloc(sizeof(name)); 

这将分配空间来容纳一个指向字符char*),因为名称是char*。你需要做的:

data[i] = (char*)malloc(sizeof(char) * (strlen(name) + 1)); 

这将为数据加上一个单一的终止字符分配足够的空间。

3)您没有正确指定data[i]。你不能只用=在这里,但需要使用strcpy

strcpy(data[i], name); 

4)你不是在data[..]元素释放个别指针。您应该添加,您的printf之后,自由:

for(i=0; i<size; i++) 
{ 
    printf("%s ", data[i]); 
    free(data[i]); // Free each pointer you allocate 
} 

malloc呼叫最终应该有一个匹配free电话。

+0

里德,我不会失望,因为你的回答是正确和正确的,但是当你不让他考虑这个过程时,你并没有帮助他。 – 2010-02-20 01:03:21

+0

非常感谢,现在正在工作。是的,我现在明白我做错了什么。 – Andrew 2010-02-20 01:03:50

+1

@San Jacinto:我不知道 - 我觉得这很清楚,但不仅仅是重写他的所有代码。如果没有指出事情的缺陷,很难提供帮助......但我明白你的观点。 @安德鲁:我很高兴它正在工作,你现在明白了。 – 2010-02-20 01:07:56

5

您从不为名称分配空间。但是,你把东西在这行:

fscanf(fp, "%s", name); 

变化

char name[100]; 

fscanf(fp, "%99s", name); 

你应该限制开关输入到文件名太:

scanf("%14s", fname); 

还你永远不要释放每个元素的数据在数组中,如果这是一个较大系统中的子例程,它将会发生内存泄漏。

+0

哦......但是我怎么知道有多少空间来如果我不知道这个名字会有多长时间,请分配一下?我是否必须扫描每一行的字符并计数? – Andrew 2010-02-20 00:53:51

+0

你应该有一个线路长度限制;创建一个缓冲区并扫描它 - 其余的将被截断。如果你想要无限长的行,你应该动态地重新分配缓冲区,直到读取所有内容。 然后准确分配名称中的字节数(+1)并将名称放入它中。 – kibitzer 2010-02-20 00:56:50

+0

我总是做了一个非常大的缓冲区。但是你可以先扫描并计数是否需要。对于家庭作业,你可以做一个大缓冲区恕我直言 – Hogan 2010-02-20 00:56:59

0

存在相当多的问题。其他回答说名字没有被初始化,所以我不会重复。

第二个问题是您没有正确处理EOF。 feof只会在您试图读取文件末尾时才会返回true。所以你会得到一个空的第11个名字。

最后一个问题是数据数组只能包含10个名字。由于第二个问题,您将使用空白的第11个名称溢出缓冲区。此外,你的代码取决于输入文件的细节 - 给它一个不同的名称更多的输入文件,即使修复问题2后,你仍然会崩溃。