【问题标题】:How to read string from stdin until meet blank lines如何从标准输入读取字符串直到遇到空行
【发布时间】:2014-11-10 08:12:36
【问题描述】:

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

例如: 标准输入:

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;
}

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

【问题讨论】:

  • “我试过了”——嗯? a[i].word[0] == ' ' - 没有任何意义。
  • 只是“它不起作用”。永远不能作为问题陈述被接受。以什么方式不起作用?您究竟在哪里遇到了问题,您尝试了哪些方法?
  • 对于 C++,您应该使用 std::stringstd::vector。另外,don't use fgets(为什么不是 C++ IO?)
  • 为什么包含 iostream 却没有任何用处?这几乎是您正在编写的 C,而不是 C++。

标签: c++ stdin


【解决方案1】:

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

void readStr()
{
    std::string str;

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

std::getlinestd::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 的形式,它不会检查缓冲区溢出情况

【讨论】:

    【解决方案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
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-08-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-05-09
      相关资源
      最近更新 更多