工大后院

 找回密码
 加入后院

扫一扫,访问微社区

QQ登录

只需一步,快速开始

搜索
查看: 3282|回复: 14

用C++写一个COPY命令

[复制链接]
发表于 2005-11-27 00:07 | 显示全部楼层 |阅读模式
好久没上工大后院了,最近看了看C++的书,又在此浏览了不少有关C的贴子,就想起自己写的一个小程序.所以贴出来,顺便给初学者参考参考.

会DOS的人对COPY这个复制文件的命令一定不陌生,我用C++写了个相似的程序.
先贴出代码:

/*
************************************
仿制DOS下COPY命令的程序
************************************
*/
#include<fstream>
#include<iostream>
#include<cstdlib>
using namespace std;
void print_error(const char*,const char* =" ");         //出错时的函数
bool equals(char *,char *);                                    //比较字符串是否相等
char lastIndex(char *);                                         //取得字符串的最后字符
int main(int argc,char *argv[]){
                const int LEN=1024;                           
        char ch[LEN];                                     //使用数组缓存
        if(3!=argc)print_error("usage:cp source dest");   //输入参数提示
        if(equals(argv[1],argv[2]))print_error("usage:the source can't be the dest");                   //防止复制源文件与目标文件相同
        ifstream in(argv[1],ios::binary);          //将文件作二进制处理
        if(!in)
        print_error("Can't open",argv[1]);
        if(lastIndex(argv[2])=='\\'||lastIndex(argv[2])=='/'||lastIndex(argv[2])==':')         //这个是为了目标输入处理如:"C:"或"C:\"
        {
       char *filename;                                                                           
       if(lastIndex(argv[2])==':'){
                char *ff=argv[2];
                char *f=strcat(ff,"\\");         //用strcat连接字符串成完整文件名
                filename=strcat(f,argv[1]);
                }
      else                                                                                                                                                         
       filename=strcat(argv[2],argv[1]);
       ofstream out(filename,ios::binary);
       if(!out)
           print_error("Can't open ",filename);
       while(in.read(ch,LEN))out.write(ch,LEN);//这个一边读一边写,看上去很自然,但我认为关键在下面的处理
           char *s=ch;
           int ii=in.gcount();           //in.gcount()取得最后一次读的字节数
           int i=0;
           for(;i<ii;i++)out.put(s);//用put函数一个一个写入
           if(!in.eof())
           print_error("something wrong!");
           cout<<"成功复制了一个文件: "<<filename<<endl;
    }
    else
    {
           ofstream out(argv[2],ios::binary);
           if(!out)
           print_error("Can't open ",argv[2]);
           while(in.read(ch,LEN))out.write(ch,LEN);
           int ii=in.gcount();
       char *s=ch;
      
       int i=0;
       for(;i<ii;i++)out.put(s);
           if(!in.eof())
           print_error("something wrong!");
           cout<<"成功复制了一个文件: "<<argv[2]<<endl;
    }
       
        return 0;
        }

void print_error(const char*p,const char *p2){
        cerr<<p<<' '<<p2<<'\n';
        exit(1);
        }

bool equals(char *a,char *b)
{
    if(strcmp(a,b)==0)return 1;
        return 0;
}       

char lastIndex(char *a)
{
     return a[strlen(a)-1];
}


刚开始时,我只写了 while(in.read(ch,LEN))out.write(ch,LEN); 以为就可以了.其实最后一次读的字节并无写入,才有了下面的处理.
我试过这样处理:
while(in.read(ch,LEN))out.write(ch,LEN);
char* p=ch;
for(int i=0;*p!='\0';p++)out.put(p);
开始测试没问题,后来发现有时文本文件后面会出现一两个不正常字符.
当我发现有gcount()这个方法,高兴到不得了.解决了一切问题.我试过复制1K和1G的文件,很正常,包括速度和质量.

如果只用put,get就不用想这么多了,只是速度方面不好,读一个写一个是最没办法的办法啦!
发表于 2005-11-27 00:17 | 显示全部楼层
不错。支持一下!
回复

使用道具 举报

发表于 2005-11-27 00:26 | 显示全部楼层
得闲写个format嚟睇下。
回复

使用道具 举报

发表于 2005-11-27 00:48 | 显示全部楼层
及时雨...感谢楼主...偶正在努力学习C++中...
回复

使用道具 举报

发表于 2005-11-27 01:35 | 显示全部楼层
Originally posted by Faust at 2005-11-27 12:26 AM:
得闲写个format嚟睇下。


等待你的大作
回复

