powerwind 发表于 2005-11-27 00:07

用C++写一个COPY命令

好久没上工大后院了,最近看了看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;                                     //使用数组缓存
        if(3!=argc)print_error("usage:cp source dest");   //输入参数提示
        if(equals(argv,argv))print_error("usage:the source can't be the dest");                   //防止复制源文件与目标文件相同
        ifstream in(argv,ios::binary);          //将文件作二进制处理
        if(!in)
        print_error("Can't open",argv);
        if(lastIndex(argv)=='\\'||lastIndex(argv)=='/'||lastIndex(argv)==':')         //这个是为了目标输入处理如:"C:"或"C:\"
        {
       char *filename;                                                                           
       if(lastIndex(argv)==':'){
                char *ff=argv;
                char *f=strcat(ff,"\\");         //用strcat连接字符串成完整文件名
                filename=strcat(f,argv);
                }
      else                                                                                                                                                         
       filename=strcat(argv,argv);
       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,ios::binary);
           if(!out)
           print_error("Can't open ",argv);
           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<<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;
}


刚开始时,我只写了 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

不错。支持一下!

Faust 发表于 2005-11-27 00:26

得闲写个format嚟睇下。

wool王 发表于 2005-11-27 00:48

及时雨...感谢楼主...偶正在努力学习C++中...

jackvenn 发表于 2005-11-27 01:35

Originally posted by Faust at 2005-11-27 12:26 AM:
得闲写个format嚟睇下。

等待你的大作

