【问题标题】:Trying to catch if the entered value stored in long is a decimal number C试图捕捉存储在 long 中的输入值是否是十进制数 C
【发布时间】:2021-12-18 02:30:18
【问题描述】:

这是我当前的程序,其中我取 N 个自然数的 3 个不同(或相同)值并计算它们的校验和,长数据类型的使用是必须的,因为我还需要能够计算值的校验和超过 int 的 MAX。我无法更改数据类型。现在我还需要捕捉当用户输入一个非自然数时,例如 -23、2.3 ......我已经做了 if 语句,如果输入一个负数和一个超过 long 的 MAX 的数字,实际的问题是当我输入十进制数,它跳过我的 if 条件并打印出 printf 函数,但没有打印出任何其他函数,我尝试用 x % 1 !=0 捕获十进制数,这不起作用,因为 x 的实际值似乎不是存储为小数而不是整数,我通过打印 x 的值在我的程序中的各个位置确认了这一点。 我对 C 语言真的很陌生,刚开始学习 2 周,还没有真正掌握一切,但我真的似乎无法在我的程序中找到问题。 我知道我的代码看起来像意大利面条代码。

P.S 请原谅我糟糕的英语

#include <stdio.h>
#include <stdlib.h>
int checksum(long q){
    long countingVariable = 0;

    while(q > 0)
    {
        countingVariable += q%10; // steht für sx = s + q%10
        q/=10;     // steht für q = q/10

    }
    return countingVariable;
}

int main(void) {

    long x,y,z;
    long long max_long = 2147483647;

    printf("Bitte geben sie ihre erste Zahl ein:\n"); // enter first number
    scanf("%ld",&x);

    long sx = quersumme_1(x); // checksum of x first number

    if ( x > 0 && x < max_long && x % 1 != 0){    // check if positive  and natural number

        printf("Bitte geben Sie ihre zweite Zahl ein:\n"); //enter second number
        scanf("%ld",&y);

        if (y > 0 && y < max_long){

            long sy = quersumme_2(y); //checksum of y second number
            printf("Bitte geben sie ihre dritte Zahl ein:\n");// enter third number
            scanf("%ld",&z);

            if (z > 0 && z < max_long){
                long sz = quersumme_3(z); // checksum of z 3rd number
                if (sx>sy && sx>sz && sy>=sz){
                    printf("Die Quersumme s der Zahl %ld ist %ld\n",x,sx);
                    printf("Die Quersumme s der Zahl %ld ist %ld\n",y,sy);
                    printf("die Quersumme s der Zahl %ld ist %ld\n",z,sz);
                } else if (sx>sy && sx>z && sz>sy){
                    printf("Die Quersumme s der Zahl %ld ist %ld\n",x,sx);
                    printf("die Quersumme s der Zahl %ld ist %ld\n",z,sz);
                    printf("Die Quersumme s der Zahl %ld ist %ld\n",y,sy);
                } else if (sy>sx && sy>sz && sx>=sz){
                    printf("Die Quersumme s der Zahl %ld ist %ld\n",y,sy);
                    printf("Die Quersumme s der Zahl %ld ist %ld\n",x,sx);
                    printf("die Quersumme s der Zahl %ld ist %ld\n",z,sz);
                } else if (sy>sx && sy>sz && sz>sx){
                    printf("Die Quersumme s der Zahl %ld ist %ld\n",y,sy);
                    printf("die Quersumme s der Zahl %ld ist %ld\n",z,sz);
                    printf("Die Quersumme s der Zahl %ld ist %ld\n",x,sx);
                } else if(sz>sx && sz>sy && sx>=sy){
                    printf("die Quersumme s der Zahl %ld ist %ld\n",z,sz);
                    printf("Die Quersumme s der Zahl %ld ist %ld\n",x,sx);
                    printf("Die Quersumme s der Zahl %ld ist %ld\n",y,sy);
                } else if(sz>sx && sz>sy && sy>sx){
                    printf("die Quersumme s der Zahl %ld ist %ld\n",z,sz);
                    printf("Die Quersumme s der Zahl %ld ist %ld\n",y,sy);
                    printf("Die Quersumme s der Zahl %ld ist %ld\n",x,sx);
                } else if (sx==sy && sx==sz && sy==sz){
                    printf("Die Quersumme s der Zahl %ld ist %ld\n",x,sx);
                    printf("Die Quersumme s der Zahl %ld ist %ld\n",y,sy);
                    printf("die Quersumme s der Zahl %ld ist %ld\n",z,sz);
                }
// the big if tree is just a sorting "algorithm" it sorts the values of checksums 

            }if (z < 0){ //check for negative number z
                printf("Falsche Eingabe: Minus Zahl"); //error
                exit(0);
            }if (z > max_long){ // cant exceed Max value of long
                printf("Falsche Eingabe: Zahl overflowed long");// error
                exit(0);
            }
        }if (y < 0){ //check for negative number y
            printf("Falsche Eingabe: Minus Zahl"); // error
            exit(0);
        }if (abs(y) > max_long){ // cant ewxceed max value of long
            printf("Falsche Eingabe: Zahl overflowed long"); /error
            exit(0);
        }

    }if (x < 0){ //check for negative numbers
        printf("Falsche Eingabe: Minus Zahl"); // error
        printf("%ld",x);
        exit(0);
    }
    if (x > max_long){ // cant exceed max of long
        printf("Falsche Eingabe: Zahl overflowed long"); // error
        exit(0);
    }

    return 0;
}

