Reading Data from files in C

Oct 11, 2010 at 10:32pm
First, I'm using plain C and can only use plain C for this. Hence why I'm having issues.

I want to be able to open a file and read the data from it in lines. Eventually, I actually want to be able to search for a certain string in a file and get it's line number, and read certain lines based on line numbers.

The issue I'm running in to is how to read the data by lines and store it as C strings. I can read characters readily easily, but getting the characters combined into a string when I have no way of knowing how long the string will be is proving to be difficult, and I'm not even sure if it's a good way to do it.

Any advice?
Oct 12, 2010 at 1:05am
If you have no problem on limiting string size, you may use fread(), which lets you tell what is the size of each block you're gonna read (for instance, 1 byte, or sizeof(char), since you are reading characters) and how many blocks are you gonna read.
See http://www.cplusplus.com/reference/clibrary/cstdio/fread/
Oct 12, 2010 at 1:52am
Last edited on Oct 12, 2010 at 1:53am
Oct 12, 2010 at 12:44pm
I've taken a look at the function you wrote and it seems to work nicely. I'm going to play with it a little bit and see if I can figure out what's happening in it.

One thing though; it would not compile with block = ok +block -result -1; in it on my compiler (Dev-Cpp is my IDE), but upon commenting it out, it compiled and still seemingly works fine. What is that line for?

Edit: My question before still stands. I would still like to know what that line was for. Also, I have written my own function based on yours. It's not as dynamic, as the block sizes are hard-coded, but I would like to know how mine compares to yours and such. You see, I actually have never used malloc or realloc before, so I'm trying to get a grasp of what they're doing.

Here's my function:
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
char* readLine(FILE *file) {
    char *line, *block, *ok;
    int lastChar, size = 50;

    block = line = (char*)malloc(size);
    if(!line) return NULL;
    *line = '\0';

    do {
        ok = (char*)realloc(line, size += 50);
        if(!ok) break;

        ok = fgets(block, 50, file);
        if(!ok) break;

        lastChar = strlen(block) - 1;
    } while(block[lastChar] != '\n');

	if(!(*line)) {
		free(line);
		line = NULL;
	}

    return line;
}


Like I said, I've never used malloc and realloc and based this completely off of your code. So, I would appreciate any critiquing that you may provide. I'll be looking up the specifics of those functions, as well, and seeing if that helps me understand why this works.

Thank you for your help up until now =)
Last edited on Oct 12, 2010 at 4:24pm
Oct 12, 2010 at 3:00pm
Your code is not the same as Duoas' code, you've broken it badly.

block = ok +block -result -1; is pointer arithmetic and is correct.
Oct 12, 2010 at 4:30pm
Ok, well what's wrong with my code? If you can help me run through and fix it, that would be nice.

As it stands, the function works in my environment and runs as expected when compiled and ran, and adding that pointer arithmetic makes it not compile:

invalid operands to binary + 


I'm using Dev-C++, which I know is not the best, but it's what my C class required and I want to use it on my side projects (such as this one) as well, so I don't get used to the features of a different environment.

I'm going to start reading about malloc and realloc now (I had class for the last hour and a half), so if I figure out anything on my own, I will update the function and whatnot. But, for now, assume I haven't learned anything, and explain to me what's broken, so I can focus my attention on fixing it.
Oct 12, 2010 at 5:30pm
Ok, well what's wrong with my code? If you can help me run through and fix it, that would be nice.
You already have a posted solution.

I'm using Dev-C++
I've not used Dev-C++, but the code looks correct to me. Did you get syntax errors when you used the code as posted?

I'm going to start reading about malloc and realloc now
A good place to start is here. Read on for a few pages. http://computer.howstuffworks.com/c28.htm
Oct 12, 2010 at 5:52pm
1) I wanted to try to figure out how the function was doing things rather than blindly following it. That's why I tried to personalize it.

2) I get the error invalid operands to binary + for the code block = ok +block -result -1;

3) I was reading from the cplusplus references, but I'll take a look at that as well. Thank you.
Oct 12, 2010 at 7:33pm
If you try to enter a line more than 50 characters long you'll see why it works.

The problem is that I forgot something about pointer arithmetic -- C requires pointers to point to the same block to perform arithmetic. So line 28 should read something like:

  block = ok + (long)(block - result - 1);

The block is the current block of characters being read in the result string.
The result points to the entire string to be returned.
The ok pointer is the reallocated block of memory, and is non-NULL if successfully reallocated.

The function is pretty well commented if you want more information.
Topic archived. No new replies allowed.