Reputation: 2924
I'm trying to read lines on a text file into a buffer by giving a function a line number as a parameter. This function then copies the text contained on that particular line of the file into the variable retreiveString
for use. The problem I'm having is that, if there is no 'empty newline' at the very end of the text file, the program doesn't copy the last entry into the buffer. What am I doing wrong?.
example of textfile that reads properly
line 0
line 1
example of textfile that doesnt read in the last line into the buffer (i.e line 1).
line 0
line 1
//test2
#include <stdio.h>
#include <string.h>
#define BUFFER_SIZE 80
char read_in_buffer[BUFFER_SIZE];
char retreivedString[BUFFER_SIZE];
void getString(int lineNum);
int maxDataNum = 0;
bool endOfFileReached = false;
int main(void){
printf("-Main-\n");
getString(1);
printf("retrieved:%s\n",retreivedString);
printf("maxdata: %d\n",maxDataNum);
printf("strlen: %d",strlen(retreivedString));
/*
getString(2);
printf("retrieved: %s\n",retreivedString);
printf("maxdata: %d\n",maxDataNum);
getString(4);
printf("retrieved: %s\n",retreivedString);
printf("maxdata: %d\n",maxDataNum);
*/
return 0;
}
void getString(int lineNum){
FILE *fin=fopen("file1_Windows.txt","r");
int line_number = 0;
char *temp;
if(fin==NULL){
printf("cannot open file1_Windows.txt\n");
}
while (1){
memset(read_in_buffer,0,sizeof(read_in_buffer));
fgets(read_in_buffer,sizeof(read_in_buffer),fin); //change to segment size?
if (!feof(fin)) {
if (lineNum == line_number){
memset(retreivedString,0,sizeof(retreivedString));
strcpy(retreivedString,read_in_buffer);
}
//printf("current line %d: ",line_number);
//printf("%s",read_in_buffer);
line_number++;
}else {
fclose(fin);
printf("End-of-File reached. \n");
maxDataNum = line_number;
printf("maxdata: %d\n",maxDataNum);
if (lineNum == maxDataNum){
endOfFileReached = true;
}else if (lineNum > maxDataNum){
printf("file read error, you're reading further that data on file\n");
}
break;
}
}
}
Upvotes: 2
Views: 1564
Reputation: 1857
put the fgets() line inside if() condition. After all u want to read something from file only if EOF has not been set.
if (!feof(fin)) {
line_number++;
fgets(read_in_buffer,sizeof(read_in_buffer),fin);
...
}
Upvotes: 0
Reputation: 1376
Here is what standard says about fgets:
Synopsis
char *fgets(char * restrict s, int n, FILE * restrict stream);
Description
The fgets function reads at most one less than the number of characters specified by n from the stream pointed to by stream into the array pointed to by s. No additional characters are read after a new-line character (which is retained) or after end-of-file. A null character is written immediately after the last character read into the array.
Returns
The fgets function returns s if successful. If end-of-file is encountered and no characters have been read into the array, the contents of the array remain unchanged and a null pointer is returned. If a read error occurs during the operation, the array contents are indeterminate and a null pointer is returned.
So, here is what happens:
Conclusion:
So if you print retreivedString, the output will be an empty string.
Upvotes: 3
Reputation: 64700
Do this. It returns if the fopen
call fails and puts the fgets
call in the while loop:
void getString(int lineNum){
FILE *fin=fopen("file1_Windows.txt","r");
int line_number = 0;
char *temp;
if(fin==NULL){
printf("cannot open file1_Windows.txt\n");
return;
}
memset(read_in_buffer,0,sizeof(read_in_buffer));
while (fgets(read_in_buffer,sizeof(read_in_buffer),fin) != NULL){
if (lineNum == line_number){
memset(retreivedString,0,sizeof(retreivedString));
strcpy(retreivedString,read_in_buffer);
}
//printf("current line %d: ",line_number);
//printf("%s",read_in_buffer);
line_number++;
memset(read_in_buffer,0,sizeof(read_in_buffer));
}
fclose(fin);
printf("End-of-File reached. \n");
maxDataNum = line_number;
printf("maxdata: %d\n",maxDataNum);
if (lineNum == maxDataNum){
endOfFileReached = true;
}else if (lineNum > maxDataNum){
printf("file read error, you're reading further that data on file\n");
}
}
Upvotes: 3
Reputation: 10381
Rather than testing feof
(see this thread for reasons not to) within the while loop, test to see if read_in_buffer
is null, as once you've run out of lines to read, that pointer becomes null. You could even put your fgets as your if statement body:
if (fgets(read_in_buffer,sizeof(read_in_buffer),fin))
{
}
Upvotes: 2