为什么在给定的代码段中,`fgetc()` 函数给出了正确的输出,而 `fscanf()` 却失败了?

Why in the given piece of code `fgetc()` function gave proper output whereas `fscanf()` failed to do so?

以下代码有效:

 #include<stdio.h>
    void main()
    {
        FILE *ip, *op ;
        char ch ;
        ip = fopen ( "read.txt", "r" ) ;
        op = fopen ( "out.txt", "a" );
        while ( 1 )
        {
            ch = fgetc ( ip ) ;   //used for getting character from file read.txt
            if ( ch == EOF )
                break ;
            fprintf ( op, "%c", ch ) ;
        }
            fclose ( ip ) ;
            fclose ( op );
    }

但由于使用了 fscanf(),因此以下代码未提供所需的输出:

#include<stdio.h>
void main()
{
    FILE *fp, *op ;
    char ch ;
    fp = fopen ( "read.txt", "r" ) ;
    op = fopen ( "out.txt", "a" );
    while ( 1 )
    {
        ch = fscanf ( fp, "%c", &ch ) ;  //to read the characters from read.txt
        if ( ch == EOF )
            break ;
        fprintf ( op, "%c", ch ) ;
    }
        fclose ( fp ) ;
        fclose ( op );
}

我也不明白变量 ch 是如何自动占用下一个字符的。

问题是您将 fscanf 的结果分配给 ch:

    ch = fscanf ( fp, "%c", &ch ) ;  //to read the characters from read.txt
//  ^^^^^---- here
    if ( ch == EOF )
        break ;

所以首先fscanf将一个字符读入ch(如果有的话),然后returns,它的return值被写入ch,覆盖字符。 fscanf 的 return 值是 "Number of receiving arguments successfully assigned, or EOF if read failure occurs before the first receiving argument was assigned." 当有一个字符要读取时,你最终将 ch 设置为 1。

所以:

if (fscanf ( fp, "%c", &ch ) != 1) {
    break;

if (fscanf ( fp, "%c", &ch ) == EOF) {
    break;

I also don't understand how the variable ch was automatically taking up the next character.

注意 fscanf ( fp, "%c", &ch )&ch 部分:获取 ch 变量的地址并将该地址传递给 fscanffscanf 收到指向 ch 指针 fscanf 将数据写入指针指向的内存,这就是为什么它最终在 ch.