注册 登录
编程论坛 C语言论坛

新写了个复制粘贴的程序,还请大家看看还有没有什么不足

aCprogrammer 发布于 2019-07-04 17:23, 4552 次点击
#include<stdio.h>
#include<stdlib.h>
void string(char pp[]);//给被复制的文件的文件名进行去双引号的函数 1
void string_1(char vv[]);// 给被复制的文件的文件名进行去双引号的函数 2
char io[100],uu[100];//定义全局变量,保证数据离开被调函数后不会被销毁,用来存放经函数去掉引号后的字符串
int mm=0;



int main()
{
    FILE *fp,*f,*oj;
    char a[100],b[100],ch,aj[100];
   
   
    puts("PS1: the function of this program is to copy one\nspecified file into another specified fileand\nthen destroy the contents of the copied file!");
    puts("\n\n");
    printf("PS2: You can drag files directly in.\n");
    puts("\n\n");
    puts("PS3: You can only copy and paste documents of the same kind!");
    putchar('\n');
    putchar('\n');
    puts("Please enter a file name to copy:");
    gets(b);//输入原始的被复制文件的文件名
    string(b);//调用函数去掉被复制文件的文件名中可能出现的双引号
    putchar('\n');
    puts("Please enter the file name to be pasted:");
    gets(a);//输入原始的要粘贴文件的文件名
    string_1(a);//调用函数去掉要粘贴文件的文件名中可能出现的双引号
    putchar('\n');
    fp=fopen(uu,"ab+");//使用去掉双引号后的文件名打开要粘贴的文件
    if(!fp)
    {
        printf("Can not open the file %s",uu);
        system("pause");
        return 0;
    }
    f=fopen(io,"rb");//使用去掉双引号后的文件名打开被复制的文件
    if(!f)
    {
        printf("Can not open the file %s",io);
        system("pause");
        return 0;
    }
    while(!(feof(f)))
    {
        ch=fgetc(f);
        fputc(ch,fp);
    }
    fclose(fp);//关闭要粘贴的文件
    fclose(f);//关闭被复制的文件
    oj=fopen(io,"wb");//重新打开被复制的文件,并且把其中的数据删除
    if(!oj)
    {
        printf("Can not destroy files %s",b);
        return 0;
    }
    fclose(oj);
    puts("Done!\n");
    system("pause");
    return 0;
}



void string(char pp[])//去文件名中双引号的函数定义1
{
    int rr=0;
    while(pp[rr]!='\0')
    {
        if(pp[rr]!='"')
        {
            io[mm]=pp[rr];
            mm++;
        }
        rr++;
    }
}




void string_1(char vv[])//去文件名中双引号的函数定义2
{
    int o=0;
    int y=0;
    while(vv[o]!='\0')
    {
        if(vv[o]!='"')
        {
            uu[y]=vv[o];
            y++;
        }
        o++;
    }
}
23 回复
#2
rjsp2019-07-04 19:14
看到 while(!(feof(f))) 十有八九是错的
#3
aCprogrammer2019-07-04 20:07
回复 2楼 rjsp
有什么问题吗,编译的时候没给报错啊
#4
rjsp2019-07-05 09:43
以下是引用aCprogrammer在2019-7-4 20:07:18的发言:

有什么问题吗,编译的时候没给报错啊

错误太多,我帮你重写吧
程序代码:
#include <stdio.h>

FILE* open_file( const char* filemode )
{
    char filename[260]; // windows定义_MAX_PATH为260,linux定义PATH_MAX为4096,但都可以更大
    if( !fgets(filename,sizeof(filename)/sizeof(*filename),stdin) ) // 读入一行
    {
        puts( "输入失败." );
        return NULL;
    }

    // 去除双引号
    {
        char* q=filename;
        for( char* p=filename; *p; ++p )
            if( *p != '"' )
                *q++ = *p;
        if( q==filename || q[-1]!='\n' ) // filename空间容量不足
        {
            puts( "文件名过长." );
            return NULL;
        }
        q[-1] = '\0';
    }

    FILE* file = fopen( filename, filemode );
    if( !file )
        printf( "文件\"%s\"打开失败.\n", filename );
    return file;
}

