Home > Software engineering >  Is there a way to turn input string to input stream in c ?
Is there a way to turn input string to input stream in c ?

Time:05-08

What I want to do is get user input from the terminal and use this input in other functions in my program. Since my functions only take input streams as arguments I want to convert the input string into an input stream.

int main(int argc, char** argv)
{

    std::vector<std::string> args(argv, argv   argc);
    
    if(args.size() == 1){ //if no arguments are passed in the console
        std::string from_console;
        std::istringstream is;
        std::vector<std::string> input;
        while(!getline(std::cin,from_console).eof()){
            input.emplace_back(from_console);
        }
        for(std::string str : input){
            std::cout << "\n" << str;
        }
}

Another questions that arose when I was trying this code, was that when I ended the console input with a bunch of characters and not with a new line(pressing enter then ctrl d) the line was ignored and didn't get printed out. Example: When I typed the following:

aaa bbb
ccc ctrl d

I got only the first line(aaa bbb) and not ccc printed out. But:

aaa bbb
ccc
ctrl d 

prints out ccc as well, but it does ignore the new line. So why is this happening?

CodePudding user response:

Is there a way to turn input string to input stream in c ?

Yes, it is possible. This is what std::istringstream is for. Example:

std::string input = some_input;
std::istringstream istream(input); // this is an input stream

CodePudding user response:

The std::istringstream class has a constructor that takes a std::string as an argument, which uses a copy of the string passed as the initial content of the stream.

So, rather than use a std::vector to store all your input lines from the console, just keep adding those to a single (different) std::string object, remembering to add the newlines after each, then construct your std::istringstream from that.

Here is a trivial example that shows how you can use std::getline (which, like your functions, takes an input stream as its first argument) equally well on std::cin and a std::istringstream object created like that:

#include <iostream>
#include <sstream>

int main()
{
    std::string buffer; // Create an empty buffer to start with
    std::string input;
    // Fill buffer with input ...
    do {
        getline(std::cin, input);
        buffer  = input;
        buffer  = '\n';
    } while (!input.empty()); // ... until we enter a blank line

    // Create stringstream from buffer ...
    std::istringstream iss{ buffer };

    // Feed input back:
    do {
        getline(iss, input);
        std::cout << input << "\n";
    } while (!input.empty());

    return 0;
}

CodePudding user response:

When the eof is in the same line as the last line of content, getline(std::cin,from_console) will reach it and .eof() will return true, thus the last line is read into string from_console but not push into the vector.

There are two ways:

  1. Modify your code by pushing the last line into the vector manually:
while(!getline(std::cin,from_console).eof()){
    input.emplace_back(from_console);
}
input.emplace_back(from_console);  // add one line
for(std::string str : input){
  1. iterator can be an elegant way:
#include <iterator>
// ...
if (args.size() == 1) {  // if no arguments are passed in the console
    copy(std::istream_iterator<std::string>(std::cin), {}, 
         std::ostream_iterator<std::string>(std::cout, "\n"));
}
  • Related