2010-03-09 124 views
9

當您將cin >> letter轉換爲int變量時會發生什麼?我嘗試了簡單的代碼來添加2​​個int數字,首先閱讀它們,而不是添加它們。但是,當我輸入字母時,它只是失敗並打印大量的數字。但是什麼導致了這個錯誤?我的意思是,我期望它加載並使用該字母的ASCII碼。C++字符轉換爲int

+1

你可以發佈你使用的代碼嗎? – 2010-03-09 09:24:00

回答

3

如果您明確地將您的char轉換爲int類型,它將使用ASCII代碼,否則它不會自己對int進行轉換,因此您會得到奇怪的結果。

1

你可以使用int istream::get();

10

我假設你有這樣的代碼:

int n; 
while (someCondition) { 
    std::cin >> n; 
    ..... 
    std::cout << someOutput; 
} 

當你輸入的東西,不能被理解爲一個整數,流(的std :: CIN)進入故障狀態和所有後續嘗試輸入失敗,只要你不處理輸入錯誤。

您可以測試的輸入操作的成功:

if (!(std::cin >> n)) //failed to read int 

,您可以流恢復到良好的狀態,並丟棄處理的字符(導致輸入失敗輸入):

std::cin.clear(); 
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n'); 

另一種可能性是接受輸入到字符串變量(很少失敗)並嘗試將字符串轉換爲int。

這是一個非常常見的輸入問題,在這裏和其他地方應該有大量關於它的線程。

+0

謝謝,所以如果我得到它的權利,stdout實際上發送ASCII代碼到程序,但std :: cin認識到它是什麼類型,並以此方式使用它。 – Vit 2010-03-09 10:06:46

+1

如果您希望輸入** int **變量,那麼「123」確定,但「xyz」會使輸入操作失敗。該流只是從輸入中獲得一系列字符,但它會根據您請求的類型執行轉換,並以您可以測試的方式指示失敗。 – visitor 2010-03-09 11:23:26

1

問題在於,當您使用C++流讀入整數變量時,輸入法需要可以組成數字的字符,例如'+',' - ','0'...'9 」。任何不在此集合中的字符都會終止輸入,並從這些字符創建一個數字。

要獲取字符的ASCII值,需要將數據輸入到char變量中。它在內部具有ASCII值(提供程序不讀取16位字符或EBCDIC)。如果要查看ASCII值,則需要輸出整數變量(通常需要在輸出之前進行強制轉換)。

如果讀取整數失敗,程序需要通知用戶輸入不正確。程序可能要求用戶在程序可以處理輸入數據之前再次輸入該號碼。

1

當你正在做的事情,如:

int x; 
cin >> x; 

您指示C++的期望來讀取鍵盤的int。實際上,當你輸入的東西不是int時,輸入流(在本例中爲標準輸入)由於其錯誤狀態而呈現不可用。

這就是爲什麼我個人更喜歡總是讀取字符串,並根據需要將它們轉換爲數字。 C++標準庫的C部分有轉換功能,可以幫助實現這一點。

double cnvtToNumber(const std::string &num) 
{ 
    char * ptr; 
    double toret = strtod(num.c_str(), &ptr); 

    if (*ptr != 0) { // If it got to the end of the string, then it is correct. 
     throw std::runtime_error("input was not a number"); 
    } 
    return toret; 
} 

在這裏,您正在轉換一個數字,並檢測轉換是否正確。strtod(s)只會在查找字符串末尾或空格時停止。爲了避免尾隨空格愚弄功能,你可以需要一個微調功能:

std::string &trim(std::string &str) 
{ 
    // Remove trailing spaces 
    unsigned int pos = str.length() -1; 

    while(str[ pos ] == ' ') { 
     --pos; 
    } 

    if (pos < (str.length() -1)) { 
     str.erase(pos + 1); 
    } 

    // Remove spaces at the beginning 
    pos = 0; 
    while(str[ pos ] == ' ') { 
     ++pos; 
    } 

    if (pos < 1) { 
     str.erase(0, pos); 
    } 

    return str; 
} 

現在可以安全地從控制檯(或任何其他輸入流)閱讀:

int main() 
{ 
    std::string entry; 

    try { 
     std::getline(std::cin, entry); 
     int age = cnvtToNumber(trim(entry)); 

     std::cout << age << std::endl; 
    } catch(const std::exception &e) { 
     std::cerr << e.what() << std::endl; 
    } 
} 

當然,你可以如果你總是讀double然後轉換它們,會失去精度。整數有特定的功能(strtol(s)),以防您想進一步調查。