-2

Suppose I'm having-

string s="Hello Hi Hey\n""Bye Bye good night";

Now,I want to get the string within "\n" ,i.e I want to get "Hello Hi Hey"

How can i do so? I've thinking of stringstream, but it's not possible as "Hello Hi Hey" itself contains space.

πάντα ῥεῖ
  • 1
  • 13
  • 116
  • 190
  • 1
    Hint: Use `std::getline()` with `std::istringstream`. – πάντα ῥεῖ Jul 16 '22 at 13:54
  • @πάνταῥεῖ How is that possible? How would I store Hello Hi Hey in a steam? – PHANTOM DRAGON Jul 16 '22 at 13:55
  • 1
    `string s2(s.begin(), std::find(s.begin(), s.end(), '\n'));`? – fabian Jul 16 '22 at 13:55
  • @fabian Sorry,I don't know STL – PHANTOM DRAGON Jul 16 '22 at 13:56
  • 1
    https://en.cppreference.com/w/cpp/io/basic_stringstream/basic_stringstream should help – rohitt Jul 16 '22 at 13:57
  • @PHANTOMDRAGON `string s="Hello Hi Hey\n""Bye Bye good night"; string hellohihey; std::istringstream iss(s); std::getline(iss,hellohihey);` – πάντα ῥεῖ Jul 16 '22 at 14:00
  • @PHANTOMDRAGON `std::find` is part of the same standard library as `std::string`. It's not to hard to understand, if you know about how iterators work. Basically `std::find(s.begin(), s.end(), '\n')` finds the string iterator position pointing to the first occurance of `'\n'` returning the past the end iterator, if the char isn't found. The constructor `std::string s2(iterator1, iterator2);` creates a string copying the content starting at `iterator1` and ending just before `iterator2`. – fabian Jul 16 '22 at 14:05
  • @πάνταῥεῖ It's actually working, Thanks, I'm wandering if it's possible to get string at new line ,i.e Bye Bye Good night – PHANTOM DRAGON Jul 16 '22 at 14:07
  • @PHANTOMDRAGON I.e. use another `getline()` with the same stream. – πάντα ῥεῖ Jul 16 '22 at 14:11
  • You can use `std::getline` twice or going with my logic (without handling the case where there is no newline char: `auto const newLinePos = std::find(s.begin(), s.end(), '\n'); std::string part1(s.begin(), newLinePos); std::string part2(newLinePos + 1, s.end());` – fabian Jul 16 '22 at 14:11
  • Btw: [`std::string::find`](https://en.cppreference.com/w/cpp/string/basic_string/find) and [`std::string::substr`](https://en.cppreference.com/w/cpp/string/basic_string/substr) are also options, but personally I prefer the ones using iterators. – fabian Jul 16 '22 at 14:14
  • @fabian Actually,I gotta study about STL soon. – PHANTOM DRAGON Jul 16 '22 at 14:16
  • Btw: Note that it may be better not to refer to the standard library as "STL", see https://stackoverflow.com/questions/5205491/whats-the-difference-between-stl-and-c-standard-library – fabian Jul 16 '22 at 14:21
  • @PHANTOMDRAGON The STL is an old and outdated predecessor of the C++ standard library. I would not bother studying STL; learn the standard library instead. ;) (As I recall, STL has no algorithms, such as `std::find()`. But it has been a while.) – JaMiT Jul 16 '22 at 14:22
  • @PHANTOMDRAGON it's all well documented publicly: https://en.cppreference.com/ – πάντα ῥεῖ Jul 16 '22 at 14:31
  • STL was originally written in Ada. Later ported to C++. About a third of STL made it into ISO/IEC 14882:1998 standard C++. @JaMIT • Stepanov's STL does have algorithms, some of them made it into C++98. – Eljay Jul 16 '22 at 14:56
  • Are standard library and standard template library diff? Isn't stuffs like vectors etc considered as STL? – PHANTOM DRAGON Jul 16 '22 at 16:51
  • @PHANTOMDRAGON it's just an issue about precise terminology, nothing actually important. – πάντα ῥεῖ Jul 16 '22 at 17:12
  • A subset of the STL constitutes subset of the standard library. `` and `` for example are not in the STL subset. – Clifford Jul 16 '22 at 17:29
  • @PHANTOMDRAGON Vectors exist in both STL and the C++ standard library, yes. As for "etc" -- well, STL has `hash_set` while the standard library has `unordered_set`. Both serve the same purpose, but you'll run into trouble if you try to use `std::hash_set`. If you study the STL, you'll run into several issues like this, and you'll miss out on some of what the standard library has to offer. Studying STL is sort of like studying Middle English -- it's still English, but it's not exactly modern English. There are enough differences to confound a compiler. So make sure you study the right subject. – JaMiT Jul 19 '22 at 02:10

2 Answers2

2

Now,I want to get the string within "\n" ,i.e I want to get "Hello Hi Hey"

How can i do so? I've thinking of stringstream, but it's not possible as "Hello Hi Hey" itself contains space.

Just instantiate a std::istringstream and use std::getline() to read the separate lines into strings:


string hellohihey;
string byebyegoodnight;
std::istringstream iss(s);
std::getline(iss,hellohihey);
std::getline(iss,byebyegoodnight);

Also note that the literal doesn't need separate double quotes:

string s="Hello Hi Hey\nBye Bye good night";

Or even use a raw string literal to get some kind of WYSIWYG feeling:

string s=R"(Hello Hi Hey
Bye Bye good night)";

