2010-05-26 82 views
1

我想打開一個文本文件(見下文),讀取每一行中的第一個int並將其存儲在一個數組中,但是出現了段錯誤。我擺脫了所有的海灣合作委員會警告,我通過在網上找到的幾個教程閱讀並搜索解決方案的stackoverflow,但我無法弄清楚,我做錯了什麼。由函數malloc和sscanf導致的seg故障

它在我主要功能(參見示例1)中擁有所有內容時起作用,但當我將其轉移到第二個功能時(見下面的示例2)則不起作用。在例2中,當我在sscanf (line,"%i",classes[i]);處正確解釋gdb時發現seg錯誤。

恐怕,這可能是件小事,但我已經浪費了一天的時間。

在此先感謝。

[實施例1]儘管與一切工作在主:

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

const int LENGTH = 1024; 

int main() { 
    char *filename="somedatafile.txt"; 
    int *classes; 
    int lines;  
    FILE *pfile = NULL; 
    char line[LENGTH]; 
    pfile=fopen(filename,"r"); 
    int numlines=0; 
    char *p; 

    while(fgets(line,LENGTH,pfile)){ 
    numlines++; 
    } 

    rewind(pfile); 

    classes=(int *)malloc(numlines*sizeof(int)); 
    if(classes == NULL){ 
    printf("\nMemory error."); 
    exit(1); 
    } 
    int i=0; 
    while(fgets(line,LENGTH,pfile)){ 
    printf("\n"); 
    p = strtok (line," "); 
    p = strtok (NULL, ", "); 
    sscanf (line,"%i",&classes[i]); 
    i++; 
    } 
    fclose(pfile); 
    return 1; 
} 

[實施例2]這不與轉移到一個功能的功能:

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

const int LENGTH = 1024; 

void read_data(int **classes,int *lines, char *filename){ 
    FILE *pfile = NULL; 
    char line[LENGTH]; 
    pfile=fopen(filename,"r"); 
    int numlines=0; 
    char *p; 

    while(fgets(line,LENGTH,pfile)){ 
    numlines++; 
    } 

    rewind(pfile); 

    * classes=(int *)malloc(numlines*sizeof(int)); 
    if(*classes == NULL){ 
    printf("\nMemory error."); 
    exit(1); 
    } 
    int i=0; 
    while(fgets(line,LENGTH,pfile)){ 
    printf("\n"); 
    p = strtok (line," "); 
    p = strtok (NULL, ", "); 
    sscanf (line,"%i",classes[i]); 
    i++; 
    } 
    fclose(pfile); 
    *lines=numlines; 
} 

int main() { 
    char *filename="somedatafile.txt"; 
    int *classes; 
    int lines; 

    read_data(&classes, &lines,filename) ; 
    for(int i=0;i<lines;i++){ 
    printf("\nclasses[i]=%i",classes[i]); 
    } 
    return 1; 
} 

[somedatafile.txt的內容]

50 21 77 0 28 0 27 48 22 2 
55 0 92 0 0 26 36 92 56 4 
53 0 82 0 52 -5 29 30 2 1 
37 0 76 0 28 18 40 48 8 1 
37 0 79 0 34 -26 43 46 2 1 
85 0 88 -4 6 1 3 83 80 5 
56 0 81 0 -4 11 25 86 62 4 
55 -1 95 -3 54 -4 40 41 2 1 
53 8 77 0 28 0 23 48 24 4 
37 0 101 -7 28 0 64 73 8 1 
... 

回答

2

此:

sscanf (line,"%i",classes[i]); 

可能是錯誤的。您需要取消引用那裏,嘗試:

sscanf (line,"%i", &(*classes)[i]); 

這是因爲classes是一個指向整數數組。你需要這些整數之一的地址,以便sscanf()可以在那裏寫入分析的數字。因此,您必須先取消classes以獲取數組,然後說您想要該數組中的元素編號爲i的地址。

你也可以使用

sscanf (line,"%i", *classes + i); 

這可能是更清晰,這取決於你是多麼舒適的這些事情。

+0

謝謝,這很快!但是我從來沒有見過&(* foo)[bar]。它看起來應該和foo [bar]一樣,但顯然不是。這是什麼意思? – Framester 2010-05-26 16:21:49

+0

'classes [i]'是一個'int *'; '(* classes)'也是'int *','(* classes)[i]'是'int','&(* classes)[i]'是'int'的地址。 – danben 2010-05-26 16:28:06

+0

@danben謝謝! – Framester 2010-05-26 16:50:18

0

問題是你在第一種情況下將[]運算符應用於int *,在第二種情況下爲int **。 int **就像一個二維數組,當您將int運算符與int **結合使用時,您將索引到一個int *數組中。在你的情況下,這不是你想要的,因爲你只初始化這個數組中的第一個入口。所以當你訪問類[1]時,它會因爲未初始化而崩潰。你可以自己避免這種混亂在指針傳遞作爲參考,而不是雙指針:

int*& classes instead of int** classes 

然後,你可以使用相同的代碼從您的主要功能。