c - 我想连接 n 个文件,但连接顺序不正确?

标签 c

我正在尝试编写一个C程序来连接N个文件,我应该从键盘读取它们,然后获取从FILE1到n开始的所有内容并将它们放在一个NEWFILE上,我的程序连接所有N个文件但顺序不是从1到n。例如:

I input N=3 and I put three files:
text1.txt (inside the file I have "We cannot")
text2.txt ("live")
text3.txt ("without water.")
and then save the concatination on a finalresult.txt

现在我的 Finalresult.txt 应该是:

We cannot
live
without water.

但我的结果是:

withoutwater. We cannot live

这是我的完整程序:

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

int main()
{

    int number;
    scanf("%d", &number);

    int i;

    char a[number][50];
    char help[50];
    for(i=0; i<number; i++)
    {
        scanf("%s", help);
        strcpy(a[i], help);
    }

    printf("Concating the content of %d files ...\n", number);

    FILE * filer, * filew;
    int numr,numw;
    char buffer[64];

    for(i=0; i<number; i++)
    {

        filer = fopen(a[i], "rt");
        if(filer == NULL)
        {
            fprintf(stderr, "open read file error.\n");
            exit(1);
        }

        filew = fopen("finalresult.txt","a+t");
        if(filew==NULL) {
            fprintf(stderr,"open write file error.\n");
            exit(1);
        }

        while(feof(filer)==0) {
            numr=fread(buffer,1,100,filer);

            if(numr!=100) {

                if(ferror(filer)) {
                    fprintf(stderr,"read file error.\n");
                    exit(1);
                }
            }

            numw=fwrite(buffer,1,numr,filew);

            if(numw!=numr) {
                fprintf(stderr,"write file error.\n");
                exit(1);
            }

        }
    }

    fclose(filer);
    fclose(filew);

    return 0;
}

最佳答案

你可以重写这个

char a[number][50];
char help[50];
for(i=0; i<number; i++)
{
    scanf("%s", help);
    strcpy(a[i], help);
}

作为

char a[number][50];
for(i=0; i < number; ++i)
    scanf("%s", a[i]);

您不需要另一个中间缓冲区。另请记住,“%s” 仅匹配非空字符,如果您的文件名有空字符, scanf 不会读取整个输入并在输入中留下额外的字符 缓冲区,从而扰乱下一个 scanf 调用。这里最好使用 fgets

char a[number][50];
for(i = 0; i < number; ++i)
{
    if(fgets(a[i], sizeof a[i], stdin) == NULL)
    {
        fprintf(stderr, "Could not read the filename\n");
        exit(1);
    }

    a[i][strcspn(a[i], "\n")] = 0; // removing newline
}

我还没有看到 fopen 的模式 't',它是模式的扩展吗 对于Windows?

您的代码存在问题,因为您正在调用

filew = fopen("finalresult.txt","a+t");

在循环内部,但你永远不会在循环内部关闭它。 FILE* 文件 被缓冲, 这意味着当您使用 fprintf(file,...)fwrite(..., file) 内容被缓冲并且内容以物理方式写入文件中 稍后,例如当缓冲区已满或您使用 fflush(filew) 时。所以 当您在执行 fflushfclose 之前 fopen 相同的文件时,旧的 缓冲的内容保留在缓冲区中,并在稍后的时间点写入(在 程序退出时的情况),从而覆盖您的新内容。您的新内容 都会有同样的命运。最后你会变得一团糟,因为内容 在程序结束时被覆盖。这就是为什么你会看到“垃圾” 文件。

因此,您必须先执行 fclose,然后再使用相同的文件名执行 fopen,或者 最好在循环之前执行fopen

此检查也不正确:

if(numr!=100) {
    if(ferror(filer)) {
        fprintf(stderr,"read file error.\n");
        exit(1);
    }
}

只有当文件大小是 100 的倍数时,这才是正确的。如果不是, 最后一个 block 将少于 100 个字节,您将结束程序, 即使 fread 没有错误。

所以我会像这样重写你的程序:

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

int main(void)
{
    size_t num_of_files;
    printf("Enter the number of files: ");
    fflush(stdout);
    if(scanf("%zu", &num_of_files) != 1)
    {
        fprintf(stderr, "Could not read the number of files\n");
        exit(1);
    }

    int c;
    // clearing the input buffer
    while((c = getchar()) != '\n' && c != EOF);

    char fnames[num_of_files][50];
    for(size_t i = 0; i < num_of_files; ++i)
    {
        printf("Enter the filename %zu: ", i+1);
        fflush(stdout);

        if(fgets(fnames[i], sizeof fnames[i], stdin) == NULL)
        {
            fprintf(stderr, "Could not read the filename\n");
            exit(1);
        }

        fnames[i][strcspn(fnames[i], "\n")] = 0; // removing newline
    }


    FILE *filew = fopen("finalresult.txt", "wt");
    if(filew == NULL)
    {
        fprintf(stderr, "Could not open file finalresult.txt for writing: %s\n",
                strerror(errno));
        exit(1);
    }

    for(size_t i = 0; i < num_of_files; ++i)
    {
        FILE *filer = fopen(fnames[i], "rt");
        if(filer == NULL)
        {
            fprintf(stderr, "could not open %s for reading, skipping: %s\n",
                    fnames[i], strerror(errno));
            continue;
        }

        char buffer[100];
        size_t len;
        while((len = fread(buffer, 1, sizeof buffer, filer)) != 0)
        {
            if(fwrite(buffer, 1, len, filew) != len)
            {
                fprintf(stderr, "Error writing finalresult.txt\n");
                fclose(filer);
                fclose(filew);
                exit(1);
            }
        }

        if(!feof(filer))
            fprintf(stderr, "file %s could not be read completely\n", fnames[i]);

        fclose(filer);
    }

    fclose(filew);

    return 0;
}

关于c - 我想连接 n 个文件,但连接顺序不正确?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48968479/

相关文章:

谁能告诉我为什么这段代码不起作用并且一直打印 0.00 公里作为最短距离?

c - 如何在 C 中绘制 3D 图形?

c - 在我的代码中有一个 null block 是个好主意吗

c - C中指针的内存分配

c - 如何在C中访问父进程的变量?

c - 为什么此代码在特定值后失败

C 无法在 Unix 中打开文件,但在 macOSx 上运行良好

c - 非套接字上的 send() 套接字操作

java - 从 c malloc 矩阵到 java 数组

c 程序无法正确接受输入并产生错误的输出