Searching txt files

Started by
12 comments, last by rAm_y_ 9 years, 10 months ago

I'm currently learning fstream and I am trying to search a txt file I created for certain strings.

Once I find a string I want to start copying the strings directly under them until I find another string to begin the copying directly under them. Except for my first string I want to copy after the "=" sign then stop after a new line.

For example the txt will look something like this:

R = 1-1

cbl

12

14

16

18

R = 2-1

cbl

11

13

15

17

where R equals the remote number. Cbl means the cables and under "cbl" is the cable numbers (none are going to be integers all are strings).

But I want the out put to be in the format

1-1 12

1-1 14

1-1 16

1-1 18

2-1 11

2-1 13

2-1 15

2-1 17

The reason I am creating this searching and outputting program because once it is in my final format, I plan on inputting them into excel to be placed into a database.

I can open the file but I have no idea how to search word for word and then tell the program to copy next to key words then continue until another keyword.

Help?

Advertisement

The ifstream object provides an interface for reading input from a file. It doesn't provide any searching or otherwise "semantic" uses of the file, all of that is up to the programmer to do on his/her own.

What you'll want to do is use the getline function of your ifstream object to read one line at a time. Then you can determine if that line matches the "R = x-x" type of line, and if so you can use getline to get the subsequent lines, which you will then copy into your output.

How will you detect that a line matches the "R = x-x" format? That's up to you, there are a lot of ways you could do it. To me, it looks like the simplest solution is to merely check that the first character is 'R' since it appears no other lines have R as the first character. Therefore that is an identifying property of the remote lines. This approach isn't very safe, and doesn't check for malformed lines, but the amount of safety you think you require is up to you. You can certainly do a more rigorous examination of each line, if that's something you need.

Thanks for the help, I will research the getline() function. That will most definitly help gathering information for each line.

But is there a way to tell the program to begin after "=" or after finding the desired keyword? Like how to make the program to begin inputting strings after a desired keyword or the next line?

Take a look at some of the functions available for std::string, such as:


std::string myString = "";
while( std::string::npos == myString.find("=",0)  ) { ... [load myString with the next input text line, checking for end-of-file]... }
// myString contains "="
// or, for some keyword..
while( std::string::npos == myString.find("keyword",0) { .. [load myString, looping until the keyword is found] ...}
//.. continue as desired

The find() function for std::string returns the position where the quoted string occurs. If the quoted string is not found, the function returns std::string::npos (no position). There are also variations such as find_first_of("=", 0), and find_last_of("=",0) if there are multiple occurrences of some string or token. The 0 (zero) argument is just the start position within the string to start the search.

Be sure to check for end-of-file when you're searching through a file.

EDIT: you can also input directly to a std::string. E.g.,


file >> myString; // NOTE: a complete line may or may not be input, depending on whitespace.
// The input will end when whitespace is encountered, including std::string::endl (endline)
// BUT.. the string will NOT contain any whitespace - spaces, tabs, endlines..
// for instance, for the line: R<space>=<space>1-1
file >> myString; // "R" (without the quotation marks)
file >> myString; // "="
file >> myString; // "1-1"

// for the line: R=<space>1-1
file >> myString; // "R="
file >> myString; // "1-1"

Please don't PM me with questions. Post them in the forums for everyone's benefit, and I can embarrass myself publicly.

You don't forget how to play when you grow old; you grow old when you forget how to play.

That's just your typical string manipulation stuff. What you get back from getline is a string. A c-string to be exact. There are number of functions for dealing with c-strings (strstr, strchr, strcmp, etc, you can look them up). If you would like you could construct a std::string from the c-string that you get back from getline. You can look up std::string, as well. There are quite a few member functions of std::strings that will be useful to you.

But regardless: what you get back from getline is a string. You have to parse the string yourself, however you choose. You check if the string matches a certain format, if it does, then you grab some substrings of that string and copy them into the output. How you determine what substrings are important is up to you. If you want everything after the first '=' sign then you could use strchr to find the first '=' and go from there, or you could use the 'find' member function of std::string to find the '=' sign, and then only look at the substring that immediately follows the '=' sign. If you know the '=' sign is always the third character of the string, then you could simply use the substring starting at the 4th character. Whatever you want.

EDIT: ninja'd by Buckeye laugh.png

Oh thanks a bunch guys. I will research and try my best to create.

If you're going to do some research, try looking up string parsing and tokenizing.


and under "cbl" is the cable numbers (none are going to be integers all are strings).

Clarify this statement. You say none are going to be integers, yet your example text contains only integers. When it comes to string parsing, the details are essential.

You could use fscanf i beleive, something like this:

(Untested)


char c;
int x, y, z;

char szString[256];
ZeroMemory(szString, 256);

FILE *f = fopen("YourFileName.txt", "rt");
if(!f)
    return;

// add error checking later...
fscanf(f, "%c = %d-%d\n", c, x, y);
fnscanf(f, 256, "%s\n", szString);
fscanf(f, "%d-%d %d\n", x, y, z);
fscanf(f, "%d-%d %d\n", x, y, z);
fscanf(f, "%d-%d %d\n", x, y, z);
fscanf(f, "%d-%d %d\n", x, y, z);
fscanf(f, "\n");

fclose(f);

http://www.cplusplus.com/reference/cstdio/fscanf/

You'd want to read each line into a string and use sscanf (convert to char* with c_str()) instead, since fscanf advances the file read pointer as it goes along, whereas sscanf does not.

I prefer the scanf family of functions for this kind of parsing too.

"Most people think, great God will come from the sky, take away everything, and make everybody feel high" - Bob Marley

This topic is closed to new replies.

Advertisement