从 txt 文件中逐个字符读取,然后写入 C 中的另一个文件?

character by character reading from a txt file, and writing to another file in C?

(C, visual studio 2022 环境)

我必须编写一个程序来读取 .txt 文件(逐个字符)并将每个字符放入另一个 .txt 文件中(在 visual studio 创建的同一目录中)。 初始.txt文件太长,所以在这个问题中我写了一小部分数据。

这是我的首字母file.txt:

3.456789 3.456789 3.5671234566 3.450934759435735738457 3.3298017238973289742398074238 3.456789 3.456789 3.5671234566 3.450934759435735738457 3.3298017238973289742398074238 3.456789 3.456789 3.5671234566 3.450934759435735738457 3.3298017238973289742398074238 3.456789 3.456789 3.5671234566 3.450934759435735738457 3.3298017238973289742398074238

这是代码:(我只使用了 main.c 因为它只是测试 C 输入输出的测试):

代码应该做这些事情:

阅读部分:我赋值给计数fgetc的值[fgetc()return值是一个字符]。 fgetc 获取 f 流的字符。

检查部分:检查是否等于EOF宏。如果是这种情况,则“中断”并跳出第一个 while 循环。 {在写这个问题的时候,我在考虑这个阶段可能出现的一个错误:如果这个检查条件成立,那么第二个数组就会被执行,但是我在第二个 while 循环中会遇到另一个错误,因为我没有读取第一个文件完整}.

使用部分:如果 if 检查成立,则执行 calloc 并分配足够的内存(i,sizeof(double))来存储使用 fgetc 读取的值。

(又一次空指针检查,我又检查了x,因为我分配了x)。 {在写这个问题时,我在想是否必须检查 calloc,因为它不像 malloc。 malloc 用随机的东西填充分配的内存,但 calloc 将内存初始化为零}。

我分配了值(x[i] = 计数)。

我当然把 i 加了 1。

总结一下我的问题:

以及一般性问题:以这种方式编写此程序是否合法,或者您认为有更明智的方法来完成相同的任务吗? (注意:我知道我可以使用 fprintf() 和 fscanf(),但我想测试我的技能来编写一个程序来执行相同的任务,但一个字符一个字符地(在一个长的 txt 文件上))。

(我有两个错误和三个警告:

第一个错误:使用了未初始化的局部变量f(为什么?我已经初始化了它,因为它指向文件的开头)

第二个错误:使用了未初始化的局部变量 x(为什么?x 是一个指针,我已经检查过它是否是一个空指针,所以我不必初始化它)

第一个警告:“函数”:不兼容的类型(从“FILE *”到“const char *”)。

其余警告与错误一样,调试器也将其复制到警告列表中。

   #define _CRT_SECURE_NO_WARNINGS
    #include <stdio.h>
    #include <stdlib.h>
    int main(void) {
    
        FILE* f = fopen(f, "r"); 
        if (f == NULL) {
            return NULL; 
        }
        int* x; char count = 0; 
        if (x == NULL) {
            return NULL; 
        }
        unsigned int i = 1; 
        while (1) {
            count = fgetc(f); 
            if (count == EOF) {
                break; 
            }
             
            int* x = calloc(i, sizeof(double)); 
            if (x == NULL) {
                return -3; 
            }
            x[i] = count;
            i++; 
        } 
        FILE* g = fopen("otherfile.txt", "w"); 
        if (g == NULL) {
            return -2; 
        }
        int j = 1; 
        while (1) {
            fputc(x[j], g); 
            if (x[j] == EOF) {
                break; 
            }
            j++; 
        }
    
    
        free(x); 
        fclose(f); 
        fclose(g); 
        return 0; 
    }
        
FILE* f = fopen(f, "r"); 

这是明显的错字。应该是 fopen("inputfile", "r").

int* x; 
if (x == NULL) { return NULL;  }

x 未初始化。这意味着它可以是 NULL(零)或者它可以是任何其他随机值。你现在不能测试它。

while (1) {
    ...
    int* x = calloc(i, sizeof(double)); 
}

您在这里声明了一个不同的同名指针。第二个 x 是一个不同的变量,因为它在不同的范围内(当您将变量放在 {} 中时,范围会发生变化)

第二个x分配内存,然后在循环的下一次迭代中丢失。这会导致严重的内存泄漏。

sizeof(double) 不适用。如果您打算存储在 char 缓冲区中,首先您必须知道文件中有多少个字符。在阅读文件之前不可能知道这一点。

要解决此问题,您可以检查文件一次并计算字符数,或者检查文件大小。

分配足够的内存后,您可以使用 fread/fwrite 读取整个文件。

int main(void)
{
    FILE* fin = fopen("input.txt", "r");
    if (!fin) { perror("input error"); return 0; }
    FILE* fout = fopen("output.txt", "w");
    if (!fout) { perror("fout error"); return 0; }

    fseek(fin, 0, SEEK_END); //go to the end of file
    size_t filesize = ftell(fin); //get file size
    fseek(fin, 0, SEEK_SET); //go back to the beginning 

    //allocate enough memory
    char* buffer = malloc(filesize * sizeof(char));

    //read one character at a time (or `fread` the whole file)
    size_t i = 0;
    while (1)
    {
        int c = fgetc(fin);
        if (c == EOF) break;

        //save to buffer
        buffer[i++] = (char)c;
    }

    //write one character at a time (or `fwrite` the whole file)
    for (i = 0; i < filesize; i++)
        fputc(buffer[i], fout);

    free(buffer);
    fclose(fin);
    fclose(fout);
    return 0;
}