有没有一种方法可以使我的间隔条件在两次间隔之间工作?

时间:2019-08-03 21:02:31

标签: c cs50

我试图使用长号获取必须在13到16之间的数字,然后我需要将长号转换为字符串,使用strlen进行测量,并验证它是否为13到16之间的数字。

我的问题是,无论我输入哪个数字,都无法满足while条件的要求

我试图改变while的条件,试图通过使用for循环将其除以10来测量long的长度……没有任何效果。

long card;
char str[17];
int len;

    do
        {
            card = get_long("Number: ");
            snprintf(str, 17, "%ld", card);
            len = strlen(str)-1;
        } 
        while (len >= 13 || len <=16);

2 个答案:

答案 0 :(得分:1)

为什么不只是!

if(card >= 1000000000000 && card < 10000000000000000){
do_somthing();}

答案 1 :(得分:1)

正如其他人指出的那样,long仅保证包含最多32位或+/- 2,147,483,647。它可能更合适,但不能保证。要适合10 ** 17,您需要64位或long long。另外,您可以像int64_t一样使用fixed width integer types,它将映射到适当的整数类型。

您使用的方法有些折磨。 get_long将输入作为字符串读取,将其转换为long,然后将其重新转换为字符串以检查长度。

相反,读取行,使用sscanf将其更改为数字并检查它是否在1e13和1e17之间是更简单,更快的方法。

更新@user3629249 points out in the comments我们必须考虑负数。为此,我们用llabs取绝对值。

我没有CS50,我也不是粉丝。我发现它的抽象对学习C有害。因此,在常规C中,这就是get_long_long的基本工作。

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

#define DIGITS13 10000000000000LL
#define DIGITS17 100000000000000000LL

long long card;
long long abs_card;
char line[1024];

do {
    printf("Number: ");
    if( !fgets(line, sizeof(line), stdin) ) {
        break;
    }
    if( sscanf(line, "%lld", &card) != 1 ) {
        printf("Not a number.\n");
        continue;
    }

    abs_card = llabs(card);
}
while( abs_card < DIGITS13 || DIGITS17 <= abs_card);

我添加了一些宏,以便更轻松地跟踪正在发生的事情。

在CS50中,它可能看起来像...

long long card;
long long abs_card;

#define DIGITS13 10000000000000LL
#define DIGITS17 100000000000000000LL

do {
    card = get_long_long("Number: ");
    abs_card = llabs(card);
} 
while(abs_card < DIGITS13 || DIGITS17 <= abs_card);