Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/58.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 简单的文件复制,在不同的文件类型上有不同的行为_C_Pdf_Jpeg - Fatal编程技术网

C 简单的文件复制,在不同的文件类型上有不同的行为

C 简单的文件复制,在不同的文件类型上有不同的行为,c,pdf,jpeg,C,Pdf,Jpeg,我尝试了一些C语言中的文件操作技术,所以我编写了一个简单的程序,将一个文件作为输入并复制到一个空文件中。我在“二进制”和“读取”模式下用fopen()打开了要读取的文件,使用fgetc()逐个读取所有字节,并将它们写入我想要写入的文件,该文件在“写入”和“二进制”模式下打开。当复制操作完成(EOF)时,我对这两个文件调用了fclose()并终止了程序 问题是:对于文本文件来说,一切都很好,但是当我尝试以不同的格式复制文件(如pdf或jpeg)时,我会遇到分割错误。由于代码非常简短,我怀疑这个问题

我尝试了一些C语言中的文件操作技术,所以我编写了一个简单的程序,将一个文件作为输入并复制到一个空文件中。我在“二进制”和“读取”模式下用fopen()打开了要读取的文件,使用fgetc()逐个读取所有字节,并将它们写入我想要写入的文件,该文件在“写入”和“二进制”模式下打开。当复制操作完成(EOF)时,我对这两个文件调用了fclose()并终止了程序

问题是:对于文本文件来说,一切都很好,但是当我尝试以不同的格式复制文件(如pdf或jpeg)时,我会遇到分割错误。由于代码非常简短,我怀疑这个问题是因为我对用C语言读写这些文件格式缺乏理解,而不是因为代码中有错误

欢迎您提出任何建议和想法,如果您怀疑我可能对代码做了一些错误,我也可以发布它

编辑:好的,我可能把代码搞乱了,现在是:

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

#define MAXCHAR 10000000

