Getting substring in C++ from a file based on a delimiter

Hello World!

Great to be a part of your community!

This is the data I have saved in a text file:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

    A|City1|Data1|Data2|Data3
    R|01R|Data4|Data5|Data6
    R|02R|Data4|Data5|Data6
    R|03R|Data4|Data5|Data6 
    R|04R|Data4|Data5|Data6
 
    A|City2|Data1|Data2|Data3
    R|01R|Data4|Data5|Data6
    R|02R|Data4|Data5|Data6
    R|03R|Data4|Data5|Data6
    R|04R|Data4|Data5|Data6

    etc.


I am trying to save a substring from the text that would include the whole set of data based on the selection of City, i.e. if I select `City2`, I would get the following string:

1
2
3
4
5
6
7
8
 

    A|City2|Data1|Data2|Data3
    R|01R|Data4|Data5|Data6
    R|02R|Data4|Data5|Data6
    R|03R|Data4|Data5|Data6
    R|04R|Data4|Data5|Data6


This is the code that I have developed so far:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28

    #include <iostream>
    #include <string>
    #include <cstring>
    #include <boost/regex.hpp> // need this for something else
    #include <fstream>
    #include <map>
    
    using namespace std;
    
    main()  
    {
        ifstream ifs("data.txt");
    
        string s;
        char z[]= "City2";
        char delim = 'A|';
    
        while(1)
        {
            getline(ifs, s, delim);
            if (ifs.eof()) break;
            if (s.find(z) != string::npos) {
                cout << s << endl;
            }
        }
    }


The problem is that it only extracts the first substring `City1`. If I change the delimiter to something like `\r\n\r\n`, it only extracts the first line:

1
2
3
4
 

    City2|Data1|Data2|Data3


It does the same if I have no delimiter in the `getline` function.

Thank you so much for your help!

Igor
Line 16, why not use std::string? You included the header for it.
Line 17, a character is a single character...you can't put more characters in a single character like that.

Lines 19-22: the correct way to do this would be to remove lines 21 and 22 and change the while condition to while(getline(ifs, s, delim))

Try making these changes and seeing if it helps. I'm unable test code right now so I can't be of more help :(
L B.
Thank you. I changed it to:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28

#include <iostream>
#include <string>
#include <cstring>
#include <boost/regex.hpp>
#include <fstream>
#include <map>


using namespace std;

main()  {

ifstream ifs("data.txt");

string s;
string z;
z = "City2";
char delim = 'A|';

while(getline(ifs, s, delim))
{
    if (s.find(z) != string::npos) {
        cout << s << endl;
    }
}

}


Still have the same problem. I understand that delimiter is not working. If I put it as a string, the function does not accept it as a parameter. If I have it as a character, I do not get the full set of data. Stuck...

Thanks anyways!
Just a check: the basic format of your input is:
entry

entry

entry

Where entry contains multiple lines and has identifier of a city is on the first line between first and second '|'.

Is that correct?

If so, you could read all of an entry first and later split it into "words".
Last edited on
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
#include <string>
#include <sstream>
#include <iostream>

int main()
{
    // open the stream which contains the city data
    // (this example uses a stringstream instead of a filestream)
    std::istringstream stm( R"(
A|City1|Data.1|Data.2|Data.3
R|01R|Data.4|Data.5|Data.6
R|02R|Data.4|Data.5|Data.6
R|03R|Data.4|Data.5|Data.6
R|04R|Data.4|Data.5|Data.6

A|City2|Data..1|Data..2|Data..3
R|01R|Data..4|Data..5|Data..6
R|02R|Data..4|Data..5|Data..6
R|03R|Data..4|Data..5|Data..6
R|04R|Data..4|Data..5|Data..6

A|City3|Data...1|Data...2|Data...3
R|01R|Data...4|Data...5|Data...6
R|02R|Data...4|Data...5|Data...6
R|03R|Data...4|Data...5|Data...6
R|04R|Data...4|Data...5|Data...6

                          )" ) ;

   // get the city name
   std::string city_name = "City2" ;

   // we need to look a line starting with
   // the city_name prefixed by "A|" and suffixed by '|'
   const std::string search_string = "A|" + city_name + '|' ;

   // read and discard lines from the stream
   // till we get to a line starting with the search_string
   std::string line ;
   while( std::getline( stm, line ) && line.find(search_string) != 0 ) ;

   // check if we have found such a line, if not report an error
   if( line.find(search_string) != 0 )
   {
       std::cerr << "city '" << city_name << " was not found\n" ;
       return 1 ;
   }

   // we need to form a string that would include the whole set of data
   // based on the selection of City
   std::string result = line + '\n' ; // result initially contains the first line

   // now keep reading line by line till we get an empty line or eof
   while( std::getline( stm, line ) && !line.empty() )
      result += line + '\n' ; // append this line to the result

   // use the result (in this example, we just print it out)
   std::cout << "data for '" << city_name << "'\n--------------\n" << result ;
}

http://ideone.com/TcAGNJ
JLBorges. Thank you so much! What I mostly appreciate about your answer are the comments that explain in details the steps and logic behind the code. This is extremely valuable for beginners like me! Much appreciated.

Thank you all for your help.

Igor
Topic archived. No new replies allowed.