C 字符串行为和 atoi 函数

标签 c string atoi gets

我想知道为什么 int 的两个值不验证 if 条件,即使它是 true。 printf 显示两者相等。

缓冲区溢出是否会影响 if 条件的行为,从而破坏其他代码段的行为。

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

  int main(void) {
    srand(time(NULL));
    char instring[2]; // when this increases somehow I get the right behavior
    int inint;
    int guess;
    guess = rand() % 127;
    inint = ~guess;
    printf("%i\n", guess); //testing with printf()
    while (guess != inint) {
      printf("Guess Number\r\n");
      gets(instring);
      inint = atoi(instring);
      printf("%i\n", inint);

      if (inint > guess) {
        printf("%i\n", inint);
        puts("too high");
      } else if (guess > inint) {
        puts("too low");
      } else {
        puts("right");
      }
    }
    return 0;
  }

最佳答案

问题确实出在这里。

char instring[2];

现在让我们考虑一下这一行。

gets(instring);

假设您输入 10 并按 Enter 键。 instring 中将包含三个字节。

  1. 1
  2. 0
  3. 终止 null。

instring 只能容纳两个 个字节,但gets 无论如何都会塞入(至少)三个 字节。该额外的字节将溢出到相邻的内存中,从而破坏其他一些变量的内存,从而导致一些奇怪的错误。

这就是为什么使 instring 足够大以容纳 gets 的结果来修复程序。

为了在处理字符串时避免这种情况,请使用将自身限制为可用内存的函数。在这种情况下fgets .

fgets(instring, sizeof(instring), stdin);

这将限制自己只能读取 instring 所能容纳的内容。

一般来说,不要吝惜内存来读取输入。一种常见的做法是分配一个大缓冲区来读取输入,1024 是好的,并重用该缓冲区仅用于读取输入。数据被复制到大小更合适的内存中,atoi 可以有效地为您完成这项工作。

关于C 字符串行为和 atoi 函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49850276/

相关文章:

c - 在 Objective-C 中前向声明具有已定义数组大小的函数

java - 改变方法的返回值

java - 我怎么知道我的 GCM 消息是否足够小 (< 4kb) 可以发送? (如何获取字符串的大小?)

c - 在 C 中使用 atoi() 解析具有二进制值的字符数组

c - 从 C 中的 void 函数返回二维数组

c - ATSAM4s8b,如何等待 USB 设备连接

c - 从 *.tar.gz 的存储库下载库或从安装更好

python - 如何将变量作为值插入字典中

c - 如何转换我从文件 (char) 中获取的值并将这些值存储到 double 组中?

c - atoi (argv[1]) 的返回值始终为 0