使用while(scanf(“%d”、&n)!=EOF)和while(scanf(“%d”、&n)&&n!=EOF)之间的时间间隔

使用while(scanf(“%d”、&n)!=EOF)和while(scanf(“%d”、&n)&&n!=EOF)之间的时间间隔,c,scanf,eof,C,Scanf,Eof,我的问题不是关于算法,而是关于C编程语言的一些令人困惑的东西。 我遇到了如下问题: 问题描述 N!N阶乘对于N的大值可能非常恼人且难以计算。因此,与其计算N!,我想知道里面有多少个数字。记住,N!=N*N-1*N-2*…*2*1 输入 输入的每一行上都有一个整数N,0=1.0e31{result+=31;temp/=1.0e31;}}}whiletemp>=10.0{result++;temp/=10.0;}printf%d\n,result;。31选择为DBL_MAX至少为1.0e31*100

我的问题不是关于算法,而是关于C编程语言的一些令人困惑的东西。 我遇到了如下问题:

问题描述

N!N阶乘对于N的大值可能非常恼人且难以计算。因此,与其计算N!,我想知道里面有多少个数字。记住,N!=N*N-1*N-2*…*2*1

输入

输入的每一行上都有一个整数N,0 输出

对于N的每个值,打印出N!中的数字数

我的代码是这样的:

 #include<stdio.h>
 int main()
{
    int n ;
    while(scanf("%d",&n)&&n!=EOF)//1
    //while(scanf("%d",&n)!=EOF)//2
    {
        int result=1;
        int i;
        double temp = 1;
        for(i=n;i>0;i--)
        {
            temp*=i;
            while((temp/10)>1)
            {
                result++;
                temp=temp/10;
            }           
        }
        printf("%d\n",result);
    }
    return 0;
}

当我使用whilescan%d、&n&&n=EOF,我使用的在线判断显示超过了时间限制,我将其更改为whilescanf%d,&n=EOF,一切都很顺利,我想n=EOF可能需要太多的时间,那么EOF的本质是什么呢?

这不是两个句子的时间,而是它们有不同的意思

下一个将scanf读取的值与EOF进行比较,这是一个错误,如果到达文件末尾,scanf将不会加载n中的任何值:

while(scanf("%d",&n) && n!=EOF)
while(scanf("%d",&n)!=EOF)
这是检测文件结尾的正确方法:

while(scanf("%d",&n) && n!=EOF)
while(scanf("%d",&n)!=EOF)
一般来说,EOF==-1,因为judge中的输入不包含-1,所以您的程序会无限期地循环

正如注释中所述,检查scanf的转换次数通常更好,因为它检查输入是否或多或少有效*。如果您要求在格式字符串%d中进行1次转换,您可以检查scanf是否返回1:

while(scanf("%d", &n) == 1)
*如果必须遵循严格的格式,则可能无法验证某些情况,例如,如果数字后面必须紧跟exaclty one,则最好使用strtol进行转换,检查strtol是否使用了完整的行


由于这一特殊问题来自使用在线评委的编程竞赛,因此输入格式良好,通常不需要进行此类测试。

这不是两个句子的时间,而是它们具有不同的含义

下一个将scanf读取的值与EOF进行比较,这是一个错误,如果到达文件末尾,scanf将不会加载n中的任何值:

while(scanf("%d",&n) && n!=EOF)
while(scanf("%d",&n)!=EOF)
这是检测文件结尾的正确方法:

while(scanf("%d",&n) && n!=EOF)
while(scanf("%d",&n)!=EOF)
一般来说,EOF==-1,因为judge中的输入不包含-1,所以您的程序会无限期地循环

正如注释中所述,检查scanf的转换次数通常更好,因为它检查输入是否或多或少有效*。如果您要求在格式字符串%d中进行1次转换,您可以检查scanf是否返回1:

while(scanf("%d", &n) == 1)
*如果必须遵循严格的格式,则可能无法验证某些情况,例如,如果数字后面必须紧跟exaclty one,则最好使用strtol进行转换,检查strtol是否使用了完整的行


由于此特定问题来自使用在线评委的编程竞赛,因此输入格式良好,通常不需要进行此类测试。

除了scanf%d、&n!=EOF是最好使用的

循环应写为:

while (scanf("%d",&n) == 1)

因为您要求scanf转换1个值,而scanf的返回值是成功转换的项目数。

除了使用scanf%d、&n!=EOF是最好使用的

I would strongly suggest using the following code rather than 
the illmannered scanf() function:

#include<stdio.h>

