C 确保用户只输入自然数的最佳方法是什么?

C 确保用户只输入自然数的最佳方法是什么?,c,unsigned-long-long-int,C,Unsigned Long Long Int,刚开始学习C,如果您能在以下方面帮助我,那就太好了: 我刚刚编写了一个程序,计算用户输入的自然数的阶乘。如果数字是负数或字符,则应通知用户您尚未输入自然数。。此消息来自函数检查值是否有效 到目前为止,它在输入字符时显示该消息,但似乎不适用于负值。我原以为将变量强制转换为long unsigned就可以了,但事实似乎并非如此。问题是scanf()函数返回一个0,因此不确定程序为什么不运行该函数检查值是否有效,以便返回消息:您没有输入自然数。 我期待着阅读任何改进这段代码的建议 #include &

刚开始学习C,如果您能在以下方面帮助我,那就太好了:

我刚刚编写了一个程序,计算用户输入的自然数的阶乘。如果数字是负数或字符,则应通知用户您尚未输入自然数。。此消息来自函数
检查值是否有效

到目前为止,它在输入字符时显示该消息,但似乎不适用于负值。我原以为将变量强制转换为
long unsigned
就可以了,但事实似乎并非如此。问题是
scanf()
函数返回一个
0
,因此不确定程序为什么不运行该函数
检查值是否有效,以便返回消息:
您没有输入自然数。

我期待着阅读任何改进这段代码的建议

#include <stdio.h>
#include <stdlib.h>

void check_if_valid_value(int value_entered)
{
        if (value_entered != 1) 
        {
                printf("You have not entered a natural number.\n");
                exit(1);
        }
}          

void do_the_factorial(int p)
{  
        int i;
        unsigned long long int factorial=1;

        for (i = 1; i <= p; ++i)
        {
                factorial=factorial*i;
                printf("%llu\n", factorial);
        }
}


int main(void)
{
        int value_entered, p;

        printf("Enter a natural number:");

        value_entered=scanf("%llu",&p);

        check_if_valid_value(value_entered);

        do_the_factorial(p);

        return 0;
}
#包括
#包括
无效检查\u是否有效\u值(输入的int值)
{
如果(输入的值!=1)
{
printf(“您没有输入自然数。\n”);
出口(1);
}
}          
void do__因数(int p)
{  
int i;
无符号长整型阶乘=1;

对于(i=1;i代码问题:

  • scanf返回成功转换的次数。因此,您可能应该重命名该变量
    successful\u conversions
  • 指向无符号整数的指针的scanf格式是
    %u
    ,而不是
    %llu
您也可以从2开始阶乘循环,因为乘以1基本上是无用的。因此我们有:

#include <stdio.h>
#include <stdlib.h>

void check_if_valid_value(int successful_conversions)
{
        if (successful_conversions != 1)
        {
                printf("You have not entered a natural number.\n");
                exit(1);
        }
}

void do_the_factorial(unsigned int p)
{
        unsigned int i;
        unsigned long long int factorial=1;

        for (i = 2; i <= p; ++i)
        {
                factorial=factorial*i;
        }
        printf("%llu\n", factorial);
}

int main(void)
{
        int successful_conversions;
        unsigned int p;

        printf("Enter a natural number:\n");
        successful_conversions=scanf("%u",&p);
        check_if_valid_value(successful_conversions);
        do_the_factorial(p);
        return 0;
}
#包括
#包括
无效检查\u是否有效\u值(int成功\u转换)
{
如果(成功的_转换!=1)
{
printf(“您没有输入自然数。\n”);
出口(1);
}
}
void do__因数(无符号整数p)
{
无符号整数i;
无符号长整型阶乘=1;

对于(i=2;i代码问题:

  • scanf返回成功转换的次数。因此,您可能应该重命名该变量
    successful\u conversions
  • 指向无符号整数的指针的scanf格式是
    %u
    ,而不是
    %llu
您也可以从2开始阶乘循环,因为乘以1基本上是无用的。因此我们有:

#include <stdio.h>
#include <stdlib.h>

void check_if_valid_value(int successful_conversions)
{
        if (successful_conversions != 1)
        {
                printf("You have not entered a natural number.\n");
                exit(1);
        }
}

void do_the_factorial(unsigned int p)
{
        unsigned int i;
        unsigned long long int factorial=1;

        for (i = 2; i <= p; ++i)
        {
                factorial=factorial*i;
        }
        printf("%llu\n", factorial);
}

int main(void)
{
        int successful_conversions;
        unsigned int p;

        printf("Enter a natural number:\n");
        successful_conversions=scanf("%u",&p);
        check_if_valid_value(successful_conversions);
        do_the_factorial(p);
        return 0;
}
#包括
#包括
无效检查\u是否有效\u值(int成功\u转换)
{
如果(成功的_转换!=1)
{
printf(“您没有输入自然数。\n”);
出口(1);
}
}
void do__因数(无符号整数p)
{
无符号整数i;
无符号长整型阶乘=1;

对于(i=2;我仔细阅读了C11标准草案的文档和/或。使用所有警告和调试信息编译代码(
gcc-Wall-Wextra-g
with…)。阅读“强制转换变量”是什么意思?如果您的意思是使用scanf格式
%llu
,那不是强制转换。变量是
int
scanf
的参数是“指向
int
”的指针,而转换代码
%llu
,这意味着该参数是“指向
长无符号的指针”,是谎言。对参数类型撒谎是未定义的行为。不要这样做。并启用编译器警告以帮助您不要这样做。为什么会出现否决票?这是一个编程问题,OP显示了他所做的尝试。让我们让Henry放松一下,找出错误所在。仔细阅读和/或C11标准草案的文档。编译y我们的代码包含所有警告和调试信息(
gcc-Wall-Wextra-g
with…)。请阅读,您所说的“强制转换变量”是什么意思?如果您指的是使用scanf格式
%llu
,那就不是强制转换。变量是
int
,scanf
的参数是“指向
int
的指针”,以及转换代码
%llu
,这意味着该参数是“指向
长无符号
的指针”,是谎言。对参数类型撒谎是未定义的行为。不要这样做。并启用编译器警告以帮助您不要这样做。为什么会出现否决票?这是一个编程问题,OP显示了他所做的尝试。让我们让Henry放松一下,找出错误所在。我发现
scanf
接受负数并返回的结果令人惊讶s
1
当给定一个
无符号的
说明符,如
%u
。非常感谢@Jens!:-)这真的帮助我提高得更快!最好的!@WeatherVane这是因为C中的无符号算术是模2^N,所以不能下溢或溢出。-1相当于
UINT_MAX
,这就是scanf转换的内容。我发现
scanf
接受负数并在给定
uns时返回
1
,这令人惊讶签名的
说明符,如
%u
。非常感谢@Jens!:-)这真的帮助我提高得更快!最好的!@风向标这是因为C中的无符号算术是模2^N,所以不能下溢或上溢。-1相当于
UINT\u MAX
,这就是scanf转换的。