2013-03-11 106 views
0

我正在寫的代碼輸入一個文件,並作爲一個單獨的字符中的每個字爲單位讀取*是這樣的:分配特定的char *數組元素的數組的所有元素設置到該元素 - C++

char label[8]; 
char type[5]; 
char value[6]; 


while (!input.eof()) { 
    input >> label; 
    input >> type; 
    input >> value; 
    storeSymbols(label, type, value); 
} 

然後我將其設置爲一個char *陣列的像這樣的元件:

void storeSymbols(char* lab, char* type, char* val) { 
    labels[symCount] = lab; 
    types[symCount] = type; 
    values[symCount] = val; 
    symCount++; 

}

然而,當我打印出所有的字符*陣列的元件,所有的元素都相同最後一個元素retri從文件中刪除。例如,如果文檔中有三個標籤,分別定義爲「one」,「two」和「three」,則在第一個循環結束時,數組將包含「one」,第二次包含「兩「和」兩「,第三次將包含」三「」三「和」三「。它還循環了一段額外的時間,再次將最後一個元素添加到數組中,使其在數組中成爲四個「三」元素。有誰知道爲什麼會發生這種情況?

我也測試過這裏,我將值轉換爲一個int並將其添加到一個int數組,它工作正常。

+0

第二位的代碼是否也在第一位代碼的循環內? – Xymostech 2013-03-11 01:56:50

+0

我想我們在這裏需要更多的代碼。 – SirPentor 2013-03-11 01:58:18

+0

您需要複製/複製字符串,而不是一遍又一遍地分配指向同一緩衝區的指針(這正是您現在正在執行的操作)。 – 2013-03-11 02:00:45

回答

0

正在讀取輸入的循環只是將每個項目存儲到之前使用的相同緩衝區中。例如,input >> label每次將讀取的項目存儲到相同的char label[8]緩衝區中。所以在任何時候,label數組只包含最近讀取的項目。

然後,當您嘗試在storeSymbols()中保存該信息時,您將傳遞label數組的地址 - 每次都有相同的地址。因此,labels數組中的每個元素(我假設它是一個數組char*)獲取相同的指針 - 它們每個都指向相同的正在更新的緩衝區。

一個簡單的更改可以讓您存儲指向不同項目的指針,可以使用strdup()來複制字符串。如果您的作業中不允許使用strdup(),則可以使用少於10行的代碼將等同物編寫爲函數。

如果使用strdup(),你不使用它們存儲指向將被動態分配的,所以你需要釋放他們時,你就大功告成了弦:

for (i = 0; i < symCount; ++i) { 
    free(labels[i]); 
    free(types[i]); 
    free(values[i]); 
} 

爲了您的有關問題在從輸入讀取最後一個項目之後循環一段額外的時間,用於讀取輸入的循環使用直接檢查EOF的反模式。 EOF直到您實際嘗試在輸入流爲'空'時執行讀取時才設置。見Why is 「while (!feof (file))」 always wrong?http://drpaulcarter.com/cs/common-c-errors.php#4.2

嘗試:

while (input >> label >> type >> value) { 
    storeSymbols(label, type, value); 
} 

此外,請確保您的輸入緩衝器是爲您的數據足夠大(記住空終止符)。理想情況下,您可以使用在讀取輸入時動態擴展的數據類型(如std::string)。

+0

太棒了,我使用了strdup()並且工作正常!謝謝! – 2013-03-11 18:14:11

0

您明確使用C++而不是C,因此請使用std::string而不是char *來存儲標籤,而使用vector而不是數組來存儲標籤等。

因此:

std::vector<std::string> labels, types, values; 

std::string label, type, value; 
input >> label >> type >> value; 

labels.push_back(label); 
types.push_back(type); 
values.push_back(value); 

爲何您會看到相同的輸出反覆是因爲你推指針相同的固定全局數組,這是反覆input >> label覆蓋的原因。 std::string通過複製和分配內部緩衝區(全部自動完成)來避免這種情況。

+0

問題是,這是一個可選的練習,我正在採用一個班,老師告訴我們,我們只能使用char *,因爲她希望我們主要關注編碼C.不能告訴你爲什麼,但這就是她想要的。 – 2013-03-11 02:17:04

+0

這是錯誤的。只是......錯了。你有C++,而你被要求用C語言編寫代碼。這會讓不好的C++程序員認爲他們沒有更好的使用方式,但是堅持和堅持。我聲稱你應該跳過作業並告訴老師,如果她想要你使用C,她應該很好地教C而不是C++。 – nneonneo 2013-03-11 02:18:44

+0

這是班上每個人都在說的話。我可能只是使用std :: string來冒險取得積分。可能是最好的。 – 2013-03-11 02:27:34