int main( void )
{
    puts( "Please enter a file name to copy:" );
    FILE* src = open_file( "rb" ); // f
    if( !src )
        return 1;

    puts( "Please enter the file name to be pasted:" );
    FILE* dst = open_file( "ab+" ); // fp
    if( !dst )
    {
        fclose( src );
        return 2;
    }

    // 从你错误的 while(!(feof(f))) 改写而来。当然,一个一个字符的拷贝,运行效率就不谈了
    for( int ch; ch=fgetc(src), ch!=EOF; )
    {
        if( fputc(ch,dst) == EOF )
        {
            puts( "拷贝文件内容时错误." );
            fclose( dst );
            fclose( src );
            return 3;
        }
    }
    puts( "拷贝完毕." );

    fclose( dst );
    fclose( src );
    return 0;
}

#5
aCprogrammer2019-07-05 14:02
回复 4楼 rjsp
为什么要用ch!=EOF,不是以二进制的格式打开的吗,feof函数不是检查是否到文件末尾的函数么,而且照你这样的话就不能删除被复制的文件了

[此贴子已经被作者于2019-7-5 14:05编辑过]

#6
aCprogrammer2019-07-05 14:09
你这个方法C99不支持
#7
aCprogrammer2019-07-05 14:11
只有本站会员才能查看附件,请 登录
#8
rjsp2019-07-05 14:20
为什么要用ch!=EOF,
C标准只规定了以返回值判断正误这种唯一的方式
不是以二进制的格式打开的吗,
什么?且,不管是什么,又和是不是“以二进制的格式打开”有什么关系?
feof函数不是检查是否到文件末尾的函数么,
不是
而且照你这样的话就不能删除被复制的文件了
“照你这样的话”是什么样的话?不明白你在说什么,我干什么了,导致你不能删除被复制的文件?
C标准函数中没有删除文件的函数,非标的有 remove 等。
#9
rjsp2019-07-05 14:30
以下是引用aCprogrammer在2019-7-5 14:09:08的发言:

你这个方法C99不支持
是 C99不支持,还是 C99之前不支持?
证据在你自己贴的7楼上。图片上写着 'for' loop initial declaration used outside c99 mode

保险起见,我将编译参数从现世的“-std=c18”改为上世纪古老的“-std=c99”,重新编译,无警告无错误。
#10
aCprogrammer2019-07-05 14:33
回复 9楼 rjsp
我只是搞不懂EOF不是判断文本文件的结尾吗,可我要的不是文本文件的复制粘贴啊
#11
aCprogrammer2019-07-05 14:35
我这个程序的意思是打开一个被复制的文件,把它复制到另一个文件中,然后把原来的文件数据销毁
#12
aCprogrammer2019-07-05 14:39
只有本站会员才能查看附件,请 登录
#13
rjsp2019-07-05 15:05
我只是搞不懂EOF不是判断文本文件的结尾吗,
再说一次“不是!!!”
EOF 是 fgetc 的一种可能的返回值。
当 fgetc 返回 EOF,说明文件读取出错无内容可读,判断是“错误”还是“无内容可读”可以用ferror或feof来判断。
我随便举个例子,假设 a.txt 就1个字节,内容是 char(0xFF),那么
    FILE* src = fopen( "a.txt", "rb" );
    int a = feof(src); // a 应当是 0
    int b = fgetc( src ); // b 应当不是 EOF,(char)b 应当是 0xFF ---------- 注意,这就是为什么C标准要将 fgetc 的返回类型定为 int 的原因,用于区分是 正常返回了一个char,还是出错了。
    int c = feof(src); // c 应当是 0 ---------- 注意,feof 并不判断是否尚有文件内容可读,它标示的是读文件出错是因为无内容可读了吗。
    int d = fgetc( src ); // d 应当是 EOF
    int e = feof(src); // c 应当不是 0

