This question already has an answer here:
I'm dealing with small text files that i want to read into a buffer while i process them, so i've come up with the following code:
...
char source[1000000];
FILE *fp = fopen("TheFile.txt", "r");
if(fp != NULL)
{
while((symbol = getc(fp)) != EOF)
{
strcat(source, &symbol);
}
fclose(fp);
}
...
Is this the correct way of putting the contents of the file into the buffer or am i abusing strcat()
?
I then iterate through the buffer thus:
for(int x = 0; (c = source[x]) != '\0'; x++)
{
//Process chars
}
There are quite a few things wrong with this code:
sizeof(source)
, this is prone to buffer overflows.You are appending a character (not a NUL-terminated string!) to a string that may or may not be NUL-terminated. The only time I can imagine this working according to the man-page description is if every character in the file is NUL-terminated, in which case this would be rather pointless. So yes, this is most definitely a terrible abuse of
strcat()
.The following are two alternatives to consider using instead.
If you know the maximum buffer size ahead of time:
Or, if you do not:
See this article from JoelOnSoftware for why you don't want to use
strcat
.Look at fread for an alternative. Use it with 1 for the size when you're reading bytes or characters.
Why don't you just use the array of chars you have? This ought to do it:
Methinks you want fread:
http://www.cplusplus.com/reference/clibrary/cstdio/fread/
Yes - you would probably be arrested for your terriable abuse of strcat !
Take a look at getline() it reads the data a line at a time but importantly it can limit the number of characters you read, so you don't overflow the buffer.
Strcat is relatively slow because it has to search the entire string for the end on every character insertion. You would normally keep a pointer to the current end of the string storage and pass that to getline as the position to read the next line into.
If you're on a linux system, once you have the file descriptor you can get a lot of information about the file using fstat()
http://linux.die.net/man/2/stat
so you might have
This avoids seeking to the beginning and end of the file.