C 复制文件并向后写入文件信息
需要创建一个以前创建的文件副本,其中包含15个随机数字,并在此副本中向后写入这些数字 我试图用for()读取文件并写入数组,数组也会用for()填充新创建的文件,但IDE会在脚本转到for()时立即停止脚本C 复制文件并向后写入文件信息,c,C,需要创建一个以前创建的文件副本,其中包含15个随机数字,并在此副本中向后写入这些数字 我试图用for()读取文件并写入数组,数组也会用for()填充新创建的文件,但IDE会在脚本转到for()时立即停止脚本 #包括 #包括 int main(){ chara[20],sf[20],tf[20]; 文件*源,*目标; int i; printf(“输入要复制的文件名\n”); 获取(sf); 来源=fopen(sf,“r”); if(source==NULL){ printf(“按任意键退出…\n
#包括
#包括
int main(){
chara[20],sf[20],tf[20];
文件*源,*目标;
int i;
printf(“输入要复制的文件名\n”);
获取(sf);
来源=fopen(sf,“r”);
if(source==NULL){
printf(“按任意键退出…\n”);
出口(1);
}
printf(“输入目标文件的名称”);
获取(tf);
目标=fopen(tf,“w”);
if(target==NULL){
fclose(来源);
printf(“按任意键退出…\n”);
出口(1);
}
对于(i=0;i0;i--){
fprintf(目标,“%d\n”,a[i]);
}
//printf(“文件复制成功。\n”);
返回0;
}
一些备注:
- 正如在备注中所说,您读取int,所以您需要一个int数组,而不是char数组来保存它们,当前您将使用未定义的行为写出
- 如果您需要保存15个值,15个数组就足够了,20(假设int)是无用的
- 永远不要使用gets,它是不推荐使用的(自年以来),因为它很危险,请使用FGET不要冒险写出接收字符串,并且不要忘记删除可能的换行符
- 可能输入文件和输出文件是一样的,所以先读再打开输出文件并写入其内容
fscanf(来源,“%d”,a[i])代码>无效,必须是
fscanf(源代码,“%d”,&a[i])代码>
- 检查fscanf的结果以管理输入文件中的错误案例
fprintf(目标,“%d\n”,a[i])代码>必须是
fprintf(目标,“%d\n”,a[i-1])代码>
- 显式关闭输出文件更好,以防以后将程序转换为更复杂的程序
一项建议:
#include <stdio.h>
#include <string.h>
#define N 15
FILE * openIt(const char * msg, const char * dir)
{
char fn[256];
printf(msg);
if (fgets(fn, sizeof(fn), stdin) == NULL)
/* EOF */
return NULL;
char * p = strchr(fn, '\n');
if (p != NULL)
*p = 0;
FILE * fp = fopen(fn, dir);
if (fp == NULL)
fprintf(stderr, "cannot open '%s'\n", fn);
return fp;
}
int main()
{
FILE * fp;
if ((fp = openIt("Enter name of file to copy\n", "r")) == NULL)
return -1;
int a[N], i;
for (i = 0; i != N; ++i) {
if (fscanf(fp, "%d", &a[i]) != 1) {
fprintf(stderr, "invalid integer rank %d\n", i);
fclose(fp);
return -1;
}
}
fclose(fp);
if ((fp = openIt("Enter name of target file\n", "w")) == NULL)
return -1;
while (i--) {
fprintf(fp, "%d\n", a[i]);
}
fclose(fp);
return 0;
}
“IDE停止脚本”是什么意思?它会给你一个错误信息吗?另外,第二个for循环应该从14运行到0(您的循环将使其从15运行到1),强烈建议不要使用
get()
,因为没有检查用户键入的文件名是否实际适合您提供的缓冲区。IDE是否提供了任何错误消息?你确定它在for循环开始时就退出了,并且没有打开目标文件失败吗?这不是你的解决方案的答案,但要想扭转局面,我要做的第一件事就是找到堆栈的C实现并使用它。每当有人说“推翻某件事”时,我几乎马上就会想。你已经接受了我的答案,但我添加了一个建议,如果你对此感兴趣的话,它会起作用,我忘了在fscanf中写“&”。@Dante,是的,还有fprintf(target,%d\n,a[I])代码>必须是fprintf(目标,“%d\n”,a[i-1])代码>等等,我编辑了我的答案,提出了一个建议
#include <stdio.h>
#include <string.h>
#define N 15
FILE * openIt(const char * msg, const char * dir)
{
char fn[256];
printf(msg);
if (fgets(fn, sizeof(fn), stdin) == NULL)
/* EOF */
return NULL;
char * p = strchr(fn, '\n');
if (p != NULL)
*p = 0;
FILE * fp = fopen(fn, dir);
if (fp == NULL)
fprintf(stderr, "cannot open '%s'\n", fn);
return fp;
}
int main()
{
FILE * fp;
if ((fp = openIt("Enter name of file to copy\n", "r")) == NULL)
return -1;
int a[N], i;
for (i = 0; i != N; ++i) {
if (fscanf(fp, "%d", &a[i]) != 1) {
fprintf(stderr, "invalid integer rank %d\n", i);
fclose(fp);
return -1;
}
}
fclose(fp);
if ((fp = openIt("Enter name of target file\n", "w")) == NULL)
return -1;
while (i--) {
fprintf(fp, "%d\n", a[i]);
}
fclose(fp);
return 0;
}
pi@raspberrypi:/tmp $ gcc -pedantic -Wall -Wextra r.c
pi@raspberrypi:/tmp $ cat in
1 2 3 4 5
6 7 8 9 10
11 12
13
14
15
not read
pi@raspberrypi:/tmp $ ./a.out
Enter name of file to copy
in
Enter name of target file
out
pi@raspberrypi:/tmp $ cat out
15
14
13
12
11
10
9
8
7
6
5
4
3
2
1
pi@raspberrypi:/tmp $ ./a.out
Enter name of file to copy
out
Enter name of target file
out
pi@raspberrypi:/tmp $ cat out
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
pi@raspberrypi:/tmp $