简体   繁体   中英

Reading and writing from a file in C

I got stuck in some basic file handling code in C. Basically I want to parse an input file to get some information, and then put it in another file (more information is in the input file). I used an online gcc compiler for that and all was great. When I enter code here compile the code in cmd with gcc command output file is empty.

#include <stdio.h>
#include <string.h>

int main() {
    char c[1000];
    FILE *fptr,*resultfp;
    if ((fptr = fopen("inputfile.txt", "r")) == NULL) {
        printf("can't be opened");
    }
    if ((resultfp = fopen("outputfile.txt", "w")) == NULL) {
        printf("can't be opened");
    }
    while(strcmp(c,"END OF FILE")){
 fscanf(fptr, "%[^\n]", c);
 fseek(fptr, 1,SEEK_CUR);
 if(strstr(c,"Example name") || strstr(c,"Example description") )
 {
    fscanf(fptr, "%[^\n]", c);
    fprintf(resultfp,"%s\n", c);
 }

    }

    fclose(fptr);
    fclose(resultfp);
    return 0;
}

and this is input file:

This is an example
Example name:
example1
Example description:
description1
Example name:
example2
Example description:
description2
I want to parse this file
In order to get example name and example description
END OF FILE

First, even if OP code worked without problem, the input file has a problem. Neither instance of the second criteria in the input file would never be read, or posted into the output file. ie the search criteria in the code is:

"Example description"

But the inputfile.txt line is:

"Example descripton:"//mis-spelled

Next, the lines...

char c[1000];
...
while(strcmp(c,"END OF FILE")){

...result in accessing the variable c before it is initialized. This in turn results in undefined behavior . The fix is simple, always initialize variables before using them the first time: `char c[1000] = {0};

Also, this line...

 while(strcmp(c,"END OF FILE")){

will have different results depending on the contents of c . Read about strcmp here .

Finally, this line:

fseek(fptr, 1,SEEK_CUR);

When using fseek with text files, one of the following must be true:

  • offset must be zero.
  • offset is the value returned by a previous call to ftell and origin is set to beginning-of-file.

The value of 1 for offset does not meet either of these criteria.

If you are open to trying a simpler read/parse method, using a while(fgets(...)){...} construct takes advantage of simpler parsing than can be done using variations of fscanf . The following loops until it finds the specified tag, then reads the next line in the file for the value. When fgets sees EOF , it will exit the loop. (Note, EOF is inherent to text files, negating the need for the last line in your inputfile.txt)

int main() {
    char c[1000] = {0};//always initialize before using
    FILE *fptr,*resultfp;
    if ((fptr = fopen("inputfile.txt", "r")) == NULL) {
        printf("can't be opened");
        return 0;
    }
    if ((resultfp = fopen("outputfile.txt", "w")) == NULL) {
        printf("can't be opened");
        fclose(fptr);
        return 0;
    }
    // all is well so far, continue

    while(fgets(c, sizeof(c), fptr))
    {
         if(strstr(c,"Example name") || 
            strstr(c,"Example description") )
         {
            fgets(c, sizeof(c), fptr);
            fprintf(resultfp,"%s\n", c);
         }
     }

    fclose(fptr);
    fclose(resultfp);
    return 0;
}   

Because of the way the input file is specified, it is sufficient, and simple to inspect each full line for the various tag-value pairs, in this case presented on separate lines, this method simplifies the parsing and testing of each pair.

Your program has a lot of problems, but the one that kills it is the fact that it assumes that the newline is a single character, that

fseek(fptr, 1,SEEK_CUR);

will skip over.

But that's actually not the case on Windows: the stdio library will translate \\r\\n into \\n for the sake of compatibility, but the fseek will skip just a single byte.

If you change that to

fseek(fptr, 2,SEEK_CUR);

your program will work -- for a VERY broad definition of "work".

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM