C ++ --- getline和cin ignore().在输出的字符串中删除第一个字符 [英] C++ --- getline, and cin ignore () .deleting first characters in strings on output

查看:81
本文介绍了C ++ --- getline和cin ignore().在输出的字符串中删除第一个字符的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

#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()代码.它会忽略输出中输入字符串的第一个字符.该代码可以编译,但是输入和输出是倾斜的.

As you can see its a simple code for learning structs and experimenting. The problem i run into appears to be from cin.ignore () code. it ignores the first characters of the input strings on output. The code does compile, however input and output are skewed.

例如,当我输入Terry的名称时,它将输出erry.

For example when i enter a name of Terry, it will output erry.

我曾尝试删除 cin.ignore(),但是当我这样做时,输出会跳过用户需要输入数据的部分,并使区域空白.我在论坛上进行了搜索,发现了一些建议,例如向 cin.ignore(std :: numeric_limits< std :: streamsize> :: max(),'\ n'); 添加参数.例如,但这并不能解决问题,只会增加我遇到的错误列表.

I have tried removing the cin.ignore (), however when i do that, the output skips over the parts where the user needs to enter data and leaves areas blank. I have scoured the forums and found suggestions such as adding an argument to the cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');. for example, however this does not solve the problem and only adds to the list of errors I'm experiencing.

推荐答案

问题

问题在于放置 ignore 可以防止

The Problem

The problem is with the placement of ignores to prevent the bug outlined in Why does std::getline() skip input after a formatted extraction? The ignores have been placed before the getlines, and while this solves the getline skipping problem, it causes the problem the Asker has encountered. There isn't always something that needs to be ignored.

例如

cin >> userAmountSelection;

如果用户键入金额然后按Enter键,则会在流中保留一行结尾.

will leave a line ending in the stream if the user typed in the amount and then hit enter.

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

如果 ignore ,则 for 循环内的

将越过此行结束.但是 getline 不会在流中保留换行符,因此循环的第二次及其后的迭代都不会忽略换行符.相反,部分需要的数据被忽略.

inside the for loop Would trip over this line ending if not for the ignore. But getline does not leave a newline in the stream , so the second and subsequent iterations of the loop have no newline to ignore. Part of the requiured data is ignored instead.

之后

cin >> userAmountSelection;

而不是以前

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

将是放置 ignore 的好地方,因此只有在将换行符留在流中之后,才将其从流中删除,但是...

would be a good place to place an ignore so the newline is removed from the stream only after it has been left in the stream, but...

处理此问题的最佳方法是始终使用 getline 读取整行,然后解析这些行(请参阅此答案的选项2 ).

The best way to handle this is to always read entire lines with getline and then parse those lines (see option 2 of this answer) into the pieces you want.

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

这始终有效(注意:需要 #include< sstream> ),现在您只能进行一种阅读类型,而不是一场混合-对战游戏,在这种情况下您可能会忘记自己需要 ignore .

This always works (Note: Requires #include <sstream>) and now you only have one type of reading going on, not a game of mix-n-match where you may forget you need an ignore.

随时停止阅读.

ignore 方法需要一些额外的技巧.除了人类记忆的易错性之外,它并不像看起来那样简单.您应该在操作后放置 ignore ,该操作会将不需要的内容留在流中.如果您在进行操作之前 ignore ,您经常会发现自己丢失了所需的数据,因为您无需进行 ignore 的操作.

The ignore approach requires some extra smarts. It's not as simple as it looks, in addition to fallibility of the human memory. You should place ignores AFTER an operation that leaves unwanted stuff in the stream. If you ignore BEFORE an operation, you often find yourself losing data you wanted because there was nothing to ignore.

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

经常工作,但是如果用户输入金额然后输入空格,然后按Enter或键入他们需要输入的所有输入,因为他们很好地掌握了下一个提示,那该怎么办呢?您将变得更加狡猾.

Works a lot of the time, but what if the user typed in the amount and then a space and then hit enter or typed in all of the input they needed to type because they new darn well what the next prompt was? You gotta get a bit craftier.

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

ignore 会消灭所有内容,直到碰到行尾或流中的空间用完为止.(注意:需要 #include< limits> )

This ignore annihilates everything until it hits the end of the line or runs out of space in the stream. (Note: Requires #include <limits>)

这篇关于C ++ --- getline和cin ignore().在输出的字符串中删除第一个字符的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