Reading Text Files


InsertCoin

Still Fresh
Joined
May 18, 2006
Messages
22
So I've got this 'friend' whose unsure of his code. Looking for hints on grabbing text from a file to display them character by character. I can do it using getline(__, __, '\n'), but I dont think its practical for controlling the number of characters per line and wrapping words if the file is fairly large... It feels like a 'wood for the trees' kind of problem TBH :rolleyes:
Ta.
 
fgets is the usual way to read a maximum length of line from a file. If the line is longer than the buffer you supply, it'll just leave your buffer unterminated - so it's usually a good idea to pass the size of the buffer one smaller, so the last character of the buffer is never written to, and manually set that last character to 0. You can still tell if the line was incomplete becuase fgets leaves a trailing '\n' on complete lines - but watch out for the end of the file, which is also not '\n'-terminated.

If you actually want to word-wrap the text, you may be better off using fscanf to read word by word. I usually just use fgets though, and manually parse for words.. or use strtok if you don't hate it too much.
 
Right, so I've been playing with fgets() and I'm doing alright even if I do say so myself. So thanks for the hint.

Now, we have something like
pszMatrix[x]
which needs needs an extra byte to terminate a string after it's created,
fgets()
which puts a null at the end of the bytes read.

so, using something like
char pszMatrix[x][46];
with
fgets(&pszMatrix[x][0], 46, pMyFile);
should just overwrite the null character with no problem, right?

Can simply having in the array 'NULL, Char, NULL' right before the end of the array cause an issue? Because it looks like of of those things that would cause an annoying problem later on.
 
Sorry, I might have been wrong about fgets's behaviour when it truncates a line - from the documentation it looks like it does terminate the buffer properly. I don't know where I got the idea that it didn't from!

Your fgets line looks fine - I tend to use sizeof() rather than passing 46 for example. Either that or use a #define or enum to make sure the declaration and the fgets line agree on the size of the buffer.

Generally my file reading code tends to look a lot like this:

Code:
char buffer[1024];
buffer[1023] = 0;
while( !feof(fp) )
{
	// read line from file
	fgets( buffer, sizeof(buffer) - 1, fp );

	char *newline = strchr( buffer, '\n' );
	if( newline )
	{
		*newline = 0; // remove the newline character
	}
	else if( !feof(fp) )
	{
		// Line was truncated due to being too long.
		// Either handle it nicely or just complain about bad input data.

		break; // Here I'll just give up & ignore the data
	}

	// process the line of data in buffer
}

So I create a buffer, set the last character to null in advance of reading any data, then invite fgets to write up to N-1 characters into the buffer. The pretermination and passing a short length are due to not trusting it to properly terminate truncated lines - as I said above, maybe I'm wrong about that!

I look for a newline character each time, and clear it if found - I'm usually not interested in seeing those. If there's no newline character, then either it's the end of the file (which I consider to be a complete line), or, if not, the line was too long to fit in the buffer - you can try to handle this nicely, I just quit in the above example though.

I then process the data at the end of the loop - either parsing it on the spot, or it looks like in your case you want to put it into some other data structure. I don't tend to read directly into the data structure I'm working with, but maybe that's because I rarely work on text data directly - I usually want to parse it anyway.
 
Back
Top