Identify open quotes in a delimited file

Please read \n as return character in the example record.
Example record: "info, "info", "info\n and more info"

I'm reading a file like this:

1
2
3
4
5
6
7
8
for(std::string str; std::getline(ifh,str);) {

 //If the string ends with and open double quote I need to get the next line
 //and append it to the end of the previous string.

 //What I want to do is replace the return character with a literal \n

}


How do I identify a non-closed double quote?
So I can grab the next record appended it to the first record.
Figured it out. Thanks for reading.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
for(std::string str; std::getline(ifh,str);) { 

        AGAIN:
        size_t n = std::count(str.begin(), str.end(), '"'); //ensuring all double quotes are closed
        if ( (n % 2)) { 
                //If they're not closed I'm grabing the the next record and replacing
                //the return character with a literal \n.
                std::string next_line;
                std::getline(ifh,next_line);
                str += R"(\n)";
                str += next_line;
                goto AGAIN;
        }
}


edit: Had to add a goto statement to make it check for multiple return characters
Last edited on
Had to add a goto statement to make it check for multiple return characters


It can be done without using goto. Perhaps (not tried):

1
2
3
4
5
6
7
8
9
for (std::string str; std::getline(ifh, str);)
	for (size_t n{}; (n = std::count(str.begin(), str.end(), '"') % 2; ) { //ensuring all double quotes are closed
		//If they're not closed I'm grabing the the next record and replacing
		//the return character with a literal \n.
		std::string next_line;

		std::getline(ifh, next_line);
		str += R"(\n)" + next_line;
	}

No, it didn't occur to me to remove the goto that way. Thanks for the advice.
Using goto should be the absolute last resort for a loop.

seeplus showed an excellent form of a loop using 2 for loops. The conditions for incrementing and loop termination are contained within the for loop statements.

There are several different ways to do a loop depending on what you want to do:

1. for loop

2. while loop

3. do/while loop

If you want an endless loop, the closest variant for a goto loop, that you then break out when you reached specified conditions you could use a while(true) loop:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include <iostream>

int main()
{
   // initialize a counting variable
   int counter { };

   // this is an unending loop
   while (true)
   {
      std::cout << counter << ' ';

      ++counter;

      // test condition for breaking out of the loop
      if (counter >= 10)
      {
         break;
      }
   }

   std::cout << '\n';
}

0 1 2 3 4 5 6 7 8 9

for loops are really versatile with containers like a std::string. You can use the most common form of a for loop:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include <iostream>
#include <string>

int main()
{
   std::string hello_str { "Hello World!" };

   for (unsigned i { }; i < hello_str.size(); ++i)
   {
      std::cout << hello_str[i] << ' ';
   }

   std::cout << '\n';
}

Or use iterators on the container:
8
9
10
11
12
13
   // https://en.cppreference.com/w/cpp/string/basic_string/begin
   // https://en.cppreference.com/w/cpp/string/basic_string/end
   for (auto itr { hello_str.cbegin() }; itr != hello_str.cend(); ++itr)
   {
      std::cout << *itr << ' ';
   }

C++11 added the range-based for loop:
8
9
10
11
12
   // https://en.cppreference.com/w/cpp/language/range-for
   for (const auto& itr : hello_str)
   {
      std::cout << itr << ' ';
   }


Just an historical note. The 'old' way to get an infinite loop was often to use for (;;) - you still see it in old C code today - with newbies scratching their heads!
Topic archived. No new replies allowed.