2015-11-02 38 views
0

我想從文件中讀取字符串並將它們插入到矩陣中。每一行都是一個字。錯誤動態創建字符串數組

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

if(fp == NULL) 
{ 
    perror("Error while opening the file.\n"); 
    exit(EXIT_FAILURE); 
} 


int symbol, num_of_lines = 0, len_of_string = 0, max_len = 0; 
do { 
    symbol = fgetc(fp); 
    len_of_string++; 
    if (symbol == '\n' || feof(fp)) { 
     num_of_lines++; 

     if(len_of_string > max_len){ 
      max_len = len_of_string; 
     } 
     len_of_string = 0; 
    } 
} while (symbol != EOF); 
fclose(fp); 

printf("Number of words: %d\n", num_of_lines); 
printf("Longest word: %d\n", max_len); 

fp = fopen("zadanie4.txt","r"); 
char (*arr)[num_of_lines] = calloc(num_of_lines, sizeof(char*) * max_len); 
int index = 0; 

while(fscanf(fp, "%s", arr[index++]) == 1) { 
    printf("%s\n", arr[index - 1]); //first check to see what is written into array 
} 
close(fp); 

printf("--------------------------\n"); 

int i; 
for(i = 0; i < num_of_lines; i++){ 
    printf("%s\n", arr[i]); //second check 
} 

我找出最長的字符串的大小,並分配內存的字符串數*最長的字符串。

下面是輸出的樣子,如果最長的單詞是5(+1空 '\ 0'):

Number of words: 6 
Longest word: 6 
AAAAA 
BBBBB 
CCCCC 
DDDDD 
EEEEE 
FFFFF 
-------------------------- 
AAAAA 
BBBBB 
CCCCC 
DDDDD 
EEEEE 
FFFFF 

如果我添加其他字符到每一行:

Number of words: 6 
Longest word: 7 
AAAAAa 
BBBBBb 
CCCCCc 
DDDDDd 
EEEEEe 
FFFFFf 
-------------------------- 
AAAAAaBBBBBbCCCCCcDDDDDdEEEEEeFFFFFf 
BBBBBbCCCCCcDDDDDdEEEEEeFFFFFf 
CCCCCcDDDDDdEEEEEeFFFFFf 
DDDDDdEEEEEeFFFFFf 
EEEEEeFFFFFf 
FFFFFf 

注:在這個例子中,每個字符串都是相同的大小,但我希望它能夠處理各種大小。

任何人都可以幫助我如何正確地分配這個數組的內存?

回答

0

您的聲明和分配arr是錯誤的並且不匹配。

您聲明arr作爲指向num_of_lines字符數組的指針。然後你分配max_len指向字符的指針數。

可以使用可變長度數組兩者的內外陣列:

char arr[num_of_lines][max_len + 1]; // +1 for string terminator 

無需動態分配的。

+0

我試圖改變它,因爲你寫了,但是現在我得到了'munmap_chunk():無效指針'。 – Wlad

+0

@Wlad然後你正在做一些你沒有向我們展示的東西。你是否在陣列上調用'free'?如果你有真正的數組,就沒有必要。只有'free'是你的'malloc'(直接或間接的,例如'calloc')。 –

+0

這樣的錯誤完全可能是由程序執行中的早期alloc/free錯誤引起的。我建議使用像valgrind這樣的malloc調試器來查找這些... – BadZen

0

我相信你不會真正理解calloc的工作原理。使用

char (*arr)[num_of_lines] = calloc(num_of_lines, sizeof(char*) * max_len); 

calloc第一個參數將塊分配用於一個陣列和所述第二參數將在每個字節塊的大小的量可以不分配給存儲器陣列的成員。

相反,你要定義這樣

char *arr[num_of_lines]; 

數組現在通過每個成員需要循環,併爲它

for(int i = 0; i < num_of_lines; i++) { 
    arr[i] = malloc(sizeof(char) * max_len); 
} 

分配內存或者你可以定義數組爲靜態數組,因爲你知道max_len的大小。

0

由於在添加多餘字符時,每個字符串的末尾都會覆蓋字符串終止符(空字符== 0),因此您會看到該行爲。

代替使用的存儲器的一個連續塊的,你要分別保持串的指針數組,並分配每個字符串:

char *strings[]; 
strings = calloc(sizeof(char*),NUMBER_OF_STRINGS); 
for i = 0; i < NUMBER_OF_STRINGS; i++ { 
    strings[i] = calloc(sizeof(char), MAX_STRING_LENGTH+1); 
} 

然後,當要一個字符添加到字符串使用strcat的,如果新的總小於最大字符串長度:

strcat(strings[i],"-suffix"); 

或者,如果是更長的時間,你就需要重新分配存儲:

strings[i] = realloc(strings[i], MAX_STRING_LEN+EXTRA_BYTES+1); 
strcat(strings[i],"-suffix"); 
+0

我需要使用一塊內存,因爲我將使用MPI來分散這個數組。 – Wlad

+1

爲什麼?只需MPI_Send(或分散)每個字符串。 – BadZen

+0

其實你是對的,那會容易得多。 – Wlad