【问题讨论】:

  • 您所有的quersumme_X 函数都是相同的。为什么你需要 3 个函数来做同样的事情?
  • 我不知道如何给一个递归 3 个值以及如何让它返回 3 个值,这就是我选择进行单独递归的原因,因为这对我来说更容易
  • 没有递归。您可以只编写一个函数,并在每个需要校验和的地方调用它。 long sx = quersumme(x); ... long sy = quersumme(y);
  • 这是函数的主要特点之一,同一个函数可以调用任意多次。
  • 如果要检测负数,只要勾选if (x &lt; 0),报错即可。

标签: c


【解决方案1】:

最好的是使用fgets()将用户输入的读入字符串,然后解析字符串。

假设你被 scanf() 卡住了(太糟糕了)。

首先,检查返回值

// scanf("%ld",&y);
if (scanf("%ld",&y) != 1) {
  printf("Non-numeric input, end-of-file or input error");
  exit(0);
}

现在读取下一个字符

unsigned char ch;
if (scanf("%c",&ch) != 1) {
  printf("Failed to read next character");
  exit(0);
}
if (!isspace(ch)) {
  printf("Unexpected character following a number %d %c\n", ch, ch);
  exit(0);
}

现在检查范围

if (y < min_long || y > max_long) {
  printf("Out of range %ld\n", y);
  exit(0);
}

存在简化。


再次使用fgets()更好。

一个健壮但未经检查的例子:

#define LINE_SZ 100 // Max expected line size
char buf[LINE_SZ * 2]; // Let us read even up to 2x expected

if (fgets(buf, sizeof buf, stdin) == NULL) {
  printf("Nothing read\n", y);
  exit(EXIT_FAILURE);
}

errno = 0;
char *endptr;
long y = strtol(buf, &endptr, 0);
if (buffer == endptr) {
  printf("Non-numeric input \"%s\"\n", buf);
  exit(EXIT_FAILURE);
}

if (errno || y < long_min || long_max) {
  printf("Input \"%s\" outside [%ld %ld] range\n", buf, long_min, long_max);
  exit(EXIT_FAILURE);
}

// Skip trailing white-space
while (isspace((unsigned char)*endptr)) {
  endptr++;
}
if (*endptr) {
  printf("Trailing junk in \"%s\"\n", buf);
  exit(EXIT_FAILURE);
}

printf("Success %ld\n", y);

如果您无法使用fgets()读入字符串,请尝试

char buf[100];
if (scanf(" %99[^\n]", buf) == 1) {
  // OK, now process the string

【讨论】:

  • 我希望我可以使用它,但他们指定需要使用 scanf,至于您的示例,isspace() 是什么类型的函数,它检查是否输入了字符?
  • @MeilenWeit 1) “但他们指定需要使用 scanf”--> 考虑到您正在学习 1990 年代之前的标准。叹。 2)isspace(ch)(来自&lt;ctype.h&gt;)测试字符是否为空格,例如' ''\n''\t''\r'等。
  • 当您说“非数字输入”时,您是在进行有根据的猜测;例如,stdin 可能已关闭。 errno 可能有更多信息,如果你想要?
  • @Neil True,当scanf("%ld",&amp;y) != 1 时,不仅是非数字输入文本,还可能是文件结尾或输入错误。 C 标准库未指定 errno 出于任何原因由 scanf() 设置 - 也许您正在考虑一些实现扩展?代码可以使用feof()ferror() 来区分EOF 返回。
【解决方案2】:

long 类型不能存储十进制值,scanf 将始终尝试将用户输入的内容与您告诉它期望的值类型相匹配。

在您的情况下,%ld 表示如果用户输入十进制数字,scanf 将忽略“。”以及它之后的所有内容,并且只在“。”之前放置数字。在y

在 C 中有一种方法可以解决这个问题:

从用户那里读取一个字符串并检查其中的字符以确保它们都是数字(或者没有小数点或您需要检查的任何其他内容)。

然后你可以使用atol将字符串转换为long

无论如何,您都应该检查scanf 返回的值。

这通常不会在初学者课程中教授,但 scanf 会返回用户的多少项目符合您的期望并存储在您提供的变量中。

在您的情况下,如果输入了有效的整数,它应该返回 1。
此方法不会告诉您用户输入的是十进制数还是单词而不是自然数,但您会知道输入是否有效。

【讨论】:

  • scanf 将忽略”“十进制数”和“不在y 中放入任何内容”是不正确的。 scanf 逐个字符匹配,因此输入“34.56”将匹配“%ld”直到出现“.”,scanf 将在相应对象中存储 34 并返回 1。此外,“十进制数”不应在此上下文中用于表示其中带有小数点的数字;它是指使用十进制而不是十六进制或二进制的数字还是带小数点的数字,这是模棱两可的。 OP 可能使用了术语,但我们澄清了措辞,而不是继续模棱两可。
  • strtol 应该用于转换为long 而不是atol,因为它为错误检查提供了足够的信息。
  • 非常感谢,这很好地解释了为什么我的程序运行但在我输入十进制数后不扫描任何内容,但是为什么 x y z 的 printf 会将小数点 3.5 的整数返回到3 NVM 有人已经解释过了
  • @EricPostpischil 感谢您指出有关scanf 的错误,我修复了该帖子。关于使用“十进制数”,虽然我同意,但我总是尝试使用与提问者相同的术语,除非它们非常不适合确保提问者理解我的答案。我知道 SO 是这样,每个人都可以使用答案,而且它是为说英语的人设计的,但并不是这里的每个人都是以英语为母语的人,而提问的人目前最需要答案。
猜你喜欢
  • 1970-01-01
  • 2016-01-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-07-22
  • 1970-01-01
  • 2017-04-23
  • 1970-01-01
相关资源
最近更新 更多