1

我想读取一个文本文件并将其内容传输到 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个,如果有人指出我的错误并告诉我如何摆脱这些无用字符,我将不胜感激......

4

5 回答 5

3

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

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;
}
于 2013-04-10T06:23:03.227 回答
2

您需要检查所有对fseek(),fread()fwrite(), 甚至的调用的返回值fclose()

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

于 2013-04-10T06:21:48.347 回答
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的文件中f_dst。它BUFSIZ使用<stdio.h>. 通常,您会发现更大的缓冲区(例如 4 KiB 或 4096 字节,甚至 64 KiB 或 65536 字节)将提供更好的性能。大于 64 KiB 很少会产生很多好处,但是 YMMV。

上面的代码调用了一个错误报告函数 ( err_syserr()),假定它不会返回。这就是为什么我将其指定为“几乎通用”。该函数可以升级为返回一个int值,成功返回 0,失败返回 EOF:

enum { BUFFER_SIZE = 4096 };

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

    while ((n = fread(buffer, sizeof(char), sizeof(buffer), f_src)) > 0)
    {
        if (fwrite(buffer, sizeof(char), n, f_dst) != n)
            return EOF;  // Optionally report write failure
    }
    if (ferror(f_src) || ferror(f_dst))
        return EOF;  // Optionally report I/O error detected
    return 0;
}

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

于 2013-04-10T16:04:25.190 回答
0

注意ftell返回 a long,而不是 a 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;
于 2013-04-10T06:30:34.440 回答
0

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

对我来说应该是这样——

fwrite(缓冲区,大小,1,pFile)

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

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

所以改变顺序再试一次。

于 2013-04-10T14:05:52.640 回答