为什么高值输入会阻止数组使用 C 中的实际输入值?

如何解决为什么高值输入会阻止数组使用 C 中的实际输入值?

我正在创建一个函数,该函数使用 scanf_s 获取一个值并将其转换为二进制值。该功能运行良好...直到我输入了一个非常高的值。

我也在 VS 2019 上用 C 语言在 x64 上做这个

以防万一,我正在使用

main(int argc,char* argv[]) 

用于主函数。

因为我不确定到底发生了什么,所以我猜这是整个代码。

BinaryGet()
{
// Declaring lots of stuff
int x,y,z,d,b,c;
int counter = 0;
int doubler = 1;
int getb;
int binarray[2000] = { 0 };

// I only have to change things to 1 now,am't I smart?
int binappend[2000] = { 0 };


// Get number
printf("Gimme a number\n");
scanf_s("%d",&getb);



// Because why not
printf("\n");

// Get the amount of binary places to be used (how many times getb divides by 2)
x = getb;
while (x > 1)
{
    d = x;
    counter += 1;

    // Tried x /= 2,gave me infinity loop ;(
    x = d / 2;
}


// Fill the array with binary values (i.e. 1,2,4,8,16,32,etc)
for (b = 1; b <= counter; b++)
{
    binarray[b] = doubler * 2;

    doubler *= 2;

    
}


// Compare the value of getb to binary values,subtract and repeat until getb = 0)
c = getb;
for (y = counter; c >= 1; y--)
{   

    // Printing c at each subtraction

    
    printf("\n%d\n",c);

    // If the value of c (a temp variable) compares right to the binary value,subtract that binary value
    // and put a 1 in that spot in binappend,the 1 and 0 list
    if (c >= binarray[y])
    {

        c -= binarray[y];
        binappend[y] += 1;
    }


    // Prevents buffer under? runs
    if (y <= 0)
    {
        break;
    }
}

// Print the result
for (z = 0; z <= counter; z++)
{
    printf("%d",binappend[z]);
}
}

问题是,当我输入值 999999999999999999(18 位)时,它只打印 0 一次并结束函数。数字的值无关紧要,18个将产生相同的结果。

然而,当我输入 17 位数字时,它给了我这个:

99999999999999999

// This is the input value after each subtraction
1569325055

495583231

495583231

227147775

92930047

25821183

25821183

9043967

655359

655359

655359

655359

131071

131071

131071

65535

32767

16383

8191

4095

2047

1023

511

255

127

63

31

15

7

3

1


// This is the binary
1111111111111111100100011011101

它给我的二进制值是 31 位数字。我觉得奇怪的是,在 32,一个方便的数字,它跳出来了,所以我把第 32 个二进制位的值减去 1 (2,147,483,647) 并且它起作用了。但是加 1 给我 0。

改变数组的类型(unsigned int 和 long)并没有改变这一点。也没有更改数组括号中的值。我试着搜索看看它是否是 scanf_s 的限制,但什么也没找到。

我确定(我认为)这不是数组,但可能我正在用函数做一些愚蠢的事情。有人可以帮忙吗?我给你一个远距离高五。

解决方法

问题确实与您注意到的数字的二次幂大小有关,但在此调用中:

scanf_s("%d",&getb);

%d 参数表示它正在读入一个有符号整数,在您的平台上可能是 32 位,并且由于它是有符号的,这意味着它可以在正方向上达到 2³¹-1。

scanf() 和相关函数使用的转换说明符可以接受更大尺寸的数据类型。例如,%ld 将接受 long int,而 %lld 将接受 long long int。检查您平台的数据类型大小,因为 long intint 实际上可能是相同的大小(32 位),例如。在 Windows 上。

因此,如果您改用 %lld,您应该能够读取更大的数字,最多可达 long long int 的范围,但请确保将目标 (getb) 更改为匹配!此外,如果您对负数不感兴趣,请让类型系统帮助您并使用无符号类型:%llu 表示 unsigned long long