int main( int argc, char** argv)
{
    if( argc != 3)
    {
        printf( "usage: fileexer1 <read_pathname> <write_pathname>");
        exit( 1);
    }

    FILE* file_read;
    FILE* file_write;

    int nextChar;
    char readBuffer[MAXCHAR];
    int valid = 0;

    // These hold the path addresses to the files to be read and written
    char* read_file_path = argv[1];
    char* write_file_path = argv[2];

    // The file to be read is opened in 'read' and 'binary' modes
    file_read = fopen( read_file_path, "rb");
    if( !file_read)
    {
        perror( "File cannot be opened for reading");
        exit( 1);
    }

    // The file to be written into is opened in 'write' and 'binary' modes
    file_write = fopen( write_file_path, "wb");
    if( !file_write)
    {
        perror( "File cannot be opened for writing");
        exit( 1);
    }

    nextChar = fgetc( file_read);
    while( nextChar != EOF)
    {
        readBuffer[valid] = (char) nextChar;
        valid++;
        nextChar = fgetc( file_read);
    }

    int i;
    for( i = 0; i < valid; i++)
    {
        fputc( readBuffer[i], file_write);
    }

    fclose( file_read);
    fclose( file_write);

   return 0;
}
#包括
#包括
#定义MAXCHAR 10000000
int main(int argc,字符**argv)
{
如果(argc!=3)
{
printf(“用法:fileexer1”);
出口(1);
}
文件*文件读取;
文件*文件写入;
int nextChar;
char readBuffer[MAXCHAR];
int valid=0;
//它们保存要读取和写入的文件的路径地址
char*read_file_path=argv[1];
char*write_file_path=argv[2];
//要读取的文件以“读取”和“二进制”模式打开
file_read=fopen(读取文件路径,“rb”);
如果(!文件读取)
{
perror(“文件无法打开读取”);
出口(1);
}
//要写入的文件以“写入”和“二进制”模式打开
file_write=fopen(写入文件路径,“wb”);
如果(!文件写入)
{
perror(“无法打开文件进行写入”);
出口(1);
}
nextChar=fgetc(文件读取);
while(nextChar!=EOF)
{
readBuffer[valid]=(char)nextChar;
有效++;
nextChar=fgetc(文件读取);
}
int i;
对于(i=0;i
我敢打赌,你的代码一定有问题,因为写二进制类型的文件没有什么特别的地方。二进制就是二进制。下面是一些将名为1.jpg的图像复制到2.jpg的代码

int main (){
    FILE *readf, *writef;
    unsigned char *buffer;
    unsigned long len;
    int i=0;

    //Open file
    readf = fopen("1.jpg", "rb");
    writef = fopen("2.jpg","wb");

    //you should check if readf & writef were opened successfully here...

    //Get file length
    fseek(readf, 0, SEEK_END);
    len=ftell(readf);
    fseek(readf, 0, SEEK_SET);

    //Allocate memory
    buffer=(char *)malloc(len);

    //check that buffer got memory allocated here... 

    fread(buffer,fileLen,sizeof(unsigned char),readf);
    fwrite(buffer,fileLen,sizeof(unsigned char),writef);

    //cleanup
    fclose(readf);
    fclose(writef);
    free(buffer);
    return 0;
}

如果你打算一个字符一个字符地读写,那么分配一个巨大的缓冲区来保存数据就没有什么意义了。忽略错误检查:

int main(int argc, char **argv) { 

   FILE *infile = fopen(argv[1], "rb");
   FILE *outfile = fopen(argv[2], "wb");

   int ch;

   while (EOF != (ch = getc(infile)))
      putc(ch, outfile);

   return 0;
}

如果要一次读取一个字符,则不需要在堆栈的缓冲区中保存1000万个字符。而且您的代码无法正常处理超过1000万字节的文件

只需在调用
fgetc()
之前的输入循环中使用
fputc(nextChar)
,并消除
readBuffer
变量和输出循环。如果需要,您仍然可以计算有效字符数,但没有必要

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

int main( int argc, char** argv)
{
    if( argc != 3)
    {
        printf( "usage: fileexer1 <read_pathname> <write_pathname>");
        exit( 1);
    }

    FILE* file_read;
    FILE* file_write;

    int nextChar;

    // These hold the path addresses to the files to be read and written
    char* read_file_path = argv[1];
    char* write_file_path = argv[2];

    // The file to be read is opened in 'read' and 'binary' modes
    file_read = fopen( read_file_path, "rb");
    if( !file_read)
    {
        perror( "File cannot be opened for reading");
        exit( 1);
    }

    // The file to be written into is opened in 'write' and 'binary' modes
    file_write = fopen( write_file_path, "wb");
    if( !file_write)
    {
        perror( "File cannot be opened for writing");
        exit( 1);
    }

    while ((nextChar = fgetc(file_read)) != EOF)
        fputc(nextChar, file_write);

    fclose( file_read);
    fclose( file_write);

   return 0;
}

使用
peror()
会限制您的消息的有用性;最好使用
fprintf(stderr,…)
,但我还没有为您解决这个问题。

当然,C对文件格式一无所知,所以您的代码中一定有错误。是的,我知道一次读取一个字符效率不高,我只是在试验,但我尝试的一些文件小于10MB,你认为代码中可能存在另一个错误而不是冗余吗?@john27:实际上,使用getc/putc并不是那么低效——在幕后,库会为你做缓冲,所以你一次读取更大的块(例如4Kib)。不确定它是你当前问题的根源,但是你可能想考虑如果你试图复制一个大于<代码> Max Char < /C> >的文件会发生什么……嗯,我只是抛弃了Jerry Coffin所说的使用缓冲区的全部想法。它成功了。虽然我没有在大于10MiB的文件中得到分段错误,但是在一些大约7MiB的文件中得到了分段错误,我猜缓冲区是错误背后的原因。
#include <stdio.h>
#include <stdlib.h>

int main( int argc, char** argv)
{
    if( argc != 3)
    {
        printf( "usage: fileexer1 <read_pathname> <write_pathname>");
        exit( 1);
    }

    FILE *file_read;
    FILE *file_write;
    char buffer[64*1024];
    size_t nbytes;

    // The file to be read is opened in 'read' and 'binary' modes
    file_read = fopen(argv[1], "rb");
    if (!file_read)
    {
        perror("File cannot be opened for reading");
        exit(1);
    }

    // The file to be written into is opened in 'write' and 'binary' modes
    file_write = fopen(argv[2], "wb");
    if (!file_write)
    {
        perror("File cannot be opened for writing");
        exit(1);
    }

    while ((nbytes = fread(buffer, sizeof(buffer), sizeof(char), file_read)) != EOF)
    {
        if (fwrite(buffer, nbytes, sizeof(char), file_write) != nbytes)
        {
            perror("Failed to write to file");
            exit(1);
        }
    }

    fclose(file_read);
    fclose(file_write);

   return 0;
}