使用C语言编辑文件

3

Input.txt:

File entry structures:
[0] ""  0       -1
[1] ""  0       -1
[2] ""  0       -1
[3] ""  0       -1
[4] ""  0       -1

我想创建一个新文件(output.txt)。该C程序将第一个出现的 "" 替换为 "Testfile",因此它看起来像这样:
Output.txt:
File entry structures:
[0] "Testfile"  0       -1
[1] ""  0       -1
[2] ""  0       -1
[3] ""  0       -1
[4] ""  0       -1

我迄今为止的工作:

#include <stdio.h>

int main() {
    FILE *input_file, *output_file;
    int  size, fblock;
    char index[81];
    char name[81];
    
    
    input_file = fopen("input.txt", "r");
    
    output_file = fopen("output.txt", "w");
    
    // ignore "File entry structures:" line when reading/writing
    
    while (fscanf(input_file, "%80s %80s %d %d", index, name, &size, &fblock) == 4) {
        fprintf(output_file, ... );
    }
    

    

我不确定应该将什么内容提供给fprintf的第二个参数。我的目标是以与输入文件相同的方式编写它。


3
你应该更担心fscanf中的参数。你的编译器是否对第4个格式说明符的类型不匹配发出警告?为什么传递&size而不是fblock?你提供了4个格式说明符,但期望fscanf返回2,这是不匹配的。 - Gerhardh
1
对于 fprintf,您可以简单地使用 "%s %s %d %d\n" 作为格式字符串,但是您的代码缺少替换字符串的逻辑。 - Gerhardh
2
以下是一些参考资料:https://en.cppreference.com/w/c/io/fscanf
https://cplusplus.com/reference/cstdio/printf/学会阅读和理解这些类型的参考资料,事情就会变得更容易。
- Samuel Åslund
1
根据您想要实现的数字对齐方式,您可以添加字段宽度修饰符或将一些空格插入格式字符串中。或者您的目标是以与输入文件相同的方式编写它?在这种情况下,您不能使用 fscanf,因为它不提供有关空格的任何信息。 - Gerhardh
1
因为那是你正在寻找的 "" - Gerhardh
显示剩余7条评论
2个回答

0

你工作太努力了。而我又太拖延了。这可以通过一个非常简单的状态机来完成:

#include <stdlib.h>
#include <stdio.h>

FILE * xfopen(const char *path, const char *mode);

int
main(int argc, char **argv)
{
    int c;
    int seen = 0;
    FILE *in = argc > 1 ? xfopen(argv[1], "r") : stdin;
    FILE *out = argc > 2 ? xfopen(argv[2], "r") : stdout;

    while( (c = fgetc(in)) != EOF ){
        if( seen == 0 && c == '"' ){
            int d = fgetc(in);
            if( d == '"' ){
                fputs("\"Testfile", out);
                seen = 1;
            } else {
                ungetc(d, in);
            }
        }
        fputc(c, out);
    }
    return 0;
}

FILE *
xfopen(const char *path, const char *mode)
{
    FILE *fp = path[0] != '-' || path[1] != '\0' ? fopen(path, mode) :
        *mode == 'r' ? stdin : stdout;
    if( fp == NULL ){
        perror(path);
        exit(EXIT_FAILURE);
    }
    return fp;
}

-1

可能有很多种方法来解决这个问题,所以这里提供一种建议的方法供您审查。在您的程序中,我添加了一些字符串检查和操作,以产生所需的结果,即将文字“Testfile”与数据的第一条记录关联起来。以下是您的程序的修订版本。

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

int main()
{
    FILE *input_file, *output_file;
    int  size, fblock, i;
    char index[81];
    char name[81];
    char h1[12], h2[12], h3[12]; /* Some work variables to bring across the heading for line #1 in the output file */
    
    input_file = fopen("input.txt", "r");
    
    output_file = fopen("output.txt", "w");
    
    // Ignore "File entry structures:" line when reading/writing
    
    i = fscanf(input_file, "%s %s %s", h1, h2, h3); /* The header line has three strings/words */
    
    fprintf(output_file, "%s %s %s\n", h1, h2, h3);  /* In the example the first line of the output file has this heading */
    
    while (1)
    {
        i = fscanf(input_file, "%80s %80s %d %d", index, name, &size, &fblock);
    
        if (i == -1) break;
        
        if (i == 4)
        {
            if (strcmp(index, "[0]") == 0)
            {
                strcpy(name, "\"Testfile\""); /* Replaces the null value with the literal */
            }
            fprintf(output_file, "%s %s %d %d\n", index, name, size, fblock);
        }
    }

   fclose(input_file);
   fclose(output_file);

   return 0;
}

我已经完成了“fprintf”函数的格式化,供您审查。此外,“<string.h>”中的“strcmp”和“strcpy”函数被用来提供“Record [0]”的搜索/替换。

当我使用您的示例数据运行此程序时,输出文件中的数据如下所示。

File entry structures:
[0] "Testfile" 0 -1
[1] "" 0 -1
[2] "" 0 -1
[3] "" 0 -1
[4] "" 0 -1

正如我所指出的,可能有其他方法可以达到您想要的结果,但这应该为您提供了一个起点。

希望能对您有所帮助。

此致敬礼。


1
Unix和Linux可以拥有并使用文本文件,但如果你的文件确实是二进制文件,那么在打开它时你需要将文件类型参数加上“b”(例如:fopen("filename", "rb"))。 - NoDakker
1
如果你的意思是 EOF,你真的应该使用 EOF 而不是 -1。此外,检查值 0-3 可能很值得,以防没有找到所有的值。if (i == -1) break; --> 如果你的意思是 EOF,你真的应该使用 EOF 而不是 -1。此外,检查值 0-3 可能很值得,以防没有找到所有的值。 - Gerhardh
1
如果第一个 "" 出现在另一行中会发生什么?此外,这段代码如何保留空格? if (strcmp(index, "[0]") == 0) - Gerhardh
1
@Heskinammo 如果你真的在处理二进制文件,就不应该使用字符串函数。如果你通过 fscanf 读取的字符串中包含了一些0字节,你的程序将会崩溃。你展示的内容明显是文本。那么二进制文件的需求从哪里来呢?也许只是一个误解,但 Unix 文件并不一定是二进制文件。 - Gerhardh
@Heskinammo 文件名并不重要,重要的是文件内容。 - Gerhardh
显示剩余4条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接