C字符串行为和atoi函数

时间:2018-04-16 05:41:47

标签: c string atoi gets

我想知道为什么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;
  }

1 个答案:

答案 0 :(得分:1)

问题确实在这里。

char instring[2];

现在让我们考虑一下这条线。

gets(instring);

我们假设您输入10并按Enter键。进入instring的内容是三个字节。

  1. 1
  2. 0
  3. 终止空。
  4. instring只能保存两个字节,但gets无论如何都会推送(至少)三个。额外的字节会溢出到相邻的内存中,破坏了其他变量的内存,造成了一些奇怪的错误。

    这就是为什么让instring大到足以保存gets结果的原因。

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

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

    这将仅限于阅读尽可能多的instring

    一般情况下,不要吝啬内存来阅读输入。通常的做法是分配一个大缓冲区用于读取输入,1024是好的,并重用该缓冲区仅用于读取输入。数据被复制到更适当大小的内存中,atoi有效地为您做好了。