int main()
{
    unsigned int n ;            // user input after conversion
    long long int result=0;     // maybe use uint64_t
    char inArray[100] = {'\0'}; // user input array
    int i;                      // loop counter
    int digitCount = 0;         // number of digits to display factorial value

    printf("\nwhen enter a number\n"); 
    printf(" then pgm will output factorial for that number\n");
    printf(" then number of digits in factorial value\n");

    printf("\n\nPlease enter first number: (or <ctrl-z> to exit)");
    while( NULL != fgets( inArray, sizeof(inArray), stdin )
    {
        n = (unsigned)atoi( inArray );
        if( 0 == n )      {result = 0;}
        else if( 1 == n ) {result = 1;}
        else if( 2 == n ) {result = 2;}
        else
        {
            result = n;
            for(i=(n-1);i>1;i--)
            {
                result *= i;
            } // end calculate factorial
        } // end if

        printf("factorial value: %lld\n",result);

        // setup work area usage
        memset( inArray, 0x00, sizeof(inArray) );
        sprintf( inArray, "%lld", result );

        // calculate and display number of digits
        digitCount = strlen(inArray);
        printf("digit count: %d\n", digitCount );

        // clear work area and prompt for next input from user
        memset( inArray, 0x00, sizeof(inArray) );
        printf("\n\nPlease enter next number: (or <ctrl-z> to exit)");
    } // end while

    return 0;
} // end function: main
循环应写为:

while (scanf("%d",&n) == 1)

因为您要求scanf转换1个值,而scanf的返回值是成功转换的项数。

请注意,如果输入格式不正确,并且包含字母或输入中的“=”等错误标点,则检测EOF将没有帮助。正确的测试是当scanf%s时,&n==1,当scanf成功地将输入转换为int值时,该测试将继续。不过,在这两个人中,scanf…!=在输入受到合理控制的情况下,EOF更接近正确,如在线判断操作。请注意,如果输入格式不正确,并且输入中包含字母或诸如“=”之类的零散标点,则检测EOF不会有帮助。正确的测试是当scanf%s时,&n==1,当scanf成功地将输入转换为int值时,该测试将继续。不过,在这两个人中,scanf…!=当输入处于合理控制之下时,EOF更接近正确,如在线判断操作。EOF定义为-1,即32位系统的0xFFFFFFFF。但是,调用scanf函数时存在两个问题:1代码应始终检查scanf返回的值,以确保输入/转换成功2 scanf返回的值永远不会被EOF忽略,它将为0或更大。位数的计数不准确且不在正确的位置。只需对N!的最终值执行“位数计数”!。注:N!很快就超过了“int”的能力。建议使用“long long int”64位或“bignum”函数。@user3629249 1 EOF
I would strongly suggest using the following code rather than 
the illmannered scanf() function:

#include<stdio.h>

int main()
{
    unsigned int n ;            // user input after conversion
    long long int result=0;     // maybe use uint64_t
    char inArray[100] = {'\0'}; // user input array
    int i;                      // loop counter
    int digitCount = 0;         // number of digits to display factorial value

    printf("\nwhen enter a number\n"); 
    printf(" then pgm will output factorial for that number\n");
    printf(" then number of digits in factorial value\n");

    printf("\n\nPlease enter first number: (or <ctrl-z> to exit)");
    while( NULL != fgets( inArray, sizeof(inArray), stdin )
    {
        n = (unsigned)atoi( inArray );
        if( 0 == n )      {result = 0;}
        else if( 1 == n ) {result = 1;}
        else if( 2 == n ) {result = 2;}
        else
        {
            result = n;
            for(i=(n-1);i>1;i--)
            {
                result *= i;
            } // end calculate factorial
        } // end if

        printf("factorial value: %lld\n",result);

        // setup work area usage
        memset( inArray, 0x00, sizeof(inArray) );
        sprintf( inArray, "%lld", result );

        // calculate and display number of digits
        digitCount = strlen(inArray);
        printf("digit count: %d\n", digitCount );

        // clear work area and prompt for next input from user
        memset( inArray, 0x00, sizeof(inArray) );
        printf("\n\nPlease enter next number: (or <ctrl-z> to exit)");
    } // end while

    return 0;
} // end function: main

未定义为-1。它当然总是一个负的int常数。2 scanf%d,&n的可能返回值为0、1或EOF。注意:使用类似于fori=n的值,代码可以运行得更快更准确;i> 0;i-{temp*=i;whiletemp>=1.0e31{result+=31;temp/=1.0e31;}}}whiletemp>=10.0{result++;temp/=10.0;}printf%d\n,result;。31选择为DBL_MAX至少为1.0e31*1000000。EOF定义为-1,即32位系统的0xFFFFFFFF。但是,调用scanf函数时存在两个问题:1代码应始终检查scanf返回的值,以确保输入/转换成功2 scanf返回的值永远不会被EOF忽略,它将为0或更大。位数的计数不准确且不在正确的位置。只需对N!的最终值执行“位数计数”!。注:N!很快就超过了“int”的能力。建议使用“long long int”64位或“bignum”函数。@user3629249 1 EOF未定义为-1。它当然总是一个负的int常数。2 scanf%d,&n的可能返回值为0、1或EOF。注意:使用类似于fori=n的值,代码可以运行得更快更准确;i> 0;i-{temp*=i;whiletemp>=1.0e31{result+=31;temp/=1.0e31;}}}whiletemp>=10.0{result++;temp/=10.0;}printf%d\n,result;。31选择为DBL_MAX至少为1.0e31*1000000。