Is it possible to use istringstream to read in more than one parameter of a stream function?

137 views Asked by At

Instead of writing a new istringstream argument, can I add another parameter inside nameStream? I have what I think below, and if this method is elligible, then can I tell the input stream to read in a space or endline to separate the two fullnames?

#include <iostream>
#include <string>

using namespace std;

string lastNameFirst (string fullname){
    fullname = "Don Blaheta";
    fullname2 = "Julian Dymacek";
    istringstream nameStream(fullname, fullname2);

    string firstName;
    string lastName;
    string firstName2;
    string lastName2;
    nameStream>>firstName>>lastName>>firstName2>>lastName2;

    return 0;
}
1

There are 1 answers

1
A M On BEST ANSWER

No, that will not work.

As you can see in the definition of std::istringstreams constructor, it will not take 2 std::strings as parameter. So, you cannot do in this way.

You have to concatenate the 2 strings before and then handover to the constructor.

Please see below some example for illustrating what I was explaining:

#include <iostream>
#include <string>
#include <sstream>
using namespace std::string_literals;

int main() {
    // Define source strings
    std::string fullname1{ "Don Blaheta"s };
    std::string fullname2{ "Julian Dymacek"s };

    // here we will store the result
    std::string firstName1{}, lastName1{}, firstName2{}, lastName2{};

    // Create stream from concatenated strings
    std::istringstream nameStream(fullname1 + " "s + fullname2);

    // Extract the name parts
    nameStream >> firstName1 >> lastName1 >> firstName2 >> lastName2;

    // Show some debug output
    std::cout << firstName1 << ' ' << lastName1 << '\n' << firstName2 << ' ' << lastName2 << ' ';
}

In more advanced C++ (starting with C++17) you could use variadic template parameters and fold expresssions to concatenate an arbitary number of names, and then split the parts into a std::vector. Here we can make use of the std::vectors range constructor(5) in combination with the std::istream_iterators constructor.

But here you need to learn more . . .

#include <iostream>
#include <string>
#include <sstream>
#include <vector>
#include <iterator>
#include <algorithm>
using namespace std::string_literals;

template<typename... Strings>
std::vector<std::string> split(Strings&& ...strings) {
    std::istringstream iss(((strings + " "s) + ...));
    return { std::istream_iterator<std::string>(iss),{} };
}

int main() {
    // Any number of names
    std::string fullname1{ "Don Blaheta"s };
    std::string fullname2{ "Julian Dymacek"s };
    std::string fullname3{ "John Doe"s };

    // Split all the names into parts
    std::vector nameParts = split(fullname1, fullname2, fullname3);

    // Show debug output
    for (const std::string& s : nameParts) std::cout << s << '\n';
}