我在C中尝试了一些文件操作技术,因此我编写了一个简单的程序,它将文件作为输入并将其复制到空文件中。我在'二进制'和'读'模式下用fopen()打开文件读取,使用fgetc()逐个读取所有字节,并将它们写入我想写的文件,在'write'和''中打开二元'模式。当复制操作完成(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;
}
答案 0 :(得分:1)
我打算猜测你的代码有问题,因为编写任何二进制类型文件都没什么好看的。二进制是二进制的。这里有一些代码将名为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;
}
答案 1 :(得分: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;
}
答案 2 :(得分:0)
如果您要一次阅读一个字符,则不需要将1000万个字符保存在堆栈中的缓冲区中。并且您的代码不会优雅地处理超过1000万字节的文件。
在fputc(nextChar)
调用之前,只需在输入循环中使用fgetc()
,并消除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;
}
请注意,某些系统存在10 MiB堆栈的问题。如果您想提高效率,请考虑使用64 KiB缓冲区,然后使用fread()
和fwrite()
来读取和写入数据块。
#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;
}
使用perror()
会限制邮件的有效性;最好使用fprintf(stderr, ...)
,但我还没有解决这个问题。