如何从stdin读取字符串直到遇到空白行

时间:2014-09-16 14:13:18

标签: c++ stdin

考虑一个简单的程序。它必须从stdin获取字符串并保存到变量。 没有说明将采用多少行输入,但如果遇到换行符,程序必须终止。

例如: 标准输入:

abc
abs
aksn
sjja
\n

我试过但它不起作用。这是我的代码:

#include <iostream>
#include <cstring>
#include <cstdio>

using namespace std;
// Constant
#define max 100000
struct chuoi
{
       char word[10];
};
chuoi a[max];

void readStr()
{
    int i=0;
    while ( fgets(a[i].word, 10,stdin) != NULL)
    {
        if (a[i].word[0] == ' ') break;
        a[i].word[strlen(a[i].word)-1] = '\0'; //replaced \n by \0
        i++;
    }
     //length = i;
}
int main()
{
    readStr();
    return 0;
}

那么,如何解决这个问题?

2 个答案:

答案 0 :(得分:3)

此处的一种替代方法是使用std::getline来获取每一行。如果该行为空,或输入失败,则退出循环。

void readStr()
{
    std::string str;

    while ( std::getline(std::cin, str) && str.length() )
    {
        // use the string...
    }
}

在示例代码中添加std::getline并使用std::vector,并保持原始样本的精神;

#include <string>
#include <iostream>
#include <vector>

const std::size_t Max = 100000;

struct chuoi
{
    explicit chuoi(std::string const& str) : word(str)
    {
    }

    std::string word;
};

void readStr(std::vector<chuoi>& a)
{
    std::string str;
    while ( std::getline(std::cin, str) && str.length() )
    {
        a.push_back(chuoi(str));
    }
}
void writeStr(std::vector<chuoi> const& a)
{
    for (auto i = a.begin(); i != a.end(); ++i) {
        std::cout << i->word << std::endl;
    }
}
int main()
{
    std::vector<chuoi> a;
    a.reserve(Max);
    readStr(a);
    writeStr(a);
    return 0;
}

为了解决您的问题,可以按如下方式对代码进行最小的更改;

void readStr()
{
    int i = 0;
    while ( fgets(a[i].word, 10, stdin) != NULL)
    {
        a[i].word[strlen(a[i].word) - 1] = '\0'; // transform the end of line character to NULL
        if (strlen(a[i].word) == 0) {
            break;
        }
        i++;
    }
}

如果始终使用标准输入(stdin),也可以使用gets功能;

while ( gets(a[i].word) != NULL)
{
    if (strlen(a[i].word) == 0) {
        break;
    }
    i++;
}

注释;

  • fgets读取stdin上的“输入”键,但包含换行符号
  • gets也会在返回之前读取,但不包括换行符号
  • 两个函数NULL终止输入
  • 注意gets的形式,它不检查缓冲区溢出情况

答案 1 :(得分:2)

我会做这样的事情:

#include <string>
#include <iostream>

int main()
{
    std::string line; // will contain each line of input

    // Stop when line is empty or when terminal input has an error
    while(std::getline(std::cin, line) && !line.empty())
    {
        // do stuff with line
    }
}