c - 有没有办法让我的 do-while 条件在间隔之间起作用?
问题描述
我正在尝试使用 long 获得一个必须介于 13 到 16 之间的数字,然后我需要将 long 转换为字符串,用 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);
解决方案
正如其他人指出的那样,along
只能保证包含最多 32 位或 +/- 2,147,483,647。它可能更适合,但不能保证。要适合 10**17,您需要 64 位或long long
. 或者,您可以使用固定宽度的整数类型,例如int64_t
将映射到适当的整数类型。
您使用的方法有点折磨。get_long
正在将输入读取为字符串,将其转换为 a long
,然后将其转换回字符串以检查长度。
相反,读取该行、将其更改为一个数字sscanf
并检查它是否在 1e13 和 1e17 之间更简单、更快捷。
更新:@user3629249 在评论中指出我们必须考虑负数。为此,我们采用 的绝对值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);
推荐阅读
- c# - 将 json 反序列化为字典
在 C# 应用程序中 - javascript - HTML 选项卡内容作为绘图对象
- python-3.x - Python dict + RuntimeError:尝试反序列化 CUDA 设备上的对象
- r - 在base R中的一个图中使用相同的变量绘制两个箱线图
- javascript - 在 Web 应用程序中从大文件中读取许多小文件
- javascript - 是的,Formik 没有 Datepicker 值
- php - HyperDB 会根据查询自动选择使用哪个数据库吗?
- javascript - 从 javascript 中的 JSON 对象中删除特定的数组元素
- vscode-extensions - 在 vscode 扩展中显示信息消息时将键分配给默认按钮选项?
- c++ - PortAudio 不输出清晰的音频