Using stringstream in C++

"How to correctly use stringstream in Leetcode with examples"

Posted by Haoyang on June 18, 2019

getline (string)

  1. getline(istream& is, string& str, char delim);
  2. getline(istream& is, string& str);

Explanations

Extracts characters from is and stores them into str until the delimitation character delim is found (or the newline character, ‘\n’, for (2)).

The extraction also stops if the end of file is reached in is or if some other error occurs during the input operation.

If the delimiter is found, it is extracted and discarded (i.e. it is not stored and the next input operation will begin after it).

Note that any content in str before the call is replaced by the newly extracted sequence.

Each extracted character is appended to the string as if its member push_back was called.

Example

// extract to string
#include <iostream>
#include <string>

int main ()
{
  std::string name;

  std::cout << "Please, enter your full name: ";
  std::getline (std::cin, name);
  std::cout << "Hello, " << name << "!\n";

  return 0;
}

leetcode 151 Reverse Words in a String

Given an input string, reverse the string word by word.

For example, Given s = “the sky is blue”, return “blue is sky the”.

class Solution {
public:
    void reverseWords(string &s) {
        istringstream is(s);
        s = "";
        string t = "";
        while (getline(is, t, ' ')) {
            // if string is ' ' then t will be ''
            std::cout << "t: " << t << " -<" << std::endl;
            if (t.empty()) continue; // this mean we meet blank space
            s = (s.empty() ? t : (t + " " + s)); // pre-append t to s and override s
        }
    }
};

If s = 'a good example', then the output will be

t: a -<
t: good -<
t:  -< // here because there are two blank spaces after good, and our delimater
is ' ', so the next char is ' '
t:  -< // same here
t: example -<

leetcode 449. Serialize and Deserialize BST

Serialization is the process of converting a data structure or object into a sequence of bits so that it can be stored in a file or memory buffer, or transmitted across a network connection link to be reconstructed later in the same or another computer environment.

Design an algorithm to serialize and deserialize a binary search tree. There is no restriction on how your serialization/deserialization algorithm should work. You just need to ensure that a binary search tree can be serialized to a string and this string can be deserialized to the original tree structure.

The encoded string should be as compact as possible.

Note: Do not use class member/global/static variables to store states. Your serialize and deserialize algorithms should be stateless.

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Codec {
public:

    // Encodes a tree to a single string.
    string serialize(TreeNode* root) {
        ostringstream os;
        serialize(root, os);
        return os.str(); // convert ostringstream to string
    }

    // Decodes your encoded data to tree.
    TreeNode* deserialize(string data) {
        istringstream is(data);
        return deserialize(is);
    }

private:
    void serialize(TreeNode* root, ostringstream& os) {
        if (!root) {
            os << "# "; // append string to stream
        } else {
            os << root -> val << " "; // use for delimating
            serialize(root -> left, os);
            serialize(root -> right, os);
        }
    }

    TreeNode* deserialize(istringstream& is) {
        string val = "";
        is >> val; // this will keep all " " away
        if (val == "#") {
            return NULL;
        } else {
            TreeNode* root = new TreeNode(stoi(val));
            root -> left = deserialize(is);
            root -> right = deserialize(is);
            return root;
        }
    }
};

// Your Codec object will be instantiated and called as such:
// Codec codec;
// codec.deserialize(codec.serialize(root));

Difference between getline and »

The difference is thatstd::getline — as the name suggests — reads a line from the given input stream (which could be, well, std::cin) and operator» reads a word1.

That is, std::getline reads till a newline is found and operator» reads till a space (as defined by std::isspace) and is found. Both remove their respective delimiter from the stream but don’t put it in the output buffer.

Note that » can also read numbers — int, short, float, char, etc.