★★用 C 标准库写了个"文件复制"程序,可用但有些问题,帮忙看看改改!!!

MPU 2003-10-15 04:26:23
★★用 C 标准库写了个"文件复制"程序,可用但有些问题,帮忙看看改改!!!

/////////////////感觉有写问题大家帮忙看看改改!!!////////////////

/////////////////只在相同目录下复制///////////
/////////////////如下使用/////////////////////
Enter the infile name:
a.rar //源文件
Enter the outfile name:
c.rar //目标文件

/////////////////或者///////////////
mycopy a.rar c.rar

/*
我对小于10 M的文件直接分配内存复制,大于10 M的反复分配10 M内存复制.
*/

// VC++ 6 编译通过 -> cl mycopy.c
#include <stdio.h>
#include <conio.h>
#include <stdlib.h>

void main(int argc, char *argv[])
{//////////////////////// 输入控制 //////////////////////
FILE *in,*out;
unsigned long SourceSize = 0,ObjectSize = 0;
unsigned long kilobyte,millionbyte;
unsigned long *buffer;
unsigned long size; // 0 to 4,294,967,295 4G
unsigned long sum,remainder,tempsize = 0,tempnum = 0;
char infile[100],outfile[100];

char *prog = argv[0]; /* program name for errors */

// argv[2] source , argv[3] object
if ( argc == 1 ) //向导输入
{
printf("Enter the infile name:\n");
scanf("%s",infile);
printf("Enter the outfile name:\n");
scanf("%s",outfile);
if ( (in = fopen(infile,"rb")) == NULL )
{
fprintf(stderr, "%s: Can't open source!%s\n",prog, infile);
exit(1);
}
if ( (out = fopen(outfile,"wb")) == NULL )
{
fprintf(stderr, "%s: Can't open source!%s\n",prog, outfile);
exit(1);
}
}
else if ( argc == 3 ) //直接输入 如: mycopy a.rar c.rar
{
if ( (in = fopen(*++argv, "rb")) == NULL )
{
fprintf(stderr, "%s: Can't open source!%s\n",prog, *argv);
exit(1);
}
if ( (out = fopen(*++argv,"wb")) == NULL )
{
fprintf(stderr, "%s: Can't open object!%s\n",prog, *argv);
exit(1);
}
}
else
{
fprintf(stderr, "%s: Error!!!%s\n",prog);
exit(1);
}

if (ferror(stdout))
{
fprintf(stderr, "%s: error writing stdout\n", prog);
exit(1);
}
////////////////// 处理文件复制 /////////////////////
fseek (in, 0, SEEK_END); // 文件指针到文件尾
SourceSize=ftell (in); // 读取该位置,即文件大小
rewind (in); // 让文件指针重新回到文件开始

if ( SourceSize >= 4294967295 ) // >= 4G exit(1)
{
printf("This is file too bigger!");
exit(0);
}
else if ( SourceSize <= 10485760 ) // < 10 M
{
buffer = (int* ) malloc (SourceSize); // 动态分配缓冲区 < 10 M
fread (buffer, 1, SourceSize, in); // 把文件读入缓冲区
fwrite (buffer, 1, SourceSize, out);
}/////////////////以下可能有问题////////////////////
else // > 10 M -> 4294967295 == 4 G
{
sum = SourceSize / 10485760;
remainder = SourceSize % 10485760;
while ( sum-- )
{

buffer = (int* ) malloc (10485760); // 动态分配缓冲区 10 M
fread (buffer, 1, 10485760, in); // 把文件读入缓冲区
fwrite (buffer, 1, 10485760, out);
free(buffer);
}
if ( remainder )
{
buffer = (int* ) malloc (remainder); // 动态分配缓冲区 10 M
fread (buffer, 1, remainder, in); // 把文件读入缓冲区
fwrite (buffer, 1, remainder, out);
free(buffer);
}
}
/////////////// 显示结果 //////////////
fseek (out, 0, SEEK_END); // 文件指针到文件尾
ObjectSize=ftell (out); // 读取该位置,即文件大小
rewind (out); // 让文件指针重新回到文件开始

kilobyte = SourceSize / 1024;
millionbyte = SourceSize / ( 1024 * 1204 );
printf("SourceSize %d byte -> kilobyte %d K -> millionbyte %d M\n",
SourceSize,kilobyte,millionbyte);

kilobyte = SourceSize / 1024;
millionbyte = SourceSize / ( 1024 * 1204 );
printf("ObjectSize %d byte -> kilobyte %d K -> millionbyte %d M\n",
ObjectSize,kilobyte,millionbyte);
//////////////////
free(buffer);
fclose(in);
fclose(out);
}
...全文
116 11 打赏 收藏 转发到动态 举报
写回复
用AI写文章
11 条回复
切换为时间正序
请发表友善的回复…
发表回复
TianGuangZao 2003-10-17
  • 打赏
  • 举报
