在c中复制文本文件的内容

时间:2013-04-10 06:19:42

标签: c file-io standard-library

我想读取一个文本文件并将其内容传输到c中的另一个文本文件,这是我的代码:

             char buffer[100]; 

             FILE*  rfile=fopen ("myfile.txt","r+");
             if(rfile==NULL)
            {
              printf("couldn't open File...\n");
            }


            fseek(rfile, 0, SEEK_END);
            size_t file_size = ftell(rfile);
            printf("%d\n",file_size);
            fseek(rfile,0,SEEK_SET);
            fread(buffer,file_size,1,rfile);


            FILE* pFile = fopen ( "newfile.txt" , "w+" );
            fwrite (buffer , 1 ,sizeof(buffer) , pFile );
            fclose(rfile);
            fclose (pFile);
            return 0;
          } 

我面临的问题是接收文件中不必要数据的出现, 我用“sizeof(buffer)”和“file_size”尝试了fwrite函数,在第一种情况下它显示了更多无用的字符,而在第二种情况下,无用字符的数量只有3,我真的很感激,如果有人指出我的错误并告诉我如何摆脱这些无用的角色......

5 个答案:

答案 0 :(得分:3)

您正在接收文件中写入buffer(100个字符)的所有内容。您需要写出准确的读取数据量。

fwrite(buffer, 1, file_size, pFile)

为您的代码添加更多检查:

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

#define BUFFER_SIZE   100

int main(void) {
    char buffer[BUFFER_SIZE]; 
    size_t file_size;
    size_t ret;

    FILE* rfile = fopen("input.txt","r+");
    if(rfile==NULL)
    {
      printf("couldn't open File \n");
      return 0;
    }

    fseek(rfile, 0, SEEK_END);
    file_size = ftell(rfile);
    fseek(rfile,0,SEEK_SET);

    printf("File size: %d\n",file_size);

    if(!file_size) {
        printf("Warring! Empty input file!\n");
    } else if( file_size >= BUFFER_SIZE ){
        printf("Warring! File size greater than %d. File will be truncated!\n", BUFFER_SIZE);
        file_size = BUFFER_SIZE;
    }

    ret = fread(buffer, sizeof(char), file_size, rfile);
    if(file_size != ret) {
        printf("I/O error\n");
    } else {
        FILE* pFile = fopen ( "newfile.txt" , "w+" );
        if(!pFile) {
            printf("Can not create the destination file\n");
        } else {
            ret = fwrite (buffer , 1 ,file_size , pFile );
            if(ret != file_size) {
                printf("Writing error!");
            }
            fclose (pFile);
        }
    }
    fclose(rfile);
    return 0;
}

答案 1 :(得分:2)

您需要检查所有来电fseek()fread()fwrite(),甚至fclose()的回复值。

在您的示例中,您有fread()读取1个块,长度为100个字节。反转参数通常是一个更好的主意,例如:ret = fread(buffer,1,file_size,rfile)。然后ret值将显示它可以读取的字节数,而不仅仅是说它无法读取整个块。

答案 2 :(得分:1)

这是(几乎)通用文件复制功能的实现:

void fcopy(FILE *f_src, FILE *f_dst)
{
    char            buffer[BUFSIZ];
    size_t          n;

    while ((n = fread(buffer, sizeof(char), sizeof(buffer), f_src)) > 0)
    {
        if (fwrite(buffer, sizeof(char), n, f_dst) != n)
            err_syserr("write failed\n");
    }
}

给定要读取的打开文件流f_src和要写入的另一个打开文件流f_dst,它将与f_src关联的文件(其余部分)复制到与{关联的文件{1}}。它使用来自f_dst的缓冲区大小BUFSIZ来适度经济地进行。通常,您会发现更大的缓冲区(例如4 KiB或4096字节,甚至64 KiB或65536字节)将提供更好的性能。超过64 KiB很少会产生很多好处,但是YMMV。

上面的代码调用错误报告函数(<stdio.h>),假定不返回。这就是为什么我指定它“几乎是通用的”。该函数可以升级为返回err_syserr()值,成功时返回0,失败时返回EOF:

int

请注意,此设计不会打开或关闭文件;它适用于打开的文件流。您可以编写一个包装器来打开文件并调用复制功能(或将复制代码包含在函数中)。另请注意,要更改缓冲区大小,我只需更改缓冲区定义;我没有更改主要的复制代码。另请注意,调用此小函数时的任何“函数调用开销”都会被I / O操作本身的开销完全淹没。

答案 3 :(得分:0)

注意ftell会返回long,而不是size_t。不过,这里无关紧要。但是,ftell本身不一定是字节偏移量。该标准要求它只是fseek的可接受参数。您可能会从fgetpos获得更好的结果,但由于标准缺乏规范,它具有相同的可移植性问题。 (忏悔:我没有检查标准本身;从联机帮助页中得到了所有这些。)

获取文件大小的更健壮的方法是使用fstat

#include <sys/types.h>
#include <sys/stat.h>
#include <unistd>

struct stat stat_buf;
if (fstat(filename, &buf) == -1)
    perror(filename), exit(EXIT_FAILURE);
file_size = statbuf.st_size;

答案 4 :(得分:0)

我认为你在fwrite中传递的参数不是正确的顺序。

对我来说应该是那样的 -

的fwrite(缓冲器,大小,1,PFILE)

作为fwrite的语法 size_t fwrite(const void * ptr,size_t size,size_t nmemb,FILE * stream);

函数fwrite()将每个大小字节长的数据的nmemb元素写入stream指向的流,从ptr给出的位置获取它们。

因此,请更改序列并重试。