可我要的不是文本文件的复制粘贴啊
听不懂
#14
aCprogrammer2019-07-05 15:10
那feof(FILE *文件指针)返回了一个非0的值不也可以表示文件结束了吗

[此贴子已经被作者于2019-7-5 15:11编辑过]

#15
rjsp2019-07-05 15:15
以下是引用aCprogrammer在2019-7-5 14:35:09的发言:

我这个程序的意思是打开一个被复制的文件,把它复制到另一个文件中,然后把原来的文件数据销毁
难道我给你的代码没完成“打开一个被复制的文件,把它复制到另一个文件中”这个功能?
“然后把原来的文件数据销毁”------ 我不知道“文件数据销毁”是干嘛用的,而且还留着个空文件在那里。但你觉得有用自己不会往代码里加“文件数据销毁”的功能吗?
#16
rjsp2019-07-05 15:15
回复 12楼 aCprogrammer
我不知道你从哪儿找来的,也不知道它瞎扯,还是文字理解有误。
看官方的C标准:
The feof function returns nonzero if and only if the end-of-file indicator is set for stream.
如果还迷糊,看 https://en.
Notes
This function only reports the stream state as reported by the most recent I/O operation, it does not examine the associated data source. For example, if the most recent I/O was a fgetc, which returned the last byte of a file, feof returns zero. The next fgetc fails and changes the stream state to end-of-file. Only then feof returns non-zero.
这个解释就比较清楚了。
#17
rjsp2019-07-05 15:19
以下是引用aCprogrammer在2019-7-5 15:10:31的发言:

那feof(FILE *文件指针)返回了一个非0的值不也可以表示文件结束了吗

返回一个非0值,确实表示文件结束,
返回一个0值,文件也可能已经结束了。
因为它就不是用来干这事的。
#18
aCprogrammer2019-07-05 15:39
大哥别激动,我只是不明白而已,现在我懂了,但我设置的删除被复制文件的数据是因为它既然已经被复制了,那也就没有存在的意义了……
#19
rjsp2019-07-05 16:22
以下是引用aCprogrammer在2019-7-5 15:39:22的发言:

大哥别激动,我只是不明白而已,现在我懂了,但我设置的删除被复制文件的数据是因为它既然已经被复制了,那也就没有存在的意义了……
没有存在的意义了,难道不应该是将文件删除吗?你怎么只是清空文件内容,文件依然存在?
#20
aCprogrammer2019-07-05 16:31
回复 19楼 rjsp
用"w"打开文件不进行录入不就可以覆盖原来的数据变成可利用的内存了吗
#21
Mr_doge2019-07-06 11:35
c打开文件可以以二进制打开,此时读取的不是字符数据,而是二进制数据,当然这时候用作字符型数据的结尾0会失效,因为你无法保证文件数据不存在长字节数据0或者-1之类的数值,EOF是c为了处理这种问题而作出的定义,用于指示文件流到达末尾,一般用作未知长度的数据流结尾标识,读取到此字符就表示文件已到达末尾,实际上它依赖于系统实现,而不是一个确切的数值或者字符,这有点类似声明的变量名,你的变量名实际上并不会带进二进制可执行文件,一样的道理

很多文件功能并非c自身的运行时环境实现的,而是依赖系统实现,系统这些功能有系统自己的游戏规则,你必须遵守,除非你自己手动在无系统环境实现这一切(然而到时候你又要遵守硬件和io的游戏规则)
#22
aCprogrammer2019-07-06 11:57
回复 21楼 Mr_doge
……这么多专业术语……
#23
Mr_doge2019-07-06 13:29
回复 22楼 aCprogrammer
都不是专业术语,而是不专业描述,都是些基础的概念,是你迟早会了解到的,如果你想接触一下这些,你需要看看k&r的那本c编程语言,那本古董是真的堪称C圣经
#24
aCprogrammer2019-07-06 14:13
回复 23楼 Mr_doge
谢谢哈,不过我已经买有了
1