2017-02-08 34 views
1

我寫了如下簡單的C++結構實現來查看指向結構的指針的用法。C++結構字符串和整數輸入

#include <iostream> 

struct Employee 
{ 
    std::string name; 
    std::string sex; 
    int e_id; 
}emp[2]; 

void printEmployee(struct Employee *e) 
{ 
    std::cout << e->name << std::endl; 
    std::cout << e->sex << std::endl; 
    std::cout << e->e_id << std::endl; 
} 

int main(int argc, char const *argv[]) 
{ 
    struct Employee *e_ptr; 
    e_ptr = emp; 

    for (int i = 0; i < 2; ++i) 
    { 
     std::getline(std::cin, emp[i].name); 
     std::getline(std::cin, emp[i].sex); 
     std::cin >> emp[i].e_id; 
    } 

    for (int i = 0; i < 2; ++i) 
    { 
     printEmployee(e_ptr+i); 
     std::cout << std::endl; 
    } 
    return 0; 
} 

的輸入是

John Smith 
male 
123 
Sarah Collin 
female 

這些輸入之後,程序將顯示輸出雖然代碼應該採取一個以上輸入。輸出是

John Smith 
male 
123 



Sarah Collin 
0 

,但如果我不包括int e_id成爲會員,然後代碼工作完美。

回答

2

這是來自getline和cin的混合。 Getline讀取輸入,直到遇到(通常)換行符'\ n'。它將所有內容都放到換行符中,並拋出換行符。

cin讀取直到你點擊空格(比如說換行符),但不會將它從流中拋出。所以,你輸入123 ENTER,這意味着你在流中有123個\ n。 Cin帶123,但離開\ n。

現在你回到員工姓名的getline,立即看到流中的\ n,這意味着它已完成,並將其拋棄。出於好奇,如果你輸入123 SPACE而不是輸入,它是否工作?

所以實際上發生的事情是John Smith很好,男性很好,123很好,但是第二個員工的名字被跳過了,你在Sarah Collin中輸入了技術上的性別,然後輸入了女性的內容是e_id。既然女性不是一個整數,會發生什麼? Cin默認情況下會進入錯誤狀態並跳過進一步的cin操作(您也可以將其配置爲引發異常)。所以你真的從來不會爲第二個e_id輸入任何東西,而你看到的0就是它創建時的情況(你從來沒有初始化它,所以它實際上可能是任何值!讀未初始化的值是未定義的行爲。你的編譯器可以通過爲你設置整數爲0來幫助你,但這不是一種你可以依靠的善意)。

這裏是別人用你的問題,以及如何使用

cin.ignore(); 

來解決這樣的一個例子。您需要手動忽略該換行符。

When and why do I need to use cin.ignore() in C++?

+0

明白了,謝謝:)而且,如果我輸入123SPACE而不是輸入,它確實有效。 –

2

在閱讀整數,當它遇到比[+][-][0-9]以外的字符std::cin停止。也就是說,std::cin停止在一個字符不能被包含在一個整數的有效表示。

在第三行輸入有4個字符是123\n

在閱讀std::string時,std::getline在遇到\n或分隔符字符時停止閱讀字符。另外,std::getline不會在正在讀取的字符串中存儲\n或分隔字符。

因此,std::cin按預期讀取整數emp[0].e_id,並停止在\n。在此之後std::getline讀取\n並停止並不存儲任何東西emp[1].name