2016-11-12 69 views
0

我試圖讓C++程序管理學生列表,但從一開始就陷入錯誤。這是我的計劃:存儲字符數組值錯誤(C++)

#include<iostream> 
#include<string.h> 
using namespace std; 
struct Candidate 
{ 
    char id[5]; 
char fullname[30]; 
int reading, listening,total; 
}; 
int main() 

{ 
struct Candidate can[100]; 
int n=0; 
do { 
    cout << "Input number of candidate:"; 
    cin >> n; 
    if (n <= 0 || n>=50) 
     cout << "Candidate number must be between 0 and 50:\n"; 
} while (n <= 0 || n>=50); 
for (int i = 0; i < n; i++) 
{ 
    cout << "Input information for candidate number " << i + 1 << endl; 
    cin.ignore(32323, '\n'); 
    cout << "Input ID(only 5 character):"; 
    gets(can[i].id); 
    cout << "Input full name:"; 
    gets(can[i].fullname); 

    do { 
     cout << "Input reading mark:"; 
     cin >> can[i].reading; 
     if(can[i].reading < 5 || can[i].reading>495) 
      cout<<"Your reading mark is not between 5 and 495\n"; 
    } while (can[i].reading < 5 || can[i].reading>495); 
    do { 
     cout << "Input listening mark:"; 
     cin >> can[i].listening; 
     if(can[i].listening < 5 || can[i].listening>495) 
      cout<<"Your listening mark is not between 5 and 495\n"; 
    } while (can[i].listening < 5 || can[i].listening>495); 


    can[i].total = can[i].reading + can[i].listening; 
} 
cout << endl << can[0].id<<endl; 
} 

,所以我得到這樣的輸出:

Input number of candidate:1 


Input information for candidate number 1 


Input ID(only 5 character):EW2RR 


Input full name:Test1 


Input reading mark:344 


Input listening mark:233 

EW2RRTest1 

好像全名的值寫入不斷地ID。我嘗試了很多方法來修復,但無法弄清楚。有人有線索嗎?

+0

也許它會更容易使用'std :: string'和相關的流函數。畢竟這是C++。如果你能夠傳遞緩衝區的長度,那麼'fgets'是一個更好的選擇。 –

+0

查看''輸入ID(只有5個字符)「,你應該使用'char id [6]'而不是'char id [5]'。可能還有其他一些問題,你應該學習如何調試你的代碼(問題的底線意味着你正在嘗試修復它而不進行調試)。 –

回答

0

在如果有N的字符串長度每串必須具有關於「\ 0」大小至少N + 1的字符數組表示該字符串結尾這裏COUT停止打印。

在你的情況,你聲明的大小5的字符數組和您填寫的所有5個字符所以「\ 0」放在別的地方。請注意,「id」和「fullname」彼此相鄰,所以我最好的猜測是,當你掃描「ID」應該是「id [5]」到「全名[0]」時,得到'\ 0'。 ,然後當你掃描「FULLNAME」時,它將替換這個'\ 0',所以「id」沒有終點,並且必須使用「全名」的終點。這就是爲什麼它看起來像全名已被追加到id。請注意,這不是默認行爲,程序在其他機器上可能會有所不同。

此外,gets()函數是一個破碎的功能,如果你之前使用CIN或scanf,你應該通過調用

fflush(stdin); 

使用之前得到(),因爲有時「\ n」是第一刷新你的標準輸入留在標準輸入,但在你的情況下,這是照顧

cin.ignore(32323, '\n'); 

使用fgets()作爲保羅魯尼說是更可取的。我自己也遇到了很多問題。

快樂編碼!

0

你需要把終端'\0'字符在每個字符串的結尾。

打印ID時,代碼(cout)不會停止,直到遇到NULL

這稱爲溢出緩衝區。

+0

我應該是確切的:讓我改變我的條款。 –

+0

(好的;經驗教訓:不要在評論中點擊。)當我說上面的「字符串」時,用「字符數組」替換它。當他提到一個字符串對象時,Paul Rooney很好。這個字符串類隱藏了你所需要的終端NULL,所以你不需要處理這些細節。同樣,使用C++字符串類處理字符串比使用C string.h庫更容易。 (除了輸出!我從來沒有能夠看到任何值寫或執行輸出與cout通過printf。幸運的是,你不需要擔心效率。) –

+0

@Poomrokc解釋你如何需要考慮管理這些終端'\ 0's。我對他的解釋做出的唯一修改是:打擊 - 「我最好的猜測」,因爲他的期望是完美無缺的。此外,如果先填充'fullname []',然後填寫'id []',則輸出將沿着'id =「EW2RR」'和'fullname =「」'的行。也就是說,'fullname []'看起來像是一個空字符串(實際上按照定義_ *將是* _),儘管你已經填充了它。 –