【问题标题】:Trouble with function calling a pointer in C [duplicate]在C中调用指针的函数有问题[重复]
【发布时间】:2014-02-22 01:22:49
【问题描述】:
 char *userinput(void){
        char input[22];
        fgets(input,22,stdin);
        char *inputpoint;
        inputpoint=input;
        return inputpoint;
}

这个函数应该简单地接收用户输入的字符串并返回它。 我在main中调用函数如下

        float arrests;
        float money;
        //print menu
        menuprint();
        //Take first User input    
        char *inputpoint;
        inputpoint=userinput();
        char input[22];
        input=inputpoint;
        printf("\nYou entered: %s\n",input);        

return 0;
}

我对编码尤其是指针比较陌生。我不知道为什么这段代码没有打印出输入的字符串。请帮忙

【问题讨论】:

  • input 被分配在userinputs 堆栈上,所以当它被返回(并且堆栈帧被展开)时,你只会得到一个指向垃圾的指针。
  • 一旦userinput 退出,其中的所有自动变量都不再可寻址。现在考虑那个函数返回,然后重读我的第一句话。一旦函数存在,返回的地址是不确定的,因此任何对它的使用都是未定义的行为
  • 返回到 main 的指针可能仍在边界内并指向堆栈上的 something,但谁知道它实际指向的是什么 (可能在 printf 的堆栈中)。我们甚至不会讨论 input=inputpoint 的愚蠢之处......您正在尝试覆盖应该是只读指针的内容,而不是将字符串传输到 inputl。

标签: c arrays string function pointers


【解决方案1】:

我在这里看到很多错误。

您似乎没有声明输入点。还是在其他地方声明?

还有你为什么要那样做你的阅读输入。对于这样一个简单的任务来说似乎太复杂了。请参阅下面的此解决方案及其下方的讨论。

void read(char *out){

  scanf("%22s",&out[0]);
  printf("%s\n", out);

}

int main(void) {

  char  chars2[22];
  read(chars2);
  printf("%s\n", chars2);
  return 0
}

您的解决方案的一个核心问题是,在 C 函数中不能返回数组,这与许多其他语言(如 Java)允许这样做不同。所以我们必须变得更有创意。我们可以做的是向我们的 read 方法传递一个内存引用,该引用指向我们想要通过参数更新的值。

&(地址)运算符允许 scanf 访问第一个数组元素的内存位置,以便它可以用输入的内容填充数组。输入的最大长度为 22 个字符以匹配 char 数组。因此,如果输入更多,则忽略 22 之后的任何内容。

【讨论】:

  • & 实际上是错误的。 scanf("%22s") 需要 char * 而你传递的是 char (*)[22]
  • 好点我的意思是把 &name[0]
  • 另外,&out[0] 只是写out 的一种更冗长的方式。
  • 是的,这是另一个好点,但我想展示实际发生的情况。
【解决方案2】:

基本问题是您要返回一个指向局部变量的指针。当userinput 返回时,它的堆栈帧被释放以供下一个调用 (printf) 的函数重用,但指针仍然指向它,因此您打印垃圾或崩溃。

【讨论】:

    【解决方案3】:

    你没有说明你遇到了什么实际问题,但在这种情况下很清楚。如果您在编译器上启用了警告,它应该会告诉您您正在返回局部变量的地址。这是未定义的行为,你不能这样做。

    这里有两种常见的方法。一种是通过将位置作为函数参数传递来提供位置:

    void userinput( char input[22] )
    {
        fgets(input, 22, stdin);
    }
    

    另一种是动态分配。在这种情况下,您可以按当前的方式声明您的函数,但使用malloc,或者只使用strdup

    char *userinput(void)
    {
        char input[22];
        fgets(input, 22, stdin);
        return strdup(input);
    }
    

    请注意,如果您使用动态内存,则需要在使用完后对其进行清理:

    char *inputpoint = userinput();
    printf("\nYou entered: %s\n", inputpoint); 
    free(inputpoint);
    

    现在我注意到另一个问题:

    input = inputpoint;
    

    上面是分配一个指向数组的指针。这是不合法的,您的编译器应该会发出错误。显然你想要复制字符串。您可以为此使用strncpy

    strncpy( input, inputpoint, 22 );
    

    【讨论】:

      猜你喜欢
      • 2021-07-11
      • 2013-03-11
      • 1970-01-01
      • 2017-12-03
      • 2017-01-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-05-31
      相关资源
      最近更新 更多