Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
195 views
in Technique[技术] by (71.8m points)

c++ - How to read string from stdin until meet blank lines

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


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] = ''; //replaced 
 by 
        i++;
    }
     //length = i;
}
int main()
{
    readStr();
    return 0;
}

So, how to solve this problem?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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] = ''; // 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

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...