按空格或换行符分隔读取输入...?

26
我正在从标准输入流中获取输入,例如,
1 2 3 4 5
或者
1
2
3
4
5

我正在使用:

std::string in;
std::getline(std::cin, in);

但是那只是获取到换行符之前的内容,对吗?我该如何使用仅限 iosteam、string 和 cstdlib 来获取用户输入,无论它们是用换行符还是空格分隔?


如果换行符不是终止条件,那么终止条件是什么?也就是说,getline应该如何知道何时返回? - ildjarn
1
程序将接受输入,直到达到“q”为止,此时程序将退出。但它需要读取“q”。在那之前,我想无论输入是由空格、换行符还是混合匹配分隔的,都可以接受输入。 - user618712
8个回答

37

直接使用:

your_type x;
while (std::cin >> x)
{
    // use x
}

operator>>默认会跳过空格。你可以链接多个变量以一次读取它们:

if (std::cin >> my_string >> my_number)
    // use them both

getline()函数读取一整行内容,即使该行为空或包含数十个以空格分隔的元素,它也会将其全部读入返回。如果你提供可选的备用定界符(如:getline(std::cin, my_string, ' ')),它仍然无法满足你想要的需求,例如制表符会被读入到my_string中。

也许现在不需要,但你可能在不久的将来会遇到一个相当常见的需求,即读取单独由换行符分隔的一行,然后将其拆分成各个组成部分...

std::string line;
while (std::getline(std::cin, line))
{
    std::istringstream iss(line);
    first_type first_on_line;
    second_type second_on_line;
    third_type third_on_line;
    if (iss >> first_on_line >> second_on_line >> third_on_line)
        ...
}

1
你的 if (std::cin >> my_string >> my_number) 处理了数字可能出现在水平和/或垂直方向的情况。 - lifebalance
@lifebalance:是的,不过如果需要更多的控制/格式验证。我回答的最后一部分展示了如何先读取行,然后解析其中的“水平”元素。 - Tony Delroy

5

使用'q'作为getline的可选参数。

#include <iostream>
#include <sstream>

int main() {
    std::string numbers_str;
    getline( std::cin, numbers_str, 'q' );

    int number;
    for ( std::istringstream numbers_iss( numbers_str );
          numbers_iss >> number; ) {
        std::cout << number << ' ';
    }
}

http://ideone.com/I2vWl


2

std::getline( stream, where to?, delimiter ie

std::string in;
std::getline(std::cin, in, ' '); //will split on space

或者你可以将文本读入一行,然后根据任何你希望的分隔符进行标记化。


4
除非这不会在换行符或空格处分割。 - Mike Seymour
1
有没有一种合理的C++方法来获取文本? - Owl

1
用户按下回车键或空格键都是一样的。
int count = 5;
int list[count]; // array of known length
cout << "enter the sequence of " << count << " numbers space separated: ";
// user inputs values space separated in one line.  Inputs more than the count are discarded.
for (int i=0; i<count; i++) {
    cin >> list[i];
}

0
int main()
{
    int m;
    while(cin>>m)
    {
    }
}

如果输入是以空格分隔或换行符分隔的,则会从标准输入读取。


0
#include <iostream>

using namespace std;

string getWord(istream& in) 
{
    int c;

    string word;

    // TODO: remove whitespace from begining of stream ?

    while( !in.eof() ) 
    {

        c = in.get();

        if( c == ' ' || c == '\t' || c == '\n' ) break;

        word += c;
    }

    return word;
}

int main()
{
    string word;

    do {

        word = getWord(cin);

        cout << "[" << word << "]";

    } while( word != "#");

    return 0;
}

0

这个问题有很多答案,其中一些非常高质量并且有解释。为什么选择这个答案? - SimonC
@SimonC 就我个人而言,上面的答案并没有直接解决我的问题,因此我添加了评论。 对于初学者来说,链接中描述的答案可能会带来一些额外的好处,并希望能够直接解决问题。 感谢您的理解。 - David Schmid
如果它是作为评论的话,请将其添加为评论而不是回答。 - SimonC
没有“上面的答案”,至少在StackOverflow上排序是可以个性化配置的。例如,在我的排序中,您的帖子在问题下方排名第一。请通过[编辑]将您的解释移动到答案帖子本身中。尝试回答。 - Yunnosch

0
使用cin.peek()在读取单个值后检查换行符。这样,您可以在以空格分隔的字符串中读取未知数量的值。请查看示例代码。
#include <iostream>
#include <string>
#include <vector>

using namespace std;

int main()
{
    vector<int> i;
    int n;
    while (cin >> n) {
        i.push_back(n);
        if (cin.peek() == '\n')
            break;
    }

    cout << i.size() << '\n';
    return 0;
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接