[英]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::cin
和getline
調用之間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.