std::getline does not work inside a for-loop

2020-02-10 08:26发布

I'm trying to collect user's input in a string variable that accepts whitespaces for a specified amount of time.

Since the usual cin >> str doesn't accept whitespaces, so I'd go with std::getline from <string>

Here is my code:

#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
using namespace std;
int main()
{
    int n;
    cin >> n;
    for(int i = 0; i < n; i++)
    {
        string local;
        getline(cin, local); // This simply does not work. Just skipped without a reason.
        //............................
    }

    //............................
    return 0;
}

Any idea?

标签: c++ getline
8条回答
一纸荒年 Trace。
2楼-- · 2020-02-10 08:55

You can see why this is failing if you output what you stored in local (which is a poor variable name, by the way :P):

#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
using namespace std;
int main()
{
    int n;
    cin >> n;
    for(int i = 0; i < n; i++)
    {
        string local;
        getline(cin, local);
        std::cout << "> " << local << std::endl;
    }

    //............................
    return 0;
}

You will see it prints a newline after > immediately after inputting your number. It then moves on to inputting the rest.

This is because getline is giving you the empty line left over from inputting your number. (It reads the number, but apparently doesn't remove the \n, so you're left with a blank line.) You need to get rid of any remaining whitespace first:

#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
using namespace std;
int main()
{
    int n;
    cin >> n;
    cin >> ws; // stream out any whitespace
    for(int i = 0; i < n; i++)
    {
        string local;
        getline(cin, local);
        std::cout << "> " << local << std::endl;
    }

    //............................
    return 0;
}

This the works as expected.

Off topic, perhaps it was only for the snippet at hand, but code tends to be more readable if you don't have using namespace std;. It defeats the purpose of namespaces. I suspect it was only for posting here, though.

查看更多
Rolldiameter
3楼-- · 2020-02-10 09:04

You can directly use getline function in string using delimiter as follows:

#include <iostream>
using namespace std;
int main()
{
    string str;
    getline(cin,str,'#');
    getline(cin,str,'#');
}

you can input str as many times as you want but one condition applies here is you need to pass '#'(3rd argument) as delimiter i.e. string will accept input till '#' has been pressed regardless of newline character.

查看更多
The star\"
4楼-- · 2020-02-10 09:05

On which compiler did you try this? I tried on VC2008 and worked fine. If I compiled the same code on g++ (GCC) 3.4.2. It did not work properly. Below is the versions worked in both compilers. I dont't have the latest g++ compiler in my environment.

int n;
cin >> n;
string local;
getline(cin, local); // don't need this on VC2008. But need it on g++ 3.4.2. 
for (int i = 0; i < n; i++)
{
    getline(cin, local);
    cout << local;
}
查看更多
够拽才男人
5楼-- · 2020-02-10 09:06

Are you hitting enter? If not get line will return nothing, as it is waiting for end of line...

查看更多
一夜七次
6楼-- · 2020-02-10 09:07

My guess is that you're not reading n correctly, so it's converting as zero. Since 0 is not less that 0, the loop never executes.

I'd add a bit of instrumentation:

int n;
cin >> n;
std::cerr << "n was read as: " << n << "\n"; // <- added instrumentation
for // ...
查看更多
smile是对你的礼貌
7楼-- · 2020-02-10 09:08
  • Is n properly initialized from input?
  • You don't appear to be doing anything with getline. Is this what you want?
  • getline returns an istream reference. Does the fact that you're dropping it on the ground matter?
查看更多
登录 后发表回答