回复
我稍微整理了一下 MPU(黑眼圈) 大大写的,应该还有不少问题,大家再帮忙完善一下:
/* 程序名称: mycopy.c
* 使用说明: 本程序复制相同目录下的文件。
* 方法一:
* Enter the infile name:
* a.rar - 源文件
* Enter the outfile name:
* c.rar -目标文件
* 方法二: mycopy a.rar c.rar
*/

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

/* #include <conio.h> 这是 borland 库, 不通用 */

#define MAX_FILE_NAME 100
#define BUFSIZE 1024*1024*10 /* 默认10M,自行修改 */

int main(int argc, char *argv[])
{
/*-------------- 输入控制部分 -----------------------------*/

FILE *in, *out;

unsigned long iReturn;

char infile[MAX_FILE_NAME], outfile[MAX_FILE_NAME];

const int iReadSize = BUFSIZE;

unsigned long SourceSize = 0L, ObjectSize = 0L;

unsigned long kiloByte, megaByte;

clock_t startTime, endTime;

double duration;

char *program_name = argv[0];

/*--------------- 输入向导部分 ---------------------------*/

/* argv[2] source , argv[3] object */

if ( argc == 1 )
{
printf("Enter the infile name:\n");
scanf("%s", infile);
printf("Enter the outfile name:\n");
scanf("%s", outfile);

if ( (in = fopen(infile, "rb")) == NULL )
{
fprintf(stderr, "%s: Can't open source!%s\n", program_name, infile);
exit(1);
}

if ( (out = fopen(outfile,"wb")) == NULL )
{
fprintf(stderr, "%s: Can't open object!%s\n",program_name, outfile);
exit(1);
}
}

/*-------------- 直接输入部分, 如: mycopy a.rar c.rar -----*/

else if ( argc == 3 )
{
if ( (in = fopen( argv[1], "rb")) == NULL )
{
fprintf(stderr, "%s: Can't open source!%s\n",program_name, *argv);
exit(1);
}
if ( (out = fopen( argv[2], "wb")) == NULL )
{
fprintf(stderr, "%s: Can't open object!%s\n",program_name, *argv);
exit(1);
}
}
else
{
fprintf(stderr, "%s: Error!!!%s\n",program_name);
exit(1);
}

if (ferror(stdout))
{
fprintf(stderr, "%s: error writing stdout\n", program_name);
exit(1);
}

/*------------------- 计时器 ------------------------------*/
startTime = clock();

/*------------------- 处理文件复制部分 ------------------ */

fseek (in, 0, SEEK_END); /* 文件指针到文件尾 */
SourceSize = ftell (in); /* 读取该位置,即文件大小 */
rewind (in); /* 让文件指针重新回到文件开始 */

if ( SourceSize >= 1024*1024*1024L ) /* >= 4G exit(1) */
{
printf("This is file too bigger!");
exit(2);
}
else
{
char *byBuffer = (char *) malloc(BUFSIZE);
if ( byBuffer == NULL)
{
printf("Memory overflow!\n");
exit(3);
}
while ( !feof(in) )
{
iReturn = fread (byBuffer, 1, iReadSize, in);
if ( ferror(in) )
{
printf("Error Reading from file!\n");
exit(4);
}

fwrite (byBuffer, 1, iReturn, out);
if ( ferror(out) )
{
printf ("Error Writing to file!\n");
exit(4);
}
}
free( byBuffer);
}

/*-------------- 显示结果部分 -----------------------------*/

fseek( out, 0, SEEK_END);
ObjectSize = ftell (out);

kiloByte = SourceSize / 1024;
megaByte = SourceSize / ( 1024 * 1024 );
printf("SourceSize %d byte -> kilobyte %d K -> megabyte %d M\n",
SourceSize, kiloByte, megaByte);

kiloByte = SourceSize / 1024;
megaByte = SourceSize / ( 1024 * 1024 );
printf("ObjectSize %d byte -> kilobyte %d K -> megabyte %d M\n",
ObjectSize, kiloByte, megaByte);

fclose(in);
fclose(out);

/*----------------- 计时结束 ------------------------------*/
endTime = clock();
duration = (double)( endTime - startTime) / CLOCKS_PER_SEC;

printf("Copy duration : %f\n", duration);
/*---------------------------------------------------------*/

return 0;
CsdnPlayer 2003-10-16
  • 打赏
  • 举报
回复
while ( !feof(in) )
{
iReturn = fread (byBuffer, sizeof(char), iReadSize, in); // 把文件读入缓冲区
fwrite (byBuffer, sizeof(char), iReturn, out);
}
这样,每次缓冲区放入1024字节,如果源文件的大小不是1024字节的整数倍,怎么办?
MPU 2003-10-16
  • 打赏
  • 举报
回复
改了一下:

/////////////////只在相同目录下复制///////////
/////////////////如下使用/////////////////////
//Enter the infile name:
//a.rar //源文件
//Enter the outfile name:
//c.rar //目标文件

/////////////////或者///////////////
//mycopy a.rar c.rar

/*
我对小于10 M的文件直接分配内存复制,大于10 M的反复分配10 M内存复制.
*/

// VC++ 6 编译通过 -> cl mycopy.c
#include <stdio.h>
#include <conio.h>
#include <stdlib.h>
#include <time.h>

void main(int argc, char *argv[])
{//////////////////////// 输入控制 //////////////////////
FILE *in,*out;
unsigned long iReturn;
char infile[100],outfile[100];
const int iReadSize = 1024;
unsigned char byBuffer[1024];
unsigned long SourceSize = 0,ObjectSize = 0;
unsigned long kilobyte,millionbyte;
clock_t startTime, endTime;
double duration;

char *prog = argv[0]; /* program name for errors */

// argv[2] source , argv[3] object
if ( argc == 1 ) //向导输入
{
printf("Enter the infile name:\n");
scanf("%s",infile);
printf("Enter the outfile name:\n");
scanf("%s",outfile);
if ( (in = fopen(infile,"rb")) == NULL )
{
fprintf(stderr, "%s: Can't open source!%s\n",prog, infile);
exit(1);
}
if ( (out = fopen(outfile,"wb")) == NULL )
{
fprintf(stderr, "%s: Can't open source!%s\n",prog, outfile);
exit(1);
}
}
else if ( argc == 3 ) //直接输入 如: mycopy a.rar c.rar
{
if ( (in = fopen(*++argv, "rb")) == NULL )
{
fprintf(stderr, "%s: Can't open source!%s\n",prog, *argv);
exit(1);
}
if ( (out = fopen(*++argv,"wb")) == NULL )
{
fprintf(stderr, "%s: Can't open object!%s\n",prog, *argv);
exit(1);
}
}
else
{
fprintf(stderr, "%s: Error!!!%s\n",prog);
exit(1);
}

if (ferror(stdout))
{
fprintf(stderr, "%s: error writing stdout\n", prog);
exit(1);
}
////////////////////////////////////
startTime = clock();
////////////////// 处理文件复制 /////////////////////
fseek (in, 0, SEEK_END); // 文件指针到文件尾
SourceSize=ftell (in); // 读取该位置,即文件大小
rewind (in); // 让文件指针重新回到文件开始

if ( SourceSize >= 4294967295 ) // >= 4G exit(1)
{
printf("This is file too bigger!");
exit(0);
}
else
{
while ( !feof(in) )
{
iReturn = fread (byBuffer, sizeof(char), iReadSize, in); // 把文件读入缓冲区
fwrite (byBuffer, sizeof(char), iReturn, out);
}
}
/////////////// 显示结果 //////////////
fseek (out, 0, SEEK_END); // 文件指针到文件尾
ObjectSize=ftell (out); // 读取该位置,即文件大小
rewind (out); // 让文件指针重新回到文件开始

kilobyte = SourceSize / 1024;
millionbyte = SourceSize / ( 1024 * 1024 );
printf("SourceSize %d byte -> kilobyte %d K -> millionbyte %d M\n",
SourceSize,kilobyte,millionbyte);

kilobyte = SourceSize / 1024;
millionbyte = SourceSize / ( 1024 * 1024 );
printf("ObjectSize %d byte -> kilobyte %d K -> millionbyte %d M\n",
ObjectSize,kilobyte,millionbyte);
//////////////////
fclose(in);
fclose(out);
//////////////////////////////
endTime = clock();
duration = (double)(endTime-startTime)/CLOCKS_PER_SEC;

printf("%f\n", duration);
}
xdspower 2003-10-16
  • 打赏
  • 举报
回复
C标准库中好像有文件复制的函数呀,好像是什么dup????
Wolf0403 2003-10-16
  • 打赏
  • 举报
回复
两个版本,buffered 和 unbuffered。感觉比楼主代码清楚点儿,参考吧。
#include <stdio.h>

long FileCpy(const char * dest, const char * src);
long BufFileCpy(const char * dest, const char * src, unsigned buflen);

int main(int argc, char ** argv)
{
int count;
if (3 == argc)
{
count = BufFileCpy(argv[2], argv[1], 1024);
switch (count)
{
case -2:
printf("Open source file failed\n");
return 0;
case -3:
printf("Write dest file failed\n");
return 0;
case -4:
printf("Memory problem\n");
return 0;
default:
printf("Total %d bytes copied.\n", count);
}
}
}

long FileCpy(const char * dest, const char * src)
{
FILE * infile, * outfile;
int ch = 0;
long count = 0;
if (!(infile = fopen(src, "r")))
return -2;
if (!(outfile = fopen(dest, "w")))
return -3;
while (EOF != (ch = fgetc(infile)))
{
fputc(ch, outfile);
count++;
}
return count;
}

long BufFileCpy(const char * dest, const char * src, unsigned buflen)
{
FILE * infile, * outfile;
void * buf = 0;
long count = 0, curr_read = 0;
if (!(infile = fopen(src, "r")))
return -2;
if (!(outfile = fopen(dest, "w")))
return -3;
buf = (char *)calloc(buflen, sizeof(char));
if (!buf)
return -4;
while (curr_read = fread(buf, sizeof(char), buflen, infile))
{
fwrite(buf, sizeof(char), buflen, outfile);
count += curr_read;
if (curr_read < buflen)
break;
}
return count;
}
CsdnPlayer 2003-10-16
  • 打赏
  • 举报
回复
to MPU(黑眼圈):
Thanks!
roselu 2003-10-16
  • 打赏
  • 举报
回复
学习!
MPU 2003-10-16
  • 打赏
  • 举报
回复
int fread (void * buffer, size_t size, size_t count, FILE * stream);

Return Value.
The total number of items readed is returned.
If this number differs from the requested amount (count parameter) an error has occured or End Of File has been reached. To determine what happened call feof or ferror.

你编译试一下就知道了,它是每次读1024个字节,读了多少返回多少....
sevencat 2003-10-15
  • 打赏
  • 举报
回复
在WIN下面可以用完成端口来写文件复制程序,有本书上有的,
MPU 2003-10-15
  • 打赏
  • 举报
回复
1024 * 1204 是个错误 ,应该 1024 byte * 1024 = 1 M

它为了算出复制和原文件的大小是不是一样,不太重要.

我没在 TC2 下试过.我用的 unsigned long 在 VC6 中最大4294967295 byte

== 4G
谢谢!

fwinfwin 2003-10-15
  • 打赏
  • 举报
回复
多分点函数吧大哥,这样看好累的!
10485760这样大的数最好加个L,不然dos下是个负的!
1024*1204也是负的,不过为什么是1204不懂!

69,364

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