2012-06-08 46 views
0

这段代码给出了一个即时seg错误,我试着把printf的全部都放了,我甚至试图在int = 0之后打印一些东西;但不管我做了什么,它都不会打印任何内容,而只是出现分段错误。该文件存在,其位置也与我执行的位置相同。 该文件包含城市名称,每行一个名称,没有别的,我如何读取它们并将它们存储在一个数组中:/ 如果在每个城市之后有一个数字,那么读数仍然是相同的呢?逐行读取,seg错误

NewYork 5 
LosAngeles 12 
California 7 

和代码;

int i=0; 

    char **city_names = malloc(sizeof(char*)); 

    FILE* fp; 
    fp = fopen("abc.txt","r"); 

    while(!feof(fp)){ 

     city_names[i] = realloc(city_names[i],sizeof(char)*255); 
     fscanf(fp,"%s",city_names[i]); 
     i++; 
    } 

    fclose(fp); 
+0

您应该运行在调试你的代码;它会告诉你哪一行导致段错误。 –

+0

这仍然是错误的。您只在顶部列表中分配了1个指针。 realloc不属于字符串大小。这是一个功课问题吗? –

回答

2

你只在你的malloc中分配一个char *的内存,然后在while循环中访问它。

如果你打算做一个二维数组malloc,你需要malloc每个指针,然后malloc分配malloc到每个到最大字符串大小(呸)。

char **city_names = malloc(sizeof(char *) * kNumCities); 

for(int i = 0; i < kNumCities; i++) 
    city_names[i] = malloc(sizeof(char) * kMaxStringSize); 

或者做一些类似char city_name[3][256]的替代方法来启动并运行它。

我还想补充一点,这种阅读非常不安全。您正在将未知数量的字节读入固定的缓冲区大小。如果您读入的字符串超过255个字节,则会破坏内存。你最好使用fread()进入一个固定大小的缓冲区类型的解决方案(或ftell()然后立即文件并读取所有内容以获得最佳效率),然后读取缓冲区。更不要说所有的开销mallocrealloc(他们加起来)。

+0

因为我不知道该文件包含多少城市,我无法指定像你说的内存。我可以使用realloc出于同样的目的吗? – Karavana

+0

如果可能,请扫描整个文件以获取城市计数,然后进行分配和读取。 x2文件读取,但内存有效。或者分配一大块城市 - 你知道什么是合理的 - 然后如果需要再重新分配。请注意,如果这是内存碎片很重要的嵌入式解决方案,则realloc在内存上非常困难。 –

+0

如果可能的话,我还会将整个文件读入内存中,并从中进行处理 - 这可以为算法等提供最大的灵活性。 –

1

而且while(!feof(fp))逻辑也是错误的;对于一个空文件,它仍然会尝试扫描一些东西并增加i

在阅读C之前,切勿测试EOF。阅读后测试。

的惯用代码遍历字符上用C标准输入是

int c; /* NOT char. */ 

while ((c = getchar()) != EOF) { 
    /* do something with c */ 
} 

遍历行:

char line[MAXLINE]; 
while (fgets (line, sizeof line, stdin) != NULL) { 
    /* do something with line */ 
} 
+0

这真的很有用,但要使用答案的第二部分,我需要计算行数,所以我认为编写此代码的最佳和简单的方法是首先计算行数,然后尝试那么,谢谢:) – Karavana

+0

不需要。只需在循环前使用'int num_lines = 0;',并在里面使用'++ num_lines'。这给你完成后的行数。如果您需要保存它们,请使用malloc和memcpy。 – Jens

1
int i=0; 
    char **city_names = malloc(sizeof(char*)); 
    FILE* fp; 
    fp = fopen("data.txt","r"); 

    while(!feof(fp)){ 
     city_names[i] = (char*)malloc(sizeof(char)*255); 
     if(1!=fscanf(fp,"%s %*d",city_names[i]))break; 
     ++i; 
     city_names = (char**)realloc(city_names, (i+1)*sizeof(char*)); 
    } 

    fclose(fp); 
+0

if(1!= fscanf(fp,“%s%* d”,city_names [i]))break; 你能否进一步解释这一行,即为什么你使用%* d,我的意思是明星的目的是什么,我知道编译器会在我写%d时抱怨它。 – Karavana

+1

@ user1128905 - 你的阅读数据格式像'NewYork 5',但你的代码是'fscanf(fp,“%s”,city_names [i]);',这是忽略int数据。 '%* d'忽略这个位置的数字数据。 – BLUEPIXY