2015-11-03 31 views
3

嘿傢伙我是一個相對較新的程序員在C,我試圖簡單地將輸入文件中的內容打印到我的屏幕上。我必須使用動態內存分配,我面臨的問題是如果字符串中的字母數大於8,它會覆蓋它。動態內存分配從輸入文件的數組字符串

int main(){ 
FILE *input = fopen("inpit.txt","r"); 
int b; 
char **aPtr; 
int i = 0; 
int j = 0; 
fscanf(input,"%d",&b); //takes first value from input file which tells me number of strings in the file 
aPtr = (char **)malloc(sizeof(char *)*b); 
for(i=0;i<b;i++) { 
    aPtr[i]=(char *)malloc(sizeof(char)); 
} 
for(i = 0;i < b;i++){ 
    fscanf(input,"%s",&aPtr[i]); 
} 
for(i = 0;i < b;i++){ 
    printf("Address %d = %d\n",i,&aPtr[i]); 
} 

for(i = 0;i < b;i++){ 
    printf("%s\n",(aPtr+i)); 
} 
return 0; } 

我輸入到文件inpit1.txt是:

5 
grapefruit 
apple 
Banana 
monkey 
orange 

如果我運行該文件。除了葡萄柚之外,一切都會打印出來。這將被覆蓋到grapefruapple。

任何幫助,將不勝感激。先謝謝你。

+0

你可能已經得到了更好的結果,如果你沒有在C項目尋找C++文檔!不要爲外語添加標籤!並且不要將'malloc'和朋友的結果放在C中! – Olaf

+1

哦,並正確縮進你的代碼! 'main'的簽名是錯誤的!寫100次:「C不是C++不是C!」 – Olaf

+0

@Olaf寫100遍:「C不是C++不是C!」哈哈好:) – LBes

回答

2

你必須與你的malloc一個問題,只分配了一個字符的位置:

aPtr[i]=(char *)malloc(sizeof(char)); 

嘗試給定的尺寸添加到它:

aPtr[i]=(char *)malloc(sizeof(char)*20); 

它應該更好地工作

關於鑄造malloc()的注意事項: 鑄造malloc()在c中是沒有必要的(除非處理超舊的st [1989年以前]),並可以隱藏錯誤。 void*會自動提升爲任何其他指針類型。 但是,如果編譯爲C++,這很有用,因爲你的問題包括C和C++,我認爲這很好的告訴你。

編輯:有關演員的其他信息malloc()我剛剛發現這個受保護的問題here。隨時檢查一下。

你也需要檢查malloc()是成功的(結果是!=NULL

最後你的printf是不正確的,應該是printf("%s\n", aPtr[i]);

2

問題,我看到:

  1. 你是沒有爲aPtr[i]分配足夠的內存。

    aPtr[i]=(char *)malloc(sizeof(char)); 
    

    分配內存只有一個char。舉行一個字符串是不夠的。你需要的東西,如:

    int arraySize = 20; // Make it large enough 
    aPtr[i] = malloc(arraySize); // No need to use sizeof(char). 
              // It is always 1 
    
  2. 確保當你讀的字符串,你不溢出數組的大小。相反的:

    fscanf(input,"%s",&aPtr[i]); 
    

    使用:

    fscanf(input,"%19s", aPtr[i]); 
    //     ^^^ Remove the & operator. That is wrong. 
    //   ^^^ Add size to prevent overflow. 
    
  3. 您使用了錯誤的參數給printf功能。相反的:

    printf("%s\n",(aPtr+i)); 
    

    使用

    printf("%s\n", *(aPtr+i)); 
    //   ^^^ Missing pointer dereferencing operator 
    

    printf("%s\n", aPtr[i]); 
    
0

對你的問題的第一個評論是正確的,在這個問題的心臟。
malloc(sizeof(char))真的只是malloc(1)

您所做的一切是...

分配n字符數組的指針

aPtr = (char **)malloc(sizeof(char *)*b); 

分配單個字符列表中的每個指針

for(i=0;i<b;i++) { 
    aPtr[i]=(char *)malloc(sizeof(char)); 
} 

將未知長度的字符串複製到分配給每個p的內存中在列表中輸入。

for(i = 0;i < b;i++){ 
    fscanf(input,"%s",&aPtr[i]); 
} 

分配給每個字符指針的內存可能與分配給其前任的內存接近或連續。後續寫入可能會覆蓋前面字符串的某些部分。就你的例子而言,連續分配的記憶塊之間似乎存在足夠的空隙,只有'葡萄柚'條目足夠長時間才能被其鄰居明顯踐踏。

0

你去那裏:)(我試過在評論中講解)

int main() { 

    FILE * pFile; 
    char * buffer = NULL; 
    size_t size = 0; 
    ssize_t line_length; 

    pFile = fopen("inpit.txt", "r"); 
    if (pFile != NULL) { 
     int number_of_lines; 
     fscanf(pFile, "%d", &number_of_lines); 

     //create charcter pointers array to hold each line 
     char* strings[number_of_lines]; 

     int i = -1; 
     while ((line_length = getline(&buffer, &size, pFile)) != -1) { 
      if (i != -1) { // skips first line because its number of lines (5) 
       strings[i] = malloc(line_length * sizeof(char)); //allocate memory for the line 
       sprintf(strings[i], "%s", buffer); //copy line from buffer to allocated space 
      } 
      //incase file has more than it said 
      if (i++ >= number_of_lines) { break; } 
     } 

     //Test print 
     for (i = 0; i <= number_of_lines; i++) { 
      printf("%s", strings[i]); 
     } 
     printf("\n"); 

     fclose(pFile); 
     if (buffer) { free(buffer); } 
    } 
}