使用道具 举报

 楼主| 发表于 2005-11-27 21:57 | 显示全部楼层
//format命令就留给高手写啦.
//改一个可变成type命令

#include<fstream>
#include<iostream>
#include<cstdlib>
using namespace std;
void print_error(const char*,const char* =\" \");
int main(int argc,char *argv[]){
    const int LEN=256;
        char ch[LEN];
        if(2!=argc)print_error(\"usage:cat source \");
        fstream in(argv[1],ios::in);
        if(!in)
        print_error(\"Can\'t open\",argv[1]);
        while(in.getline(ch,LEN))
    {
          cout<<ch<<endl;
    }
       
        if(!in.eof())
        print_error(\"something wrong,mybe the source file is not text file!\");
        return 0;
        }

void print_error(const char*p,const char *p2)
{
        cerr<<p<<\' \'<<p2<<\'\\n\';
        exit(1);
}

谁有兴趣把其它的命令写完或完善?!
回复

使用道具 举报

发表于 2005-12-6 00:57 | 显示全部楼层
for(int i=0;*p!=\'\\0\';p++)out.put(p);
开始测试没问题,后来发现有时文本文件后面会出现一两个不正常字符.

介个素为虾米捏?
回复

使用道具 举报

 楼主| 发表于 2005-12-13 00:38 | 显示全部楼层

  1. #include<fstream>
  2. #include<iostream>
  3. #include<cstdlib>
  4. #include<string>
  5. using namespace std;

  6. void print_error(const char*a,const char* b=" ");
  7. bool equals(string a,string b);
  8. char lastChar(string s);
  9. int main(int argc,char *argv[]){
  10.         if(3!=argc)print_error("usage:cp source dest");
  11.         string src(argv[1]); string dest(argv[2]);
  12.                 const int LEN=1024;
  13.                 char ch[LEN];       long end;
  14.         if(equals(src,dest))print_error("usage:the source can\'t be the dest");
  15.         ifstream in(src.c_str(),ios::binary|ios::ate);
  16.         end=in.tellg();
  17.         in.seekg(0,ios::beg);
  18.         if(!in)
  19.         print_error("Can\'t open",dest.c_str());
  20.        
  21.         if(lastChar(dest)==\'\\\\\'||lastChar(dest)==\'/\'||lastChar(dest)==\':\')
  22.         {
  23.        string filename;   
  24.        string name;                                                                        
  25.        if (lastChar(dest)==\':\')
  26.        {
  27.           filename=dest;
  28.           filename.append("\\\\");
  29.           filename.append(src);
  30.        }else filename=strcat(argv[2],argv[1]);
  31.       
  32.        const char* p=filename.c_str();
  33.        ofstream out(p,ios::binary);
  34.        if(!out)
  35.            print_error("Can\'t open the file:",filename.c_str());
  36.        while(in.read(ch,LEN))out.write(ch,LEN);
  37.            char *s=ch;
  38.            int ii=in.gcount();
  39.            int i=0;
  40.            for(;i<ii;i++)out.put(s[i]);
  41.            if(!in.eof())
  42.            print_error("something wrong!");
  43.            cout<<"成功复制了文件: "<<filename<<" "<<end<<" bytes."<<endl;
  44.            in.close();
  45.            out.close();
  46.     }
  47.     else
  48.     {
  49.            ofstream out(argv[2],ios::binary);
  50.            if(!out)
  51.            print_error("Can\'t open ",dest.c_str());
  52.            while(in.read(ch,LEN))out.write(ch,LEN);
  53.            int len=in.gcount();
  54.        char *s=ch;
  55.        for(int i=0;i<len;i++)out.put(s[i]);
  56.            if(!in.eof())
  57.            print_error("something wrong!");
  58.            cout<<"成功复制了文件:"<<argv[2]<<" "<<end<<" bytes."<<endl;
  59.            in.close();
  60.            out.close();
  61.     }
  62.        
  63.         return 0;
  64.         }

  65. bool equals(string str1,string str2)
  66. {
  67.       transform(str1.begin(),str1.end(),str1.begin(),(int(*)(int))tolower);
  68.       transform(str2.begin(),str2.end(),str2.begin(),(int(*)(int))tolower);
  69.       if(str1==str2)return true;
  70.       return false;
  71. }
  72. void print_error(const char* a,const char* b){
  73.         cerr<<a<<" "<<b<<endl;
  74.         exit(1);
  75.         }
  76.        
  77. char lastChar(string s)
  78. {
  79.      string::iterator p;
  80.      p=s.end();
  81.      return *(p-1);
  82. }
复制代码

[ Last edited by powerwind on 2005-12-13 at 00:40 ]
回复

使用道具 举报

发表于 2005-12-26 11:40 | 显示全部楼层
晕啊怎么是C++的啊!,有没有高手写一个C的COPY命令啊!命令格式为filecopy filename1 filename2,小弟找了好多资料都没有啊,拜托高手写一个啊!谢谢!
回复

使用道具 举报

 楼主| 发表于 2006-1-6 12:34 | 显示全部楼层
对以上的程序稍作修改,可变成一个简单实用的文件加密/解密的程序.
对原文件加密时输入加密密码,生成一个已经是乱码的文件
解密时输入同一个密码则可解密,生成一个和原文件一样内容的文件,否则是再次加密.
当然,可以多次加密,然后反序解密,只要密码及顺序没错,应该可以还原的.


  1. /*encode.cpp*/
  2. //通过简单的异或对文件加密/解密
  3. #include<fstream>
  4. #include<iostream>
  5. #include<cstdlib>
  6. #include<string>
  7. using namespace std;

  8. void print_error(const char*a,const char* b=" ");
  9. bool equals(string a,string b);
  10. char lastChar(string s);
  11. int main(int argc,char *argv[]){
  12.         if(3!=argc)print_error("usage:encode source dest");
  13.         
  14.         string src(argv[1]); string dest(argv[2]);
  15.         const int LEN=1024; long end;
  16.         char ch[LEN];        int seed=0;
  17.         
  18.         if(equals(src,dest))print_error("usage:the source can\'t be the dest");
  19.         ifstream in(src.c_str(),ios::binary|ios::ate);
  20.         end=in.tellg();
  21.         in.seekg(0,ios::beg);
  22.         if(!in)
  23.         print_error("Can\'t open",dest.c_str());
  24.         
  25.         if(lastChar(dest)==\'\\\\\'||lastChar(dest)==\'/\'||lastChar(dest)==\':\')
  26.         {
  27.        string filename;   
  28.        string name;                                                                        
  29.        if (lastChar(dest)==\':\')
  30.        {
  31.           filename=dest;
  32.           filename.append("\\\\");
  33.           filename.append(src);
  34.        }else filename=strcat(argv[2],argv[1]);
  35.       
  36.        const char* p=filename.c_str();
  37.        ofstream out(p,ios::binary);
  38.        if(!out)print_error("Can\'t open the file:",filename.c_str());
  39.        cout<<"请输入加密/解密的密钥(整数如123)"<<endl;cin>>seed;
  40.        while (in.read(ch,LEN))
  41.        {
  42.            for(int i=0;i<in.gcount();i++)ch[i]=ch[i]^seed;
  43.            out.write(ch,LEN);
  44.        }
  45.        char *s=ch;
  46.        int ii=in.gcount();
  47.        for(int i=0;i<ii;i++){ch[i]=ch[i]^seed;out.put(s[i]);}
  48.        if(!in.eof())
  49.        print_error("something wrong!");
  50.        cout<<"成功保存了文件: "<<filename<<" "<<end<<" bytes."<<endl;
  51.        in.close();
  52.        out.close();
  53.        }
  54.        else
  55.        {
  56.        ofstream out(argv[2],ios::binary);
  57.        if(!out)print_error("Can\'t open ",dest.c_str());
  58.        cout<<"请输入加密/解密的密钥(整数如123)"<<endl;cin>>seed;
  59.        while (in.read(ch,LEN))
  60.              {
  61.                for(int i=0;i<in.gcount();i++)ch[i]=ch[i]^seed;
  62.                out.write(ch,LEN);
  63.              }
  64.        int len=in.gcount();
  65.        char *s=ch;
  66.        for(int i=0;i<len;i++){ch[i]=ch[i]^seed;out.put(s[i]);}
  67.        if(!in.eof())
  68.        print_error("something wrong!");
  69.        cout<<"成功保存了文件:"<<argv[2]<<" "<<end<<" bytes."<<endl;
  70.        in.close();
  71.        out.close();
  72.     }
  73.         
  74.         return 0;
  75.         }

  76. bool equals(string str1,string str2)
  77. {
  78.       transform(str1.begin(),str1.end(),str1.begin(),(int(*)(int))tolower);
  79.       transform(str2.begin(),str2.end(),str2.begin(),(int(*)(int))tolower);
  80.       if(str1==str2)return true;
  81.       return false;
  82. }
  83. void print_error(const char* a,const char* b){
  84.         cerr<<a<<" "<<b<<endl;
  85.         exit(1);
  86.         }
  87.         
  88. char lastChar(string s)
  89. {
  90.      string::iterator p;
  91.      p=s.end();
  92.      return *(p-1);
  93. }
复制代码
回复

使用道具 举报

头像被屏蔽
发表于 2006-11-8 01:33 | 显示全部楼层
提示: 作者被禁止或删除 内容自动屏蔽
回复

使用道具 举报

发表于 2006-11-12 16:07 | 显示全部楼层
刚刚看到!楼主还可以,向你学习!
回复

使用道具 举报

 楼主| 发表于 2006-11-12 16:36 | 显示全部楼层
论坛搬家后,源代码的格式已经乱了。而我的电脑里仍保存有cp.cpp,重新贴出来。


  1. #include<fstream>
  2. #include<iostream>
  3. #include<cstdlib>
  4. #include<string>
  5. using namespace std;

  6. void print_error(const char*a,const char* b=" ");
  7. bool equals(string a,string b);
  8. char lastIndex(string s);
  9. int main(int argc,char *argv[]){
  10.         if(3!=argc)print_error("usage:cp source dest");
  11.         string src(argv[1]); string dest(argv[2]);
  12.     long end; const int LEN=1024; char ch[LEN];
  13.         if(equals(src,dest))print_error("usage:the source can't be the dest");
  14.         ifstream in(src.c_str(),ios::binary|ios::ate);
  15.         end=in.tellg();
  16.         in.seekg(0,ios::beg);
  17.         if(!in)
  18.         print_error("Can't open",dest.c_str());
  19.        
  20.         if(lastIndex(dest)=='\\'||lastIndex(dest)=='/'||lastIndex(dest)==':')
  21.         {
  22.        string filename;   
  23.        string name;                                                                        
  24.        if (lastIndex(dest)==':')
  25.        {
  26.           filename=dest;
  27.           filename.append("\");
  28.           filename.append(src);
  29.        }else filename=strcat(argv[2],argv[1]);
  30.       
  31.        const char* p=filename.c_str();
  32.        ofstream out(p,ios::binary);
  33.        if(!out)
  34.            print_error("Can't open the file:",filename.c_str());
  35.        while(in.read(ch,LEN))out.write(ch,LEN);
  36.            char *s=ch;
  37.            int ii=in.gcount();
  38.            int i=0;
  39.            for(;i<ii;i++)out.put(s[i]);
  40.            if(!in.eof())
  41.            print_error("something wrong!");
  42.            cout<<"成功复制了文件: "<<filename<<" "<<end<<" bytes."<<endl;
  43.            in.close();
  44.            out.close();
  45.     }
  46.     else
  47.     {
  48.            ofstream out(argv[2],ios::binary);
  49.            if(!out)
  50.            print_error("Can't open ",dest.c_str());
  51.            while(in.read(ch,LEN))out.write(ch,LEN);
  52.            int len=in.gcount();
  53.        char *s=ch;
  54.        for(int i=0;i<len;i++)out.put(s[i]);
  55.            if(!in.eof())
  56.            print_error("something wrong!");
  57.            cout<<"成功复制了文件:"<<argv[2]<<" "<<end<<" bytes."<<endl;
  58.            in.close();
  59.            out.close();
  60.     }
  61.        
  62.         return 0;
  63.         }
  64. bool equals(string str1,string str2)
  65. {
  66.       transform(str1.begin(),str1.end(),str1.begin(),(int(*)(int))tolower);
  67.       transform(str2.begin(),str2.end(),str2.begin(),(int(*)(int))tolower);
  68.       if(str1==str2)return true;
  69.       return false;
  70. }
  71. void print_error(const char* a,const char* b){
  72.         cerr<<a<<" "<<b<<endl;
  73.         exit(1);
  74.         }
  75.        
  76. char lastIndex(string s)
  77. {
  78.      string::iterator p;
  79.      p=s.end();
  80.      return *(p-1);
  81. }
复制代码
回复

使用道具 举报

头像被屏蔽
发表于 2006-11-24 19:32 | 显示全部楼层
提示: 作者被禁止或删除 内容自动屏蔽
回复

使用道具 举报

发表于 2006-11-24 19:46 | 显示全部楼层
这里就是很好的讨论环境啦!
欢迎 kongdj 常来这里交流
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 加入后院

本版积分规则

QQ|Archiver|手机版|小黑屋|广告业务Q|工大后院 ( 粤ICP备10013660号 )

GMT+8, 2025-8-31 08:02

Powered by Discuz! X3.5

Copyright © 2001-2024 Tencent Cloud.

快速回复 返回顶部 返回列表