How to read string from stdin until meet blank lines

岁酱吖の 提交于 2019-12-25 18:29:19

问题


Consider a simple program. It must take string from stdin and save to variable. It is not stated how many lines of input will be taken, but program must terminate if meet newline.

For example: stdin:

abc
abs
aksn
sjja
\n

I tried but it doesn't work. Here is my code:

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

So, how to solve this problem?


回答1:


One alternative here is to use std::getline to get each line. If the line is empty, or the input fails, then exit the loop.

void readStr()
{
    std::string str;

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

Adding the std::getline and use of std::vector to your sample code, and keeping with the spirit of your original sample;

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

To solve you immediate problem, minimal changes in the code can be made as follows;

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

If the standard input will always be used (stdin), the gets function can also be used;

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

Notes;

  • fgets reads until the "enter" key on the stdin but includes the new line character
  • gets also reads until the return, but excludes the new line character
  • Both functions NULL terminate the input
  • Be careful of the form of gets it does not check for buffer overflow conditions



回答2:


I would do something like this:

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


来源:https://stackoverflow.com/questions/25871127/how-to-read-string-from-stdin-until-meet-blank-lines

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!