2

std::wistringstream is a great way to easily parse lines from files.

However, there is one use case that it doesn't seem to be able to handle :

When parsing a std::wstring, it will consider any space in the string as the end of said string.

For example, if my file contains these lines :

This_is_a_test 42

Bad string name 747

If I attempt to parse a string and number, first one will succeed but the second one will fail.

If I change the file content with the following :

"This_is_a_test" 42

"Bad string name" 747

The parsing of the second string will still fail despite the ". Is there a trick to make the std::wistringstream ignore spaces within the string ? Something similar in principle to the ".

Is it a use case that this parsing method cannot handle ?

Code sample to try and parse the file :

#include "stdafx.h"
#include <string>
#include <iostream>
#include <fstream>
#include <sstream>

int main(int argc, wchar_t* argv[])
{
  // Open file
  std::wifstream file("D:\\file.txt", std::fstream::in);

  std::wstring str;
  double number;

  std::wstring line;

  // For each line
  while (getline(file, line))
  {
    std::wistringstream iss(line);

    // We parse the line
    if (!(iss >> str >> number))
      std::wcout << L"The line " << line << L" is NOT properly formatted" << std::endl;
    else
      std::wcout << L"The line " << line << L" is properly formatted" << std::endl;
  }

  return 0;
}

Output with the examples presented :

The line This_is_a_test 42 is properly formatted

The line Bad string name 747 is NOT properly formatted

and

The line "This_is_a_test" 42 is properly formatted

The line "Bad string name" 747 is NOT properly formatted

Norgannon
  • 487
  • 4
  • 16
  • And then, how would you want to prevent `this is a test 42` to be read as `"this is a test 42"`? – Aconcagua Jan 31 '19 at 09:46
  • It wouldn't because there would be a closing `"` at the end of the string. (just like in my example `"this is a test" 42`. – Norgannon Jan 31 '19 at 09:46
  • Well, referred to the non-quotes idea - quotes would be fine, but are not supported. Python: 'hello"world' is a string literal equivalent to C++ "hello\"world", or consider XML-Tags. Problem is that there are too many ways one could do it (special separator characters included, compare to CSV), it would not be appropriate for a general purpose library to tie down to one specific solution... – Aconcagua Jan 31 '19 at 09:49
  • Sometimes when you have particular requirements you just have to write the code yourself instead of expecting standard libraries to have written it for you. – john Jan 31 '19 at 09:56
  • Well it does seem like a pretty common use case and the standard libraries does handle it according to @Jarod42 's answer since C++14. – Norgannon Jan 31 '19 at 09:58

1 Answers1

3

You might do, with std::quoted, since C++14:

iss >> std::quoted(str);

Demo

Jarod42
  • 203,559
  • 14
  • 181
  • 302
  • That is exactly what I was looking for ! Sadly can't use C++14 right now but I'll definitly use this solution when I can :D – Norgannon Jan 31 '19 at 10:07
  • 1
    You might look at [c11-equivalent-to-stdquoted-introduced-in-c14](https://stackoverflow.com/questions/45266325/c11-equivalent-to-stdquoted-introduced-in-c14) which give links of actual implementations. – Jarod42 Jan 31 '19 at 10:10
  • Thanks I'll look into it ! – Norgannon Jan 31 '19 at 10:12