std::string/vector are on heap; reserve() to avoid re-allocation

These objects use expandable arrays. Has to be allocated on heap.

[[Optimized C++]] P70 confirms that std::string can get re-allocated when it grows beyond current capacity.

http://stackoverflow.com/questions/9521629/stdstringss-capacity-reserve-resize-functions compares std::string.resize() vs reserve().

  • Backgrounder: Capacity — allocated capacity is often uninitialized memory reserved for this string.
  • Backgrounder: size — length of the string that’s fully initialized and accessible. Some of the characters (nulls) could be invisible.
  • string.resize() can increase the string’s size by filling in space (at the end) with dummy characters.
    • After resize(55) the string size is 55. All 55 characters are part of the string proper.
    • changes string’s size() but not capacity
  • string.reserve() doesn’t affect string size. This is a request to increase or shrink the “capacity” of the object. I believe capacity (say 77) is always bigger than the size of 55. The 77 – 55 = 22 extra slots allocated are uninitialized! They only get populated after you push_back or insert to the string.

text parsing with stringstream

 

#include <ctime>
#include <iomanip>
#include <iostream>
#include <sstream>
#include <string>
using namespace std;

string _input =
"1 reverse this line\n"
"2 reverse 2nd line\n"
"3 sort gamma alpha";
istringstream entireInputStreamWithTabs(_input); //pretend to be raw input

/* With fixed column types, this parser is more strict. More professional in an interview.
Also supports DateTime parsing. See https://bintanvictor.wordpress.com/2017/03/16/cpp-parse-datetime-string-without-boost/
*/
void extractionTokenParser(string const & fullLine) {
 istringstream ss1line = istringstream(fullLine);
 int lineNum;
 ss1line >> lineNum;
 cout << "line num = " << lineNum << endl;

 for (string tmp; !ss1line.rdstate();) { // check EOL
   ss1line >> tmp; //whitespace removed:)
   cout << tmp << endl;
 }
}
// --------- simpler alternative ---------
void DelimTokenParser(string const & fullLine) {
 istringstream ss1line = istringstream(fullLine);
 for (string tmp; !ss1line.rdstate();) { // check EOL
   getline(ss1line, tmp, '\t');
   cout << tmp << endl;
 }
}
void parseUsingStringStream() {
 string fullLine;
 //cout << _input << endl;
 for (; !entireInputStreamWithTabs.rdstate();) { // check EOF
   getline(entireInputStreamWithTabs, fullLine);
   //cout << fullLine << endl;
   // you can now search or modify the string
   extractionTokenParser(fullLine);
   DelimTokenParser(fullLine);
 }
}

int main(){
 parseUsingStringStream();
 return 0;
}

cpp parse DateTime using stringstream#no boost

This is the simplest way I have found.

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

//withou Boost, parsing string to DateTime and back
// from http://arsenmk.blogspot.sg/2014/07/converting-string-to-datetime-and-vice.html
int main(){
 stringstream ss{ "1970-01-01 8:00:01" };
 tm simpleStruct; //construct a placeholder on stack
 //parse and output to the placeholder
 ss >> get_time(&simpleStruct, "%Y-%m-%d %H:%M:%S");

 time_t secSinceEpoch = mktime(&simpleStruct);
 if (secSinceEpoch < 0) {
 cout << "parsing failed. (Very strict.) " << secSinceEpoch << endl;
 return -1;
 }
 cout << secSinceEpoch <<" seconds since Epoch (1970/1/1 midnight GMT) is -> ";
 cout << asctime(localtime(&secSinceEpoch));
}

std::string is usable in MSVS but can’t cout without #include {string}

Many STL headers in Visual C++ (including iostream header) pull in a definition of the std::basic_string class (because they indirectly include the implementation-defined <xstring> header (never include that directly)). While that allows you to use the string class, the relevant operator<< is defined in the <string> header itself, so you must include that manually.

combine cheatsheets on cStr+std::string@@

If a coding test requires string operations A1 A2 A3 A4… and B1 B2 B3…, and I know how to do A1 .. on cStr and B1… on std::string, is it practical to rely on 2-way conversion? Will we be able to get the job done?

If possible, then could we save the effort or learning two solutions on every string operation.

It’s more elegant to use only std::string exclusively, but I don’t have the bandwidth…

string,debugging+other tips:[[moving from c to c++]]

[[moving from c to c++]] is fairly practical. Not full of good-on-paper “best practice” advice.

P132 don’t (and why) put “using” in header files
P133 nested struct
P129 varargs suppressing arg checking
P162 a practical custom Stack class non-template
P167 just when we could hit “missing default ctor” error. It’s a bit complicated.

–P102 offers practical tips on c++ debugging

* macro DEBUG flag can be set in #define and also … on the compiler command line
* frequently people (me included) don’t want to recompile a large codebase just to add DEBUG flag. This book shows simple techniques to turn on/off run-time debug flags
* perl dumper receives a variable $abc and dump the value of $abc and also ….. the VARIABLE NAME “abc”. C has a similar feature via the preprocessor stringize operator “#”

— chapter on the standard string class — practical, good for coding IV

* ways to initialize

* substring

* append

* insert

ref-counting string – implementation notes

([[ nitty gritty ]] P202 has simple sample code)

An option exchange interviewer asked me to outline a ref-counting string class “str”.

char* cstr; //field will be null-terminated and allocated on heap.
int counter; // field will be an int allocated on heap.

Now forget about ctor and big 3, and focus on simple, common client operations AFTER instantiation. Now I realize we need to recall how a string variable is USED.

  int length() const;
  char* c_str() const; // STL string offers this conversion method, so do we.
  char* substr(….) const;
  //operator << to print the string
  str operator+() const; // produce a new str object by concatenation. Probably follow the effC++ advice to avoid return-by-reference??

Now the big questions

Q: does copy ctor allocate the cstr or the counter, or share them with sister instances?
%%A: share

Q: does conversion ctor from a C string allocate this->cstr and this->count?
%%A: allocate

Q: how do we create another str variable sharing an existing cstr object?
%%A: copy ctor or assignment
A: cvctor

things to memorize on std::string

(c-string is far more popular and widespread)

An experienced java developer usually memorizes 10 methods of String.java. ditto for stl string. (See the Absolute c++ book.)

c_str()
append(), insert()
assign() Assigns new content to the string replacing its current content.
begin(), rbegin()
end(), rend()
empty()
clear()
…. see http://www.cplusplus.com/reference/string/string/