使用fgets的函数返回0

时间:2019-03-23 12:30:38

标签: c fgets

我正在使用RPN(反波兰表示法)编写一个用于arduino的小型计算器。因为我还想使代码在x86笔记本电脑上运行,并为计算器程序设置一些配置参数,所以我使用诸如input_strinput_intoutput_str之类的函数,因此可以实现对于我的笔记本电脑或arduino,它们是不同的。

现在在input_str

char *input_str(void) {
  #if IS_IO_STDIO
    char iobuf[IO_BUF_SIZE];
    fgets(iobuf, IO_BUF_SIZE, stdin);
    if (IS_DEBUG) { printf("1. iobuf: %s\n", iobuf); }
    if (IS_DEBUG) { printf("2. iobuf ptr: %p\n", iobuf); }
    return iobuf;
  #elif IS_IO_SERIAL
    // TODO: implement serial input str
  #endif // IS_IO_STDIO
}

使用fgets获取用户输入(以供将来计算),1. iobuf printout正确打印出用户键入的字符串,2. iobuf ptr正确打印出{{1 }}不等于0。

当我在ipo循环中使用char *的返回值时:

input_str

int ipo_loop(int16_t *stack, int *sp) { // TODO: implement real ipo loop int is_exit = false; char *iobuf; while (!is_exit) { iobuf = input_str(); if (IS_DEBUG) { printf("3. iobuf ptr: %p\n", iobuf); } output_str(iobuf); } return 0; } 突然显示3. iobuf ptr现在指向0。

iobuf为什么突然变成0?

iobufchar[IO_BUF_SIZE]是否存在类型转换问题?

1 个答案:

答案 0 :(得分:4)

在下面的代码中

char *input_str(void) { 
  char iobuf[IO_BUF_SIZE];
  fgets(iobuf, IO_BUF_SIZE, stdin);
  /* some code */
  return iobuf; 
}

您将返回本地数组iobuf的地方导致未定义行为。在iobuf中声明的char数组input_str()具有局部范围,当控件从该函数退出时,其范围结束。

例如,如果您可以使用-Wall-Wextraflags来编译代码,例如

gcc -Wall -Wextra -Werror -Wpedantic test.c

编译器可能会警告您

  警告:与局部变量关联的堆栈存储器地址   'iobuf'返回了[-Wreturn-stack-address]

上面的编译器警告会告诉您有关该问题及其可读性的所有信息。

创建动态数组并返回它,而不是返回本地数组。对于例如

char *iobuf = malloc(IO_BUF_SIZE * sizeof(*iobuf));
/* @TODO if malloc was success i.e check return value of malloc */

之后,像下面一样使用fgets()扫描数据。

  fgets(iobuf, IO_BUF_SIZE, stdin);

然后检索动态数组

  return iobuf;

在完成动态返回的数组后,调用API ipo_loop()时,请不要忘记free以避免内存泄漏。例如

iobuf = input_str();
/* processing with iobuf.. here iobuf is dynamically returned array */
free(iobuf);