1

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;
}
wovano
  • 4,543
  • 5
  • 22
  • 49
Aquarus
  • 23
  • 4

1 Answers1

2

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';
}
A M
  • 14,694
  • 5
  • 19
  • 44
  • This has definitely helped simplify what I must do, so once I finish typing, say I'd like to print the last name of the fullname first and then the first name after, would it be as simple as swapping the order of the cout statement: std:: cout< – Aquarus Oct 07 '22 at 19:51