powerwind 发表于 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;
        if(2!=argc)print_error(\"usage:cat source \");
        fstream in(argv,ios::in);
        if(!in)
        print_error(\"Can\'t open\",argv);
        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);
开始测试没问题,后来发现有时文本文件后面会出现一两个不正常字符.

介个素为虾米捏?

powerwind 发表于 2005-12-13 00:38


#include<fstream>
#include<iostream>
#include<cstdlib>
#include<string>
using namespace std;

void print_error(const char*a,const char* b=\" \");
bool equals(string a,string b);
char lastChar(string s);
int main(int argc,char *argv[]){
        if(3!=argc)print_error(\"usage:cp source dest\");
        string src(argv); string dest(argv);
                const int LEN=1024;
                char ch;       long end;
        if(equals(src,dest))print_error(\"usage:the source can\'t be the dest\");
        ifstream in(src.c_str(),ios::binary|ios::ate);
        end=in.tellg();
        in.seekg(0,ios::beg);
        if(!in)
        print_error(\"Can\'t open\",dest.c_str());
       
        if(lastChar(dest)==\'\\\\\'||lastChar(dest)==\'/\'||lastChar(dest)==\':\')
        {
       string filename;   
       string name;                                                                        
       if (lastChar(dest)==\':\')
       {
          filename=dest;
          filename.append(\"\\\\\");
          filename.append(src);
       }else filename=strcat(argv,argv);
      
       const char* p=filename.c_str();
       ofstream out(p,ios::binary);
       if(!out)
           print_error(\"Can\'t open the file:\",filename.c_str());
       while(in.read(ch,LEN))out.write(ch,LEN);
           char *s=ch;
           int ii=in.gcount();
           int i=0;
           for(;i<ii;i++)out.put(s);
           if(!in.eof())
           print_error(\"something wrong!\");
           cout<<\"成功复制了文件: \"<<filename<<\" \"<<end<<\" bytes.\"<<endl;
           in.close();
           out.close();
    }
    else
    {
           ofstream out(argv,ios::binary);
           if(!out)
           print_error(\"Can\'t open \",dest.c_str());
           while(in.read(ch,LEN))out.write(ch,LEN);
           int len=in.gcount();
       char *s=ch;
       for(int i=0;i<len;i++)out.put(s);
           if(!in.eof())
           print_error(\"something wrong!\");
           cout<<\"成功复制了文件:\"<<argv<<\" \"<<end<<\" bytes.\"<<endl;
           in.close();
           out.close();
    }
       
        return 0;
        }

bool equals(string str1,string str2)
{
      transform(str1.begin(),str1.end(),str1.begin(),(int(*)(int))tolower);
      transform(str2.begin(),str2.end(),str2.begin(),(int(*)(int))tolower);
      if(str1==str2)return true;
      return false;
}
void print_error(const char* a,const char* b){
        cerr<<a<<\" \"<<b<<endl;
        exit(1);
        }
       
char lastChar(string s)
{
   string::iterator p;
   p=s.end();
   return *(p-1);
}


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

superkamiu 发表于 2005-12-26 11:40

晕啊怎么是C++的啊!,有没有高手写一个C的COPY命令啊!命令格式为filecopy filename1 filename2,小弟找了好多资料都没有啊,拜托高手写一个啊!谢谢!

powerwind 发表于 2006-1-6 12:34

对以上的程序稍作修改,可变成一个简单实用的文件加密/解密的程序.
对原文件加密时输入加密密码,生成一个已经是乱码的文件
解密时输入同一个密码则可解密,生成一个和原文件一样内容的文件,否则是再次加密.
当然,可以多次加密,然后反序解密,只要密码及顺序没错,应该可以还原的.


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

void print_error(const char*a,const char* b=\" \");
bool equals(string a,string b);
char lastChar(string s);
int main(int argc,char *argv[]){
      if(3!=argc)print_error(\"usage:encode source dest\");
      
      string src(argv); string dest(argv);
      const int LEN=1024; long end;
      char ch;      int seed=0;
      
      if(equals(src,dest))print_error(\"usage:the source can\'t be the dest\");
      ifstream in(src.c_str(),ios::binary|ios::ate);
      end=in.tellg();
      in.seekg(0,ios::beg);
      if(!in)
      print_error(\"Can\'t open\",dest.c_str());
      
      if(lastChar(dest)==\'\\\\\'||lastChar(dest)==\'/\'||lastChar(dest)==\':\')
      {
       string filename;   
       string name;                                                                        
       if (lastChar(dest)==\':\')
       {
          filename=dest;
          filename.append(\"\\\\\");
          filename.append(src);
       }else filename=strcat(argv,argv);
      
       const char* p=filename.c_str();
       ofstream out(p,ios::binary);
       if(!out)print_error(\"Can\'t open the file:\",filename.c_str());
       cout<<\"请输入加密/解密的密钥(整数如123)\"<<endl;cin>>seed;
       while (in.read(ch,LEN))
       {
         for(int i=0;i<in.gcount();i++)ch=ch^seed;
         out.write(ch,LEN);
       }
       char *s=ch;
       int ii=in.gcount();
       for(int i=0;i<ii;i++){ch=ch^seed;out.put(s);}
       if(!in.eof())
       print_error(\"something wrong!\");
       cout<<\"成功保存了文件: \"<<filename<<\" \"<<end<<\" bytes.\"<<endl;
       in.close();
       out.close();
       }
       else
       {
       ofstream out(argv,ios::binary);
       if(!out)print_error(\"Can\'t open \",dest.c_str());
       cout<<\"请输入加密/解密的密钥(整数如123)\"<<endl;cin>>seed;
       while (in.read(ch,LEN))
             {
               for(int i=0;i<in.gcount();i++)ch=ch^seed;
               out.write(ch,LEN);
             }
       int len=in.gcount();
       char *s=ch;
       for(int i=0;i<len;i++){ch=ch^seed;out.put(s);}
       if(!in.eof())
       print_error(\"something wrong!\");
       cout<<\"成功保存了文件:\"<<argv<<\" \"<<end<<\" bytes.\"<<endl;
       in.close();
       out.close();
    }
      
      return 0;
      }

bool equals(string str1,string str2)
{
      transform(str1.begin(),str1.end(),str1.begin(),(int(*)(int))tolower);
      transform(str2.begin(),str2.end(),str2.begin(),(int(*)(int))tolower);
      if(str1==str2)return true;
      return false;
}
void print_error(const char* a,const char* b){
      cerr<<a<<\" \"<<b<<endl;
      exit(1);
      }
      
char lastChar(string s)
{
   string::iterator p;
   p=s.end();
   return *(p-1);
}

sjk_chdh 发表于 2006-11-8 01:33

henrybbs 发表于 2006-11-12 16:07

刚刚看到!楼主还可以,向你学习!

powerwind 发表于 2006-11-12 16:36

论坛搬家后,源代码的格式已经乱了。而我的电脑里仍保存有cp.cpp,重新贴出来。


#include<fstream>
#include<iostream>
#include<cstdlib>
#include<string>
using namespace std;

void print_error(const char*a,const char* b=" ");
bool equals(string a,string b);
char lastIndex(string s);
int main(int argc,char *argv[]){
        if(3!=argc)print_error("usage:cp source dest");
        string src(argv); string dest(argv);
    long end; const int LEN=1024; char ch;
        if(equals(src,dest))print_error("usage:the source can't be the dest");
        ifstream in(src.c_str(),ios::binary|ios::ate);
        end=in.tellg();
        in.seekg(0,ios::beg);
        if(!in)
        print_error("Can't open",dest.c_str());
       
        if(lastIndex(dest)=='\\'||lastIndex(dest)=='/'||lastIndex(dest)==':')
        {
       string filename;   
       string name;                                                                        
       if (lastIndex(dest)==':')
       {
          filename=dest;
          filename.append("\\");
          filename.append(src);
       }else filename=strcat(argv,argv);
      
       const char* p=filename.c_str();
       ofstream out(p,ios::binary);
       if(!out)
           print_error("Can't open the file:",filename.c_str());
       while(in.read(ch,LEN))out.write(ch,LEN);
           char *s=ch;
           int ii=in.gcount();
           int i=0;
           for(;i<ii;i++)out.put(s);
           if(!in.eof())
           print_error("something wrong!");
           cout<<"成功复制了文件: "<<filename<<" "<<end<<" bytes."<<endl;
           in.close();
           out.close();
    }
    else
    {
           ofstream out(argv,ios::binary);
           if(!out)
           print_error("Can't open ",dest.c_str());
           while(in.read(ch,LEN))out.write(ch,LEN);
           int len=in.gcount();
       char *s=ch;
       for(int i=0;i<len;i++)out.put(s);
           if(!in.eof())
           print_error("something wrong!");
           cout<<"成功复制了文件:"<<argv<<" "<<end<<" bytes."<<endl;
           in.close();
           out.close();
    }
       
        return 0;
        }
bool equals(string str1,string str2)
{
      transform(str1.begin(),str1.end(),str1.begin(),(int(*)(int))tolower);
      transform(str2.begin(),str2.end(),str2.begin(),(int(*)(int))tolower);
      if(str1==str2)return true;
      return false;
}
void print_error(const char* a,const char* b){
        cerr<<a<<" "<<b<<endl;
        exit(1);
        }
       
char lastIndex(string s)
{
   string::iterator p;
   p=s.end();
   return *(p-1);
}

kongdj 发表于 2006-11-24 19:32

MJOfPowerwind 发表于 2006-11-24 19:46

这里就是很好的讨论环境啦!
欢迎 kongdj 常来这里交流
页: [1]
查看完整版本: 用C++写一个COPY命令