求解ÿ;C语言中的文件结尾
当我将一个文件的内容复制到输出文件末尾的另一个C中时,我有一个字符求解ÿ;C语言中的文件结尾,c,eof,C,Eof,当我将一个文件的内容复制到输出文件末尾的另一个C中时,我有一个字符ÿ。多亏了这个论坛,我知道这是EOF指标,但我不知道该怎么做才能在输出文件中去掉它 这是我的代码: second_file = fopen(argv[2], "w+"); while (curr_char != EOF) { curr_char = fgetc(original_file); fputc(curr_char, second_file); } printf("Your file has been su
ÿ
。多亏了这个论坛,我知道这是EOF指标,但我不知道该怎么做才能在输出文件中去掉它
这是我的代码:
second_file = fopen(argv[2], "w+");
while (curr_char != EOF)
{
curr_char = fgetc(original_file);
fputc(curr_char, second_file);
}
printf("Your file has been successfully copy\n");
fclose(second_file);
fclose(original_file);
对于您阅读的每个字符,您有两件事要做:
while (curr_char != EOF)
{
curr_char = getc(original_file);
if(curr_char == EOF) break;
putc(curr_char, second_file);
}
在这里,我们显式地测试字符是否是EOF,在读取它之后,在写入它之前。如果是EOF,我们会尽早脱离循环。这会起作用,但很难看:我们在两个不同的地方测试EOF,其中一个地方从不“点火”。(另外,正如一位评论员提醒我的那样,有一个问题是,第一次通过循环时,我们在设置之前就在测试curr\u char
)
两个。你可以这样重新安排:
curr_char = getc(original_file);
while (curr_char != EOF)
{
putc(curr_char, second_file);
curr_char = getc(original_file);
}
while ((curr_char = getc(original_file)) != EOF)
{
putc(curr_char, second_file);
}
在这里,我们读一个初始字符,只要它不是EOF,我们就写它,然后读另一个。这很好,但还是有点难看,因为这一次我们在两个不同的地方阅读角色
三个。你可以这样重新安排:
curr_char = getc(original_file);
while (curr_char != EOF)
{
putc(curr_char, second_file);
curr_char = getc(original_file);
}
while ((curr_char = getc(original_file)) != EOF)
{
putc(curr_char, second_file);
}
这是在C中编写字符复制循环的常规方法。对getc
的调用和对curr\u char
的赋值隐藏在while
循环的控制表达式中。这取决于这样一个事实:在C语言中,赋值表达式和其他表达式一样有一个值。也就是说,表达式a=b
的值是我们刚才分配给a
的值(即b
的值)。因此表达式curr\u char=getc(原始文件)
的值就是我们刚才读取的字符。所以当我们说while((curr\u char=getc(original\u file))!=EOF)
时,我们实际上说的是,“调用getc
,将结果分配给curr\u char
,如果它不等于EOF
,那么再绕一圈。”
(如果您仍然看不到这一点,我已经在和中写了其他解释。)
这段代码既好又坏。这很好,因为我们只有一个地方可以读字符,一个地方可以测试字符,还有一个地方可以写字符。但这有点糟糕,因为,让我们承认,一开始它有点神秘。很难想象隐藏在-while
条件中的赋值。正是这样的代码给了C一个充满晦涩难懂的狼吞虎咽的名声
但是,至少在这种情况下,它确实值得学习这个习语,并适应它,因为简化为一次读、一次测试和一次写确实是一种优点。在这样一个琐碎的例子中,这并不重要,但在由于其他原因而变得复杂的实际程序中,如果有一些关键功能发生在两个不同的地方,很容易忽略这一事实,对其中一个进行更改,但忘记对另一个进行更改
(事实上,就在上周的工作中,这种情况发生在我身上。我正试图修复其他人代码中的一个错误。我最终发现,当代码执行X时,它无意中清除了Y。我找到了执行X的位置,并添加了一些新代码以正确地重新创建Y。但当我测试我的修复时,它不起作用!结果是出现了两个错误。)代码没有X的地方,我发现并修复了错误的地方。)
最后,这里有一种相当简单但非常规的循环编写方式:
while (1)
{
curr_char = getc(original_file);
if(curr_char == EOF) break;
putc(curr_char, second_file);
}
这有点像数字1,但它消除了while
循环中的冗余条件,并用常量1
替换它,即“true”在C中,这也可以很好地工作,并且它具有一次读取、一次测试和一次写入的优点。它实际上以与数字3完全相同的顺序执行完全相同的操作,但通过线性布局,它可能更容易遵循
数字4唯一的问题是它是一个非传统的“中间打断”循环。就个人而言,我对中间打断循环没有问题,我发现它们不时出现,但如果我写了一个,有人说“史蒂夫,这太难看了,这不是任何人都能识别的习惯用法,它会让人困惑”,我必须同意
另外,我已经用更传统的
getc
和putc
取代了你对fgetc
和fputc
的呼叫。我不知道是谁告诉你要使用fgetc
和fputc
,而且你需要它们的地方有一些模糊的情况,但它们是如此罕见,在我看来,人们可能会忘记它们t存在“f”变体,并且始终使用getc
和putc
对于您读取的每个字符,您有两件事要做:
while (curr_char != EOF)
{
curr_char = getc(original_file);
if(curr_char == EOF) break;
putc(curr_char, second_file);
}
在这里,我们显式地测试字符是否是EOF,在读过它之后,在写它之前。如果它是EOF,我们会很早地跳出循环。这会起作用,但很难看:我们在两个不同的地方测试EOF,其中一个从来不会“触发”。(另外,正如一位评论员提醒我的,fir存在一个问题