使用c代码复制.dat文件时出现的额外字符
我是C语言的新手,刚刚开始了文件处理章节,所以请随意修改我的代码,我坚持。在下面给出的C代码中,A-Z字符从名为textfile.dat的dat文件复制,并粘贴到名为output.dat的另一个dat文件中 但当我打开output.dat时,会得到如下结果: A. B C D E F G H 我 J K L M N O P Q R s T U v W X Y使用c代码复制.dat文件时出现的额外字符,c,file-handling,C,File Handling,我是C语言的新手,刚刚开始了文件处理章节,所以请随意修改我的代码,我坚持。在下面给出的C代码中,A-Z字符从名为textfile.dat的dat文件复制,并粘贴到名为output.dat的另一个dat文件中 但当我打开output.dat时,会得到如下结果: A. B C D E F G H 我 J K L M N O P Q R s T U v W X Y Zÿ这是因为while循环条件不是您想要的,因为它比您想要的多运行一次: while(!feof(fpin)) feof(fp)测试fp
Zÿ这是因为
while
循环条件不是您想要的,因为它比您想要的多运行一次:
while(!feof(fpin))
feof(fp)
测试fp
是否仅在文件结束标记后返回非零值
我建议您使用,而不是阅读行作为必要的解析。一次读一个字符不是很有效
char buf[1024];
while( fgets(buf, sizeof buf, stdin) ) {
...
...
}
记住fgets()
如果缓冲区中有空间,也会读取换行符。因此,如果出现问题,您可能需要将其删除。例如,您可以执行以下操作:
char *p = strchr(buf, '\n');
if (p) *p = 0;
在循环内部(在fgets()
读取输入后)移除尾随换行符(如果有)。feof(fpin)
测试EOF指示器;在设置之前,getc(fpin)
将返回EOF字符。您在输出中看到的是这个角色。(它是-1,在单字节字符中是0xFF。)
相反,您应该执行以下操作:
while((ch = getc(fpin)) != EOF)
{
printf("\t%c",ch)
putc(ch,fpout);
}
这个循环直到读取EOF,然后在EOF被打印或写入输出文件之前中断循环
另外:您需要在文件的开头添加
#include
和#include
。有几个微妙的问题值得注意,但首先是有点小,但足够大,可以讨论。所有应用程序都可以在命令行上获取参数。这是您必须向程序传递信息的方式,以防止在代码中硬编码,如文件名等。main
的标准声明是intmain(intargc,char**argv)
(在Linux上,您也可以看到char**envp
)argc
将包含命令行上的参数数量,argv[]
将包含指向每个参数的指针(argv[0]
始终是用于启动程序的名称)
接下来,ch
是typeint
,而不是char
。这是fgetc
的返回,它允许处理包含多个字节的字符。确保始终使用正确的数据类型
正如您在其他答案中所指出的那样,(fpin!=feof())
在循环中用于读取文本文件时几乎总是错误的。从文件中读取文本的选择是使用面向字符的输入函数,如(getchar
,fgetc
,等等),或者使用面向行的输入函数(如(fgets
或getline
)一次读取一行,还有一些有限的情况,数据本身的布局使得fscanf
函数集可用。虽然使用fgets
进行面向行的输入会使您的程序变得微不足道,但其目的似乎是让您接触到面向字符的方法
考虑到这些因素,您可以编写类似于以下内容的代码。注:简单的三元运算符(例如(测试)?(如果为真代码):(如果为假代码);
使得在命令行上获取输入和输出文件名非常容易,同时在没有参数的情况下仍然提供默认文件名。这允许用户指定输入/输出文件名,而不必使用硬编码值。(默认情况下,只需进行简单更改,即可从文件或stdin
中读取)
尝试以下方法:
#include <stdio.h>
int main (int argc, char **argv)
{
int ch; /* ch is type 'int' */
FILE *fpin = argc > 1 ? fopen (argv[1], "r") : fopen ("textfile.dat","r");
FILE *fpout = argc > 2 ? fopen (argv[2], "w") : fopen ("output.dat","w");;
if (!fpin || !fpout) {
if (!fpin) fprintf (stderr, "error: input file open failed\n");
if (!fpout) fprintf (stderr, "error: output file open failed\n");
return 1;
}
while ((ch = fgetc(fpin)) != EOF) {
printf (" %c", ch);
putc (ch, fpout);
}
putchar ('\n'); /* to make stdout output look nice */
putc ('\n', fpout); /* POSIX requires newline at EOF */
fclose (fpin);
fclose (fpout);
return 0;
}
输入文件
$cat dat/AZ.txt
ABCDEFGHIJKLMNOPQRSTUVWXYZ
$cat dat/AZout.dat
ABCDEFGHIJKLMNOPQRSTUVWXYZ
使用/输出
$ ./bin/read_AZ dat/AZ.txt dat/AZout.dat
A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
输出文件
$cat dat/AZ.txt
ABCDEFGHIJKLMNOPQRSTUVWXYZ
$cat dat/AZout.dat
ABCDEFGHIJKLMNOPQRSTUVWXYZ
注意:结尾没有有趣的字符…如果您有任何问题,请告诉我。另外ch
应为int
类型。