【问题标题】:C outputting variable positions (pointers) instead of actual values [duplicate]C输出变量位置(指针)而不是实际值[重复]
【发布时间】:2016-03-08 17:35:14
【问题描述】:

我正在做一个课堂项目,我想做一些额外的事情并对我的数据进行验证。问题似乎发生在num1 = num1Input(和num2 = num2Input),它正在获取位置(我假设)而不是实际输入值

int main(void) {
    //variables
    char num1input[10];
    char num2input[10];

    int length, i;
    int num1 = 0;
    int num2 = 0;
    int countErrors1 = 0;
    int countErrors2 = 0;

    bool correct1 = false;
    bool correct2 = false;

    //--end of variable declarations--//

    do {
        printf("Please enter a number: ");
        scanf("%s", num1input);
        length = strlen(num1input);
        for (i = 0; i < length; i++) {
            if (!isdigit(num1input[i])) {
                countErrors1++;
            }
        }
        if (countErrors1 > 0) {
            printf("Input is not a number \n");
        } else {
            correct1 = true;
        }
    } while (correct1 == false);
    num1 = num1input;

    do {
        printf("Please enter second number: ");
        scanf("%s", num2input);
        length = strlen(num2input);
        for (i = 0; i < length; i++) {
            if (!isdigit(num2input[i])) {
                countErrors2++;
            }
        }
        if (countErrors2 > 0) {
            printf("Input is not a number \n");
        } else {
            correct2 = true;
        }
    } while (correct2 == false);
    num2 = (int)num2input;

    printf("%d %d \n", num1, num2);

    int addition = num1 + num2;
    int substraction = num1 - num2;
    int multiplication = num1 * num2;
    float division = num1 / num2;

    printf("Addition: %d Subtraction: %d Multiplication: %d Division: %.1e", addition, substraction, multiplication, division);

    getch();
}

【问题讨论】:

  • C 在强制转换时不进行十进制到二进制的转换。您正在寻找strtol
  • 我只希望num1Input中的值存储在num1中。我能做什么?
  • 你使用strtol,就像我说的。 (另外,忘记你曾经听说过 scanf,它是按规定损坏的;在 C 中用于用户输入的正确函数是 getline(如果可用),否则是 fgets。)
  • "多做一点,对我的数据进行验证" --> 太好了!请注意isdigit(num1input[i]) 将失败'-'。研究strtol().

标签: c


【解决方案1】:

您不能将字符串转换为具有诸如num1 = num1input; 之类的强制转换的数字。你需要从&lt;stdlib.h&gt;调用一个库函数:

#include <stdlib.h>

...

num1 = atoi(num1input);

但是atoi 会忽略解析错误。为确保检测到溢出,您可以使用strtol(),如下所示:

#include <errno.h>
#include <limits.h>
#include <stdlib.h>

...

errno = 0;
char *endp;
long lval = strtol(num1input, &endp, 10);
if (endp == num1input || errno != 0 || lval < INT_MIN || lval > INT_MAX) {
    /* parse error detected:
     * you could print an error message.
     */
    if (lval < INT_MIN) lval = INT_MIN;  /* clamp lval as an int value. */
    if (lval > INT_MAX) lval = INT_MAX;
}
num1 = lval;

或者如果您想识别十六进制语法,例如0x10

num1 = strtol(num1input, NULL, 0);

同样适用于num2input

请注意,如果char 已签名且num1input[i] 具有负值,则isdigit(num1input[i]) 可能不正确。你应该写:

isdigit((unsigned char)num1input[i])

还要注意float division = num1 / num2; 将计算整数除法 并将结果转换为float。如果你想要浮点除法,你应该写:

float division = (float)num1 / num2;

最后请注意,建议使用double 而不是float 以获得更好的准确性。

这是一个更正和简化的版本:

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

/* simple implementation of strtoi(), inspired by elegant code from chux */
int strtoi(const char *s, char **endptr, int base) {
    long y = strtol(s, endptr, base);
#if INT_MAX != LONG_MAX
    if (y > INT_MAX) {
        errno = ERANGE;
        return INT_MAX;
    }
#endif
#if INT_MIN != LONG_MIN
    if (y < INT_MIN) {
        errno = ERANGE;
        return INT_MIN;
     }
#endif
    return (int)y;
}

int main(void) {
    char num1input[20];
    char num2input[20];
    char *endp;
    int num1, num2;

    for (;;) {
        printf("Please enter a number: ");
        if (scanf("%19s", num1input) != 1)
            return 1;
        errno = 0;
        num1 = strtoi(num1input, &endp, 10);
        if (errno == 0 && *endp == '\0')
            break;
        printf("Input is not a number\n");
    }

    for (;;) {
        printf("Please enter a second number: ");
        if (scanf("%19s", num2input) != 1)
            return 1;
        errno = 0;
        num2 = strtoi(num2input, &endp, 10);
        if (errno == 0 && *endp == '\0')
            break;
        printf("Input is not a number\n");
    }

    printf("%d %d\n", num1, num2);

    int addition = num1 + num2;
    int subtraction = num1 - num2;
    int multiplication = num1 * num2;
    double division = (double)num1 / num2;

    printf("Addition: %d Subtraction: %d Multiplication: %d Division: %g\n",
           addition, subtraction, multiplication, division);
    getch();
}

【讨论】:

  • 因建议 atoi 而被否决,它会默默地忽略错误。仅应为此目的推荐 strtol 家族。
  • 确实atoi 会忽略错误,但strtol() 会解析并返回long,这需要进一步测试以检测溢出。为什么委员会没有为int 值规范化strtoi() 函数是不一致的。我会更新答案。
  • 是的,缺少strtoi 有点小问题。
  • @zwol:在现实生活中,我会实现和使用strtoi()
  • "为什么委员会没有规范化 strtoi()" --> long 最宽的整数类型。很容易根据需要从中制作strtoi() strtoshort() strtoschar() 等。
猜你喜欢
  • 1970-01-01
  • 2011-07-05
  • 1970-01-01
  • 2020-09-06
  • 2020-07-27
  • 2017-05-25
  • 2021-07-22
  • 2022-01-22
  • 1970-01-01
相关资源
最近更新 更多