Reputation: 175
I'm trying to fill an array from a text file. I'm using fgetc and my problem is dealing with the newline characters that are in the text file. I've currently got,
for(i = 0; i < rows; i++){
for(j = 0; j < columns; j++){
if((fgetc(fp) == '\n') || (fgetc(fp) == '\r')){
fgetc(fp);
array[i][j] = fgetc(fp);
else{
array[i][j] = fgetc(fp);
}
printf("i %d j %d char %c code %d\n", i, j, array[i][j], array[i][j]);
}
}
The idea is that if there's a newline character I want to advance the file pointer while in the same i,j position of the loop so I can get the next character. The output for this is jumbled for the first two rows and then it starts reading characters with character code -1. Am I doing something terribly wrong?
Upvotes: 0
Views: 6574
Reputation: 585
I believe you are getting the character in your evaluation statement twice. Also, typically the CRLF (carriage return and line feed) end of line characters can be two characters. Read http://en.wikipedia.org/wiki/Newline for details on this.
#include <stdio.h>
int main ()
{
FILE *fp;
int c;
fp = fopen("file.txt","r");
if(fp == NULL)
{
fprintf(stderr,"Error opening file");
return(-1);
}
do
{
c = fgetc(fp);
if ((c == '\n') || (c == '\r')) {
fgetc(fp); // skip CR or LF and advance a character
} else {
printf("%c", c); // print all other characters
}
}while(c != EOF);
fclose(fp);
return(0);
}
This was a quick hit at the code from memory. I don't have a compiler readily available but I think it is correct.
Upvotes: 1
Reputation: 304
I can immediately see one source of error. In the following line:
if((fgetc(fp) == '\n') || (fgetc(fp) == '\r'))
There are 2 calls to fgetc(). This means that if the first call does not return '\n', another call will be made whose return value is then compared to '\r'. This has the effect of advancing the file pointer twice, as the pointer is advanced each time you call fgetc . A better way to do this would be to fetch one character and then test whether it is '\n' or '\r', and only then incrementing the file pointer with another call to fgetc if this is true. For example:
char letter = fgetc(fp);
if((letter == '\n') || (letter == '\r')
...
...
Try this and see if you still get the same error.
Upvotes: 1
Reputation: 679
In your first if()
statement, there's a bit of an issue. When you do this:
if((fgetc(fp) == '\n') || (fgetc(fp) == '\r')){
fgetc(fp);
array[i][j] = fgetc(fp);
You actually are calling fgetc(fp)
four times. Twice in the if() statement, twice later on.
Perhaps you are looking more for something like this:
for(i = 0; i < rows; i++){
for(j = 0; j < columns; j++){
int test = fgetc(fp);
if(test != '\n' && test != '\r')
array[i][j] = test;
//We want to "undo" the last j++ if we got a whitespace
else
j--;
printf("i %d j %d char %c code %d\n", i, j, array[i][j], array[i][j]);
}
}
In this example, you call fgetc(fp)
exactly once per iteration, and if it's not a \n or \r, you put it in your array.
I'm sorry, I have little experience with fgetc()
. If you notice something incredibly awful with what I've done, please notify me!
Upvotes: 1
Reputation: 301
Each call to fgetc will advance the file pointer. Try calling it once:
int c = fgetc(fp);
then test the value of c. Store it if you want or go through the loop again.
Upvotes: 1