一些细节:

  1. 如果 scanf 或其朋友失败,则 getb 中的值是不确定的,即。未初始化,并从中读取未定义行为 (UB)。 UB 是 C 中极其常见的错误来源,您希望避免它。如果 getb 告诉您它有效,请确保您的代码仅从 scanf 读取。

  2. 事实上,通常不可能用 scanf 避免 UB 除非你完全控制输入(例如,你之前用其他一些无错误的软件写出来的) )。虽然您可以检查 scanf 和相关函数的返回值(它将返回它转换的字段数),但如果某个字段太大而无法适应您拥有的数据类型,则其行为未定义

  3. 关于 scanf etc. here 有更多详细信息。

  4. 为了避免不知道 int 的大小,或者 long int 在这个或那个平台上是否不同的问题,还有定义整数的 header stdint.h特定宽度的类型,例如。 int64_t。这些具有与 scanf() 一起使用的宏,例如 SCNd64。这些可以从 C99 开始使用,但请注意,Windows 在其编译器中对 C99 的支持是不完整的,可能不包括这一点。

  5. 不要对自己太苛刻,你并不笨,C 是一门难以掌握的语言,并且不遵循自最初设计以来发展起来的现代习语。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


依赖报错 idea导入项目后依赖报错,解决方案:https://blog.csdn.net/weixin_42420249/article/details/81191861 依赖版本报错:更换其他版本 无法下载依赖可参考:https://blog.csdn.net/weixin_42628809/a
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下 2021-12-03 13:33:33.927 ERROR 7228 [ main] o.s.b.d.LoggingFailureAnalysisReporter : *************************** APPL
错误1:gradle项目控制台输出为乱码 # 解决方案:https://blog.csdn.net/weixin_43501566/article/details/112482302 # 在gradle-wrapper.properties 添加以下内容 org.gradle.jvmargs=-Df
错误还原:在查询的过程中,传入的workType为0时,该条件不起作用 &lt;select id=&quot;xxx&quot;&gt; SELECT di.id, di.name, di.work_type, di.updated... &lt;where&gt; &lt;if test=&qu
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct redisServer’没有名为‘server_cpulist’的成员 redisSetCpuAffinity(server.server_cpulist); ^ server.c: 在函数‘hasActiveC
解决方案1 1、改项目中.idea/workspace.xml配置文件,增加dynamic.classpath参数 2、搜索PropertiesComponent,添加如下 &lt;property name=&quot;dynamic.classpath&quot; value=&quot;tru
删除根组件app.vue中的默认代码后报错:Module Error (from ./node_modules/eslint-loader/index.js): 解决方案:关闭ESlint代码检测,在项目根目录创建vue.config.js,在文件中添加 module.exports = { lin
查看spark默认的python版本 [root@master day27]# pyspark /home/software/spark-2.3.4-bin-hadoop2.7/conf/spark-env.sh: line 2: /usr/local/hadoop/bin/hadoop: No s
使用本地python环境可以成功执行 import pandas as pd import matplotlib.pyplot as plt # 设置字体 plt.rcParams[&#39;font.sans-serif&#39;] = [&#39;SimHei&#39;] # 能正确显示负号 p
错误1:Request method ‘DELETE‘ not supported 错误还原:controller层有一个接口,访问该接口时报错:Request method ‘DELETE‘ not supported 错误原因:没有接收到前端传入的参数,修改为如下 参考 错误2:cannot r
错误1:启动docker镜像时报错:Error response from daemon: driver failed programming external connectivity on endpoint quirky_allen 解决方法:重启docker -&gt; systemctl r
错误1:private field ‘xxx‘ is never assigned 按Altʾnter快捷键,选择第2项 参考:https://blog.csdn.net/shi_hong_fei_hei/article/details/88814070 错误2:启动时报错,不能找到主启动类 #
报错如下,通过源不能下载,最后警告pip需升级版本 Requirement already satisfied: pip in c:\users\ychen\appdata\local\programs\python\python310\lib\site-packages (22.0.4) Coll
错误1:maven打包报错 错误还原:使用maven打包项目时报错如下 [ERROR] Failed to execute goal org.apache.maven.plugins:maven-resources-plugin:3.2.0:resources (default-resources)
错误1:服务调用时报错 服务消费者模块assess通过openFeign调用服务提供者模块hires 如下为服务提供者模块hires的控制层接口 @RestController @RequestMapping(&quot;/hires&quot;) public class FeignControl
错误1:运行项目后报如下错误 解决方案 报错2:Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.8.1:compile (default-compile) on project sb 解决方案:在pom.
参考 错误原因 过滤器或拦截器在生效时,redisTemplate还没有注入 解决方案:在注入容器时就生效 @Component //项目运行时就注入Spring容器 public class RedisBean { @Resource private RedisTemplate&lt;String
使用vite构建项目报错 C:\Users\ychen\work&gt;npm init @vitejs/app @vitejs/create-app is deprecated, use npm init vite instead C:\Users\ychen\AppData\Local\npm-