Search code examples
csvc++11c++14stdstring

How to hard code or declare the content of a file in std::string


I have the following content in a CSV file

Column1, Column2, Column3, Column4, Column5 
something, false, somemore, 1.010000, 1.020000

Above CSV file content is returned as std::string from a method of my library.

std::string GetCsvContent() {
    // Create csv content
    return csv_content;
}

Now I want to unit test GetCsvContent. I know what it will return for a certain input. But to be able to test I need to predeclare the CSV content in a std::string. Something like below.

std::string expected_csv_content = "Column1, Column2, Column3, Column4, Column5\nsomething, false, somemore, 1.010000, 1.020000";
EXPECT_EQ(expected_csv_content, my_library_object.GetCsvContent());

But above way of declaring expected_csv_content is not correct because it is not exactly matching the format of following data.

Column1, Column2, Column3, Column4, Column5 
something, false, somemore, 1.010000, 1.020000

Is there a way to declare in R notation like below?

const std::string expected_csv_content = R"(
    Column1, Column2, Column3, Column4, Column5
    something, false, somemore, 1.010000, 1.020000
)";

Question:
My question is how to I hard code or declare the content of a CSV or any small file in a std::string for comparison if I want to?


Solution

  • You can use raw string literals, but the problem is that those line indents are also part of the string, and so are the newlines you added at the beginning and end. Another problem with using raw strings is the newlines themselves -- if you end up using a text editor that puts OS-specific newlines into your code (e.g.CRLF), you might end up with failing tests and have a really hard time working out why.

    I suspect the non-matching issue in the first place was because your CSV outputs a newline after every line, but in your (non-raw) test string you did not put a newline at the end.

    If you want a nicer layout in your code, then you can concatenate ordinary string literals as follows:

    const std::string expected_csv_content =
        "Column1, Column2, Column3, Column4, Column5\n"
        "something, false, somemore, 1.010000, 1.020000\n";
    

    With the above, it's easy to see the data, you can easily copy/paste lines if you're wanting to add stuff to the test, and you get a good visual on the newline characters. And if you want to copy many lines of text in for other tests, you can easily convert between the string form and raw text using a simple regular expression search/replace.