Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Chris Miller on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

File Position Pointer

Status
Not open for further replies.

shilpashetty27

Technical User
Apr 12, 2007
32
CA
Hi all,

A little background on what I'm trying to do.

I've created a file with 5 lines, 3 numbers on each line. I intend to read only the second number of every line and then jump to the newline.

For eg: Line 1: 1 2 3
Line 2: 4 5 6
Line 3: 7 8 9
Line 4: 1 2 3
Line 5: 4 5 6



I've been able to read the second number of only the first line quite successfully but what I'm stuck on is getting to the newline.


I've seen fgetpos, fsetpos etc but none of them seem to do what I want.

Any help is appreciated.

Thanks in advance!
cheers,
Shilpa
 
I prefer to get every line in a file via a stream, then pull out the value(s) I want. I've never had much luck with file position. If you are interest and no one else has a better idea, let me know here.


James P. Cottingham
-----------------------------------------
[sup]I'm number 1,229!
I'm number 1,229![/sup]
 
Hi,

Thanks for your reply.


Yes, I'm definitely interested. Better ideas are always welcome.

It would be great if you had some tips on how i can do this using streams.

Thanks again!
Shilpa
 
First off, you will need to add #include <fstream> and #include <sstream> to your header file. fstream is the library for the file stream functions while sstream is the library for the string stream functions. If you don't use the string functions you can drop the sstream header.

Let's break this up into units. First, you need to go open the file and go through each line in the file. You say your file looks like this:
Code:
1 2 3
4 5 6
7 8 9
1 2 3
4 5 6
I called it TestFile.txt and put it into my C:\Temp directory

So now let's open the file via a file stream.
Code:
AnsiString File2Process = "C:\\Temp\\TestFile.txt";
std::ifstream FileStrm;
FileStrm.open(File2Process.c_str());
if (!FileStrm)          // OH NO, an error!
{
    // inform the user of the error then close the file
    FileStrm.close();
    return;
}                       // OH NO, an error
else                    // Process the file
{
...
}                      // Process the file
FileStrm.close()       // Close the file

This opens the file C:\Temp\TestFile.txt. Notice I prefer to use AnsiString and std::strings. That way I don't have to to worry buffer overflows. Next, I open the file stream for input using ifstream. There are alternate ways to open a file stream for input but this will suffice. Then I call the open function for the file stream and immediately check if it opened, If it did not. I put some sort of message out and close the file and return from the function.

Now lets move through the lines in the file. I do this by defining a standard string and calling getline in a while loop. This would go where the three dots (...) above.
Code:
    std::string LineStdStr;
    FileStrm.unsetf(std::ios::noskipws); // Do not skip whitespace
    FileStrm.seekg(0);       // Force to the beginning of the file (redundant)
    while (std::getline(FileStrm, LineStdStr, '\n')) // Process as long as there are line to process
    {
    ...
    } // Process as long as there are line to process

The getline will process each line in the file, looking for the newline character (/n) to determine where the end of the line is.

Here is where we have some options. You could use seekp() to move to the correct position. I prefer to
get all the info in the standard string LineStdStr and then process the data. For example, if your data doesn't change much, you could use a substring funtion to get the data. For example, you could so the following in place of the three dots (...) above.
Code:
        AnsiString SplitLineStr = LineStdStr.c_str(); // convert from std string to ansi
        if (SplitLineStr.Length() != 0)  // Data to process
        {
            // Collect the data from the line
            AnsiString FirstStr = (SplitLineStr.SubString(1, 2)).Trim();
            AnsiString SecondStr = (SplitLineStr.SubString(3, 2)).Trim();
        }

However, there is another way that will work better if the length of the substrings change. For example, instead of the file above, suppose the file looked like
Code:
1 20 3
4 5 6
7 855 9
1 2 3
4 5 6

Now the substring approach would fail. So let's try using the string streams. Substitute the following for the above code.
Code:
        // Get the parts
        std::string FirstStdStr, SecondStdStr, RemainStdStr;
        std::istringstream StrLine(LineStdStr);
        std::getline(StrLine,FirstStdStr, ' '); // Get data to first blank
        std::getline(StrLine,SecondStdStr, ' '); // Get data to second blank
        std::getline(StrLine,RemainStdStr, '/n'); // Get the rest of the line

Play around a bit and see what works for you.

Disclaimer I did NOT test this out so you will have to debug it a bit (a lot?). All I did was take snippets from programs that work and put it here.

Good luck. Check back if you get stuck.




James P. Cottingham
-----------------------------------------
[sup]I'm number 1,229!
I'm number 1,229![/sup]
 
I have another approach but then i'm doing something different.

I read the file size, reserve a buffer of that size and read the whole file into that buffer and then closes the textfile.

Then i'm able to screen through the full text and pick whatever i need and when i'm done with the text i simply delete the buffer.

In my use (reading and converting a HEX-file to binary datas) it's fast and efficient and it works like a charm.

The text in the file is, well in the buffer, just a series of characters (bytes), i don't need to seek specific index in file or anything like that.

Totte
Keep making it perfect and it will end up broken.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top