2017-10-13 53 views
0

創建具有以下代碼控制檯應用程序(重命名F到您的入口點):的std ::出2D炭的外部尺寸

#include <iostream> 
void f(){ 
    char a[5][5]; 
    std::cin>>a[0]>>a[1]>>a[2]>>a[3]>>a[4]; 
    for (int y = 0; y<5; y++)std::cout<<a[y]<<'\n'; 
} 

和輸入5行的5個字符,例如:

abcde 
abcde 
abcde 
abcde 
abcde 

我期望的輸出是與輸入相同或拋出異常,而是我得到:

abcdeabcdeabcdeabcdeabcde 
abcdeabcdeabcdeabcde 
abcdeabcdeabcde 
abcdeabcde 
abcde 

當INVE使用調試器進行標記,每個a[y]的值等於abcde,而不是顯示的輸出。 這到底是怎麼回事? 爲什麼發生這種情況,有沒有辦法阻止它?

這是否與周圍的變量 'a' 被破壞

錯誤,那是被後std::cout小號拋出

堆棧?


我很清楚的其它方式使用嵌套的循環,以獲得所需的輸出,但我不知道是否有迭代只有外部尺寸的方式,以便它使用更少的字符 - 這是一個代碼高爾夫挑戰。這使得相當多的區別:

for(int y=0;y<5;y++)std::cout<<a[y]<<'\n';

VS

for(int y=0;y<5;y++){for(int x=0;x<5;x++)std::cout<<a[y][x]}std::cout<<'\n';

+1

你處於未定義行爲的境界。爲了存儲'n'字符串,你需要保留'n + 1'字符,因爲C字符串需要NULL結束符。 –

+0

@jaunt您試圖將數組作爲字符串輸出,但它們不包含字符串,因爲沒有空間用於終止零。 –

+1

在執行cin >> a [y + 1]之前和之後檢查調試器a [y],您會注意到一些奇怪的現象,因爲後一個命令會覆蓋前一個char [5]空終止符。正如R Saku在答案中所說的,使用'string'而不是普通的字符數組(而不是普通的數組[]來代替vector)會讓你的生活更加輕鬆。 –

回答

3

的問題是事實,你試圖存儲"abcde"在字符數組有5個元素而引起的。數組中至少還需要一個元素來保存終止的空字符。

因此,您的程序具有未定義的行爲。我們可以嘗試理解輸出,但它是徒勞的。

使用

char a[5][6]; // Anything greater than 5 will work for your input 

如果你不希望你的代碼被捆綁到一個硬編碼的大小,則可以使用std::string

std::string a[5]; 
+0

哇,我很驚訝,我們必須明確地爲終止符分配空間,編譯器明確知道它是需要的嗎? – jaunt

+1

@jaunt,當數據讀取到字符串的函數被調用時,大小信息將丟失。 –

1

C字符串是一個以空終止符結尾的字符序列。這意味着"abcde"實際上是6個字符,您看到的5個加上空終止符。

由於您只爲輸入分配了足夠的空間而沒有空終止符嘗試將字符串放入數組中,因此寫入數組的末尾並且是未定義的行爲。你需要的是

char a[5][6]; 

因爲這將有足夠的空間5個字符加空終止符。