std::stringstream in C++

I want to extract each word from the sentence, so I did the following.

#include <iostream>
using namespace std;

int main()
{ 
    string line = "I often post some programming contents";
    string word = "";
    
    while (getline(line, word, ' ')) {
        cout << word << endl;    
    }

    return 0;
}

The first argument is not istream or char ** as per the getline syntax.

main.cpp:9:35: error: no matching function for call to getline(std::string&, std::string&, char)
    9 |     while (getline(line, word, ' ')) {
      |                      

I also tried char **, but it didn't work either. 

#include <iostream>
using namespace std;

int main()
{ 
    char **line = "I often post some programming contents";
    string word = "";
    
    while (getline(line, word, ' ')) {
        cout << word << endl;    
    }

    return 0;
}


main.cpp:6:19: error: cannot convert const char* to char** in initialization
    6 |     char **line = "I often post some programming contents";
      |                   ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      |                   |
      |                   const char*
istream& getline(istream& is, 
           string& str, char delim);

The first argument accepts only the istream family which are all ifstream, sstream possibly. Click here to know how getline works in ifstream. 




So, I planned to use stringstream, and it threw me the below error.

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

int main()
{ 
    stringstream line = "I often post some programming contents";
    string word = "";
    
    while (getline(line, word, ' ')) {
        cout << word << endl;    
    }

    return 0;
}
main.cpp:7:25: error: conversion from const char [39] to non-scalar type std::stringstream {aka std::__cxx11::basic_stringstream} requested
    7 |     stringstream line = "I often post some programming contents";
      |                         ^~~~~~~~

So, I initialise it with the proper syntax. 

Method 1 : using getline

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

int main()
{ 
    stringstream line("I often post some programming contents");
    string word = "";
    
    while (getline(line, word, ' ')) {
        cout << word << endl;    
    }

    return 0;
}

Method 2 : using >>

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

int main()
{ 
    stringstream line("I often post some programming contents");
    string word = "";
    
    while (line >> word) {
        cout << word << endl;    
    }

    return 0;
}

Output

I
often
post
some
programming
contents

Find the size of the bytes in string stream

#include <iostream>
#include <sstream>

int main()
{
    std::stringstream oss("Foo hello");
    std::cout << "stringstream: " << oss.str();
    
    oss.seekg(0, std::ios::end);
    int size = oss.tellg();

    std::cout << "\nSize: " << size ;

    return 0;
}
Output:
1
2
stringstream: Foo hello
Size: 9

Click here to debug.

getline with ifstream

#include <iostream>
#include <fstream>

int main()
{
    std::ifstream filein("Hey.txt");
    std::string line;
    while(std::getline(filein, line)) {
       std::cout << "ifstream lines: " << line << std::endl;    
    }
    
    // Go to the beginning of the file again to start over.
    filein.clear();
    filein.seekg(0);


    return 0;
}

Click here to debug.

I think my New Year is more technical than celebrations ;-)

Returning stringstream.str().c_str()

ss.str() implicitly calls the std::string constructor with a char[]. This string gets returned from the function_return_string and the function c_str() returns a pointer to the data from the std::string.

ss.str() returns by value(ie copy of the internal buffer).

As the string returned from the function is not referenced anywhere, it should be deallocated immediately. That was the theory. In other words, life expectancy of temporary object is rather short. Either someone takes a reference of them immediately (e.g. string& s = ss.str() or string& s = function_return_string(init_string)) or they die at the end of the statement where they were born. 

Luckily, the temporary std::string returned from ss.str() survives the puts function call. This means that the const char* pointer returned by c_str() remains valid for the duration of puts().

Remove the comments and try the other lines, you will not be able to get the print. 
At line 'const char* result = function_return_string(init_string).c_str();', the temporary object returned from function will die after executing this line. The pointer will indeed valid at the time c_str() gets it in this line. 
#include <string>
#include <iostream>
#include <sstream>
using namespace std;

std::string function_return_string(const std::string& init)
{
      std::stringstream ss;
      ss << init << " Now explore more with me!!";
      return ss.str();
}

int main(){
    string init_string = "Welcome to My blog.";  
    puts(function_return_string(init_string).c_str());
    //const char* result = function_return_string(init_string).c_str(); 
    //puts(result);
    //cout << "This is a stringstream object\n" << result << endl; 
  
    return 0;

}
Output:
1
Welcome to My blog. Now explore more with me!!

Click here for godbolt link


Reference

Size of stringstream

clear to go to the beginning of file in fstream

Other SO links

Comments