简体   繁体   English

在 C 中读取和写入文件

[英]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).我被困在 C 中的一些基本文件处理代码中。基本上我想解析一个输入文件以获取一些信息,然后将它放在另一个文件中(更多信息在输入文件中)。 I used an online gcc compiler for that and all was great.我为此使用了在线 gcc 编译器,一切都很棒。 When I enter code here compile the code in cmd with gcc command output file is empty.当我enter code here ,用 gcc 命令编译 cmd 中的代码,输出文件为空。

#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.首先,即使 OP 代码工作没有问题,输入文件也有问题。 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:但 inputfile.txt 行是:

"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. ...导致在初始化之前访问变量c This in turn results in undefined behavior .这反过来会导致未定义的行为 The fix is simple, always initialize variables before using them the first time: `char c[1000] = {0};修复很简单,在第一次使用变量之前总是初始化它们:`char c[1000] = {0};

Also, this line...还有,这条线...

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

will have different results depending on the contents of c .根据c的内容会有不同的结果。 Read about strcmp here . 在此处阅读有关strcmp 的信息

Finally, this line:最后,这一行:

fseek(fptr, 1,SEEK_CUR);

When using fseek with text files, one of the following must be true:对文本文件使用fseek时,必须满足以下条件之一:

  • offset must be zero.偏移量必须为零。
  • offset is the value returned by a previous call to ftell and origin is set to beginning-of-file. offset 是先前调用 ftell 返回的值,而 origin 设置为文件开头。

The value of 1 for offset does not meet either of these criteria. offset 的值1不满足这些标准中的任何一个。

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 .如果您愿意尝试更简单的读取/解析方法,则使用while(fgets(...)){...}构造利用比使用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.fgets看到EOF 时,它将退出循环。 (Note, EOF is inherent to text files, negating the need for the last line in your inputfile.txt) (注意,EOF 是文本文件固有的,不需要 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.但在 Windows 上实际上并非如此:为了兼容性,stdio 库会将\\r\\n转换为\\n ,但fseek只会跳过一个字节。

If you change that to如果你把它改成

fseek(fptr, 2,SEEK_CUR);

your program will work -- for a VERY broad definition of "work".你的程序会起作用——对于“工作”的一个非常广泛的定义。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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