簡體   English   中英

C++ --- getline, and cin ignore() .deleting 輸出字符串中的第一個字符

[英]C++ --- getline, and cin ignore () .deleting first characters in strings on output

#include <iostream>
#include <string>
using namespace std;


struct UserInfo{

    string userPhoneNumber;
    string userName ;
    string userAddress ;

};


int main ()
{
    cout << "How many Entries do you want to enter?";
    int userAmountSelection;
    cin >> userAmountSelection;

    UserInfo userOne [userAmountSelection];

    for (int i = 0; i < userAmountSelection; i++){
        cout << "Please enter your first and last name: ";
        cin.ignore(); // possible problem in code 
        getline (cin, userOne[i].userName, '\n');
        cout << "Please Enter your address, " << userOne[i].userName << ":";
        cin.ignore(); // possible problem in code 
        getline (cin, userOne[i].userAddress, '\n');
        cout << "Please enter your phone#: ";
        cin.ignore (); // possible problem in code 
        getline (cin, userOne[i].userPhoneNumber);
    }
    for (int i = 0; i < userAmountSelection; i++){
        cout << userOne[i].userName << "        " << 
                userOne[i].userAddress << "         " << 
                userOne[i].userPhoneNumber << endl;
    }

    return 0;
}

如您所見,它是用於學習結構和實驗的簡單代碼。 我遇到的問題似乎來自 cin.ignore () 代碼。 它在輸出時忽略輸入字符串的第一個字符。 代碼確實可以編譯,但是輸入和輸出是有偏差的。

例如,當我輸入 Terry 的名字時,它會輸出 erry。

我曾嘗試刪除cin.ignore () ,但是當我這樣做時,輸出會跳過用戶需要輸入數據的部分並將區域留空。 我搜索了論壇並找到了一些建議,例如向cin.ignore(std::numeric_limits<std::streamsize>::max(), '\\n');添加一個參數cin.ignore(std::numeric_limits<std::streamsize>::max(), '\\n'); . 例如,但這並不能解決問題,只會增加我遇到的錯誤列表。

問題

問題在於放置ignore s 以防止在為什么 std::getline() 在格式化提取后跳過輸入中概述的錯誤 ignore s 已經放在getline s 之前,雖然這解決了getline跳過問題,但它導致了 Asker 遇到的問題。 並不總是需要忽略的東西。

例如

cin >> userAmountSelection;

如果用戶輸入金額然后按回車鍵,將在流中留下一行結尾。

cout << "Please enter your first and last name: ";
cin.ignore(); // possible problem in code 
getline (cin, userOne[i].userName, '\n');

如果不是因為ignore則在for循環內將在此行結束時絆倒。 但是getline不會在流中留下換行符,因此循環的第二次和后續迭代沒有要忽略的換行符。 部分所需數據將被ignored

cin >> userAmountSelection;

而不是以前

getline (cin, userOne[i].userName, '\n');

將是放置ignore的好地方,因此僅在將換行符留在流中后才將換行符從流中刪除,但是......

解決方案

處理此問題的最佳方法是始終使用getline讀取整行,然后將這些行(請參閱此答案的選項 2 )解析為您想要的部分。

std::string line;
std::getline(std::cin, line);
std::istringstream(line) >> userAmountSelection;

這總是有效的(注意:需要#include <sstream> ),現在你只有一種類型的閱讀,而不是混搭游戲,你可能會忘記你需要一個ignore

現在可以隨意停止閱讀。

ignore方法需要一些額外的智慧。 除了人類記憶的易錯性之外,它並不像看起來那么簡單。 您應該在將不需要的內容留在流中的操作之后放置ignore s。 如果您在操作之前ignore ,您經常會發現自己丟失了您想要的數據,因為沒有什么可以ignore

std::cin >> userAmountSelection; // read a number
std::cin.ignore(); // discard the next character

很多時候都可以工作,但是如果用戶輸入數量,然后輸入一個空格,然后按回車鍵或輸入他們需要輸入的所有輸入,因為他們新的很好,下一個提示是什么? 你得再狡猾一點。

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

這種ignore消除所有內容,直到它到達行尾或流中的空間不足。 (注意:需要#include <limits>

我遇到的問題似乎來自 cin.ignore () 代碼。 它在輸出時忽略輸入字符串的第一個字符。

查看istream::ignore聲明

istream& ignore (streamsize n = 1, int delim = EOF);

默認情況下,它將丟棄第一個字符。


我曾嘗試刪除 cin.ignore (),但是當我這樣做時,輸出會跳過用戶需要輸入數據的部分並將區域留空。

這是因為執行的std::cin留下了一個殘留的換行符,然后被getline消耗。 您只需要在std::cingetline調用之間ignore

std::cin >> userAmountSelection;
std::cin.ignore(); //---
...
for (int i = 0; i < userAmountSelection; i++) {
    ...
    getline (...);
    ...
    getline (...)
}

此外,在某些情況下,您可能不知道std::cin是否位於getline之前。 在這種情況下,您可以在執行ignore之前檢查輸入流是否包含新行:

    ...

    // some I/O operations happening here

    ...

    // ignore if there's white space
    if (std::iswspace(std::cin.peek())) std::cin.ignore();

    std::getline(std::cin, somestring);

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM