Home > database >  How to accept an unknown number of lines in c , each line has two strings
How to accept an unknown number of lines in c , each line has two strings

Time:01-08

How do I accept an unknown number of lines in c ? Each line has two strings in it separated by a space. I tried the solutions mentioned in This cplusplus forum, but none of the solutions worked for me. One of the solutions works only when Enter is pressed at the end of each line. I am not sure if the \n char will be given at the end of my input lines. What are my options?

My current attempt requires me to press Ctrl Z to end the lines.

#include <iostream>
#include <fstream>
#include <sstream>
#include <vector> 
using namespace std;

int main(){
    string line; 
    while(cin>>line and cin.eof()==false){
        cout<<line<<'\n';
    }
    return 0;
}

I would like to take an unknown number of strings as shown below:

cool toolbox
aaa bb
aabaa babbaab

Please don't flag this as a duplicate, I really tried all I could find! I tried the following solution on the above given link by m4ster r0shi (2201), but it did not work for me.

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

using namespace std;

int main()
{
    vector<string> words;

    string word;
    string line;

    // get the whole line ...
    getline(cin, line);

    // ... then use it to create
    // a istringstream object ...
    istringstream buffer(line);

    // ... and then use that istringstream
    // object the way you would use cin
    while (buffer >> word) words.push_back(word);

    cout << "\nyour words are:\n\n";

    for (unsigned i = 0; i < words.size();   i)
        cout << words[i] << endl;
}

And this other solution also did not work: other soln, and I tried this SO post too: Answers to similar ques. This one worked for my example, but when I pass only one line of input, it freezes.

// doesn't work for single line input 
#include <iostream>
#include <fstream>
#include <sstream>
#include <vector> 
using namespace std;

int main(){
    string line ="-1"; 
    vector<string>data;
    while(1){
        cin>>line;
        if(line.compare("-1")==0) break;
        data.push_back(line);
        line = "-1";
    }
    for(int i =0;i<data.size();i =2){
        cout<<data[i]<<' '<<data[i 1]<<'\n';
    }
    return 0;
}

CodePudding user response:

If each line has two words separated by whitespace, then perhaps you should have a Line struct which contains two std::strings and overloads the >> operator for std::istream.

Then you can just copy from std::cin into the vector.

#include <iostream>
#include <vector>
#include <algorithm>
#include <iterator>

struct Line {
    std::string first;
    std::string second;
};

std::istream& operator>>(std::istream& i, Line& line) {
    return i >> line.first >> line.second;
}

int main() {
    std::vector<Line> lines;

    std::copy(
      std::istream_iterator<Line>(std::cin),
      std::istream_iterator<Line>(),
      std::back_inserter(lines)
    );

    for (auto &[f, s] : lines) {
        std::cout << f << ", " << s << std::endl;
    }

    return 0;
}

A test run:

% ./a.out                
jkdgh kfk
dfgk 56
jkdgh, kfk
dfgk, 56
  • Related