πάντα ῥεῖ
  • 1
  • 13
  • 116
  • 190
  • Thanks, BTW, I'm still confused that how did getline read "Hello Hi Hey" from s getline should be taken till whitespace; Hello ,Is that something that getline function will only read line till "\n"? – PHANTOM DRAGON Jul 16 '22 at 16:50
  • No, you're confusing that with the `>>` operator may be, which separates data reads by whitespace. – πάντα ῥεῖ Jul 16 '22 at 17:01
  • So, By getline function, We could read input within a line(not space) from a stream having more than one line? – PHANTOM DRAGON Jul 16 '22 at 17:09
  • I have no idea what you're asking about? – πάντα ῥεῖ Jul 16 '22 at 17:11
  • @PHANTOMDRAGON : The clue is in the name - `getline` it does what it says and operates on a stream. Yes you can get more than one line because a _stream_ has state and "knows" where it is in the stream - it maintains an index. `istringstream` is an `istream` subclass (like `ifstream`) so exhibits all the behaviour of an input stream. See the diagram at https://cplusplus.com/reference/iolibrary/ how they relate. See how `cin` is a `istream` _object_, so has all the same behaviour also. – Clifford Jul 16 '22 at 17:33
  • Clifford and πάνταῥεῖ Thank you very much,Have learned something new from you :) – PHANTOM DRAGON Jul 16 '22 at 18:42
0

Clearly the std::istringstream / std::getline() solution is simpler in most cases, but it is possible to extract the lines using std::string alone. For example:

string s = "Line 1\nLine 2\nLine 3\n" ;

size_t beg = 0 ;
size_t end = 0 ;

// While lines remain to be processed...
while( end != string::npos && beg < s.length() )
{
    // Find end of line
    end = s.find( '\n', beg ) ;

    // Extract line excluding newline
    string single_line = s.substr( beg, end - beg ) ;

    // Show extraction and the start & end positions.
    cout << beg << " to " << end - 1 << " = \"" << single_line << "\"\n" ;

    // Set beginning of next line, skipping newline from previous
    beg = end + 1 ;
}

Outputs:

0 to 5 = "Line 1"
7 to 12 = "Line 2"
14 to 19 = "Line 3"

For the simple case described in you question, the solution is simply:

string first_line = s.substr( 0, s.find( '\n' ) ) ;

Which will result in first_line == "Hello Hi Hey". So for simple cases it may not be necessary to instantiate a std::istringstream object.

Clifford
  • 88,407
  • 13
  • 85
  • 165