Do not use feof() as a loop condition; it will not return to its original state until you try to read the end of the file, which means that your loop will execute too many times. Check the result of your input call (do you use fgets() or fscanf() ) to check if it succeeded, and then check feof() if you get an error condition.
if (fgets(buffer, sizeof buffer, stream) != NULL) { // process the input buffer } else if (feof(stream) { // handle end of file } else { // handle read error other than EOF }
fgets() reads entire lines, not single characters, so you don’t want to pass the address of every single character in your line. Call it like this:
if (fgets(list[i], sizeof list[i], stream) != NULL) {
And now, for Bode, the usual spiel about arrays and pointers ...
When a majority expression is expressed in most contexts, the type of the expression is implicitly converted from "N-element array of T" to "pointer to T", and the value of the expression is the address of the first element of the array. The exceptions to this rule are that the array expression is the operand of the sizeof or & operators, or it is a string literal that is used as the initializer in the declaration. When you hear people say that “arrays and pointers are the same thing,” they distort this rule. Arrays and pointers are completely different animals, but they can be used interchangeably in some contexts.
Note that in the above code, I passed list[i] as the first argument to the fgets () function without any decoration (for example, the & operator). Despite the fact that the type list[i] is a “12-element char array”, in this context it is implicitly converted to the type “pointer to char”, and the value will be the address list[i][0] . Note that I also passed this expression to the sizeof statement. In this case, the type of the array expression is not converted to a pointer type, and the sizeof operator returns the number of bytes in the array type (12).
Just to nail it:
Expression Type Implicitly converted to
---------- ---- ----
list char [100] [12] char (*) [12] (pointer to 12-element array of char)
list [i] char [12] char *
list [i] [j] char N / A
What all this means is that fgets() will read up to the next 12 characters (assuming it doesn't get to a new line or EOF) and save it starting with list[i][0] . Note that fgets() will write a terminating null character (0) to the end of your line. Note also that if fgets() is encountered with a new line, but there is space in the target array, and the terminating nul, fgets() will store the terminating line of the new line before the nul character. Therefore, if your input file has a line like
1.1.1.1\n
then the contents of your input buffer after reading will be "1.1.1.1\n\0xxx" , where x is a random value. If you do not want to use a new line, you can use the strchr() function to find it and then overwrite it with 0:
char *newline; ... if ((newline = strchr(input[i], '\n')) != NULL) { *newline = 0; }
Since fgets() stops on the next new line, and since your input buffer is 12 characters long, you may run into a situation where you have a new line as the next input character in the file; in this case fgets() will only write this new line for the input buffer, so you will have some empty entries, which is probably not what you want. You can add extra bytes to the input buffer to avoid this situation.
Putting it all together:
char list[100][13]; ... for (i = 0; i < 100; ++) { if (fgets(list[i], sizeof list[i], stream) != NULL) { char *newline = strchr(list[i], '\n'); if (newline != NULL) *newline = 0; printf("Read address \"%s\"\n", list[i]); count++; } else if (feof(stream)) { printf("Reached end of file\n"); break; } else { printf("Read error on input; aborting read loop\n"); break; } }