这段代码,它的工作正常并返回我想要的东西,但它在打印之前挂起了吗?

Ram*_*rar 0 c printf pointers function

我制作这个节目::

#include<stdio.h>

char *raw_input(char *msg);

main() {
char *s;
*s = *raw_input("Message Here Is: ");
printf("Return Done..");
printf(s);
}

char *raw_input(char *msg){
char *d;
    printf("%s", msg);
    scanf("%s",&d);
return d;
}
Run Code Online (Sandbox Code Playgroud)

这样做,它打印我的消息并扫描用户的输入,然后打印它,但是打印输出来自用户的问题是什么?

更新::

我需要raw_input函数.没有任何额外的呼叫就像这样

*s = *raw_input("Message Here");
Run Code Online (Sandbox Code Playgroud)

我不想用这个::

raw_input("Message Here Is: ", d);
....
Run Code Online (Sandbox Code Playgroud)

只想返回用户将输入的字符串.

UPDATE2 ::

来自jamesdlin回答(谢谢),现在我明白了我的问题是如何在这里返回一个分配的字符串:)

#include<stdio.h>
#define buffer 128

char *raw_input(char *msg);

main() {
char *s;
s = raw_input("Message Here Is: ");
printf("%s\n",s);
}

char *raw_input(char *msg){
char *d;
    printf("%s", msg);
    fflush(stdout);
    fgets(d, buffer, stdin); ## In this there is a problem
return d;
}
Run Code Online (Sandbox Code Playgroud)

现在,当我启动这个程序时,它打印消息,然后退出(结束)程序,而不从用户任何消息?

Pét*_*rök 5

您没有为其分配内存d,因此使用它scanf会导致未定义的行为.

实际上,它甚至比这更糟糕:你传递to 的地址,然后填充从控制台读取的整数.实际上,您使用整数值初始化指针,因此指针指向丛林中的某个位置.因此解除引用它是未定义的行为.[更新]:即使这不是全部:正如@Heath在下面指出的那样,这实际上允许您通过在控制台上输入足够长的输入来破坏您的调用堆栈: - (([/ Update]dscanf

更不用说你试图从函数中返回一个局部变量,一旦它超出范围就会被销毁.这应该更好:

void raw_input(char *msg, char *d);

main() {
    char d[128];

    raw_input("Message Here Is: ", d);
    printf("Return Done..");
    printf(d);
}

void raw_input(char *msg, char *d){
    printf("%s", msg);
    scanf("%s", d);
}
Run Code Online (Sandbox Code Playgroud)

很公平,这并不能阻止缓冲区溢出......但这足以说明我的观点.

更新:所以你想要在任何情况下返回一个分配的字符串(即一个char*指针)raw_input().AFAIK你有3个选择:

  • 返回调用者传入的指针作为参数(上面我的例子的一个小扩展):这是我更喜欢的那个.但是,这需要一个额外的函数参数(实际上是2,因为我们还应该在适当的解决方案中传递缓冲区的长度以避免缓冲区溢出).因此,如果您绝对需要坚持上面显示的功能签名,那么这不是一个选项.
  • 返回指向调用者和被调用者都可见的静态/全局缓冲区的指针:这是上述的变体,以避免修改函数签名.缺点是代码更难以理解和维护 - 您不知道该函数修改静态/全局变量而不实际查看其实现.这反过来也使单元测试更加困难.
  • 返回一个指向函数内部分配的缓冲区的指针 - 虽然技术上可行,但这是最糟糕的选择,因为你有效地传递了缓冲区的所有权; 换句话说,调用者必须记住释放返回的缓冲区.在一个像上面所示的简单程序中,这可能看起来不是一个大问题,但在一个大程序中,缓冲区可能会被传递到应用程序内的远处,所以很有可能没有人释放它最后,从而泄露了记忆.