C 字符串行为和 atoi 函数

C strings behavior, and atoi function

我想知道为什么int的两个值不验证if条件,即使它为真。 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 并按回车键。将进入 instring 的是三个字节。

  1. 1
  2. 0
  3. 终止空值。

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

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

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

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

这将限制自己只阅读它可以容纳的内容 instring

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