C 这段代码,它的工作很好,并返回我想要的,但它挂起之前打印它?

C 这段代码,它的工作很好,并返回我想要的,但它挂起之前打印它?,c,function,pointers,printf,C,Function,Pointers,Printf,我制作这个程序:: #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

我制作这个程序::

#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;
}
我不想用这个::

raw_input("Message Here Is: ", d);
....
只想返回用户将输入的字符串

更新2::

从jamesdlin的回答(谢谢),,现在我很清楚,我的问题是如何在下面返回分配的字符串:)

#包括
#定义缓冲区128
字符*原始输入(字符*味精);
main(){
char*s;
s=原始输入(“此处的信息为:”);
printf(“%s\n”,s);
}
字符*原始输入(字符*味精){
char*d;
printf(“%s”,msg);
fflush(stdout);
fgets(d,buffer,stdin)####这里有一个问题
返回d;
}

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

您不会为
d
分配内存,因此在
scanf
中使用它会导致未定义的行为

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

更不用说您正试图从函数返回一个局部变量,该变量一旦超出范围就会被销毁。这应该可以更好地工作:

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);
}
公平地说,这并不能防止缓冲区溢出……但足以说明我的观点

更新:因此,在任何情况下,您都希望从
raw\u input()
返回分配的字符串(即
char*
指针)。假设您有3种选择:

  • 返回调用者作为参数传入的指针(上面示例的一个轻微扩展):这是我更喜欢的一个。但是,这需要一个额外的函数参数(实际上是2,因为我们还应该在适当的解决方案中传入缓冲区的长度,以避免缓冲区溢出)。因此,如果您确实需要遵守上面显示的函数签名,则这不是一个选项
  • 返回一个指向调用方和被调用方都可见的静态/全局缓冲区的指针:这是上述方法的一个变体,以避免修改函数签名。缺点是代码更难理解和维护-您不知道函数在没有实际查看的情况下修改静态/全局变量这反过来也使得单元测试更加困难
  • 返回一个指向函数内部分配的缓冲区的指针——虽然技术上可能,但这是最糟糕的选择,因为您实际上传递了缓冲区的所有权;换句话说,调用方必须记住释放返回的缓冲区。在一个简单的程序中,如上面所示,这似乎不是一个大的i虽然如此,但在一个大程序中,缓冲区可能会被传递到应用程序中很远的地方,因此最终没有人释放缓冲区,从而导致内存泄漏的风险很高

函数中的指针
d
未初始化。
scanf
将填充任意内存。相反,您需要传递一个缓冲区(字符数组)来填充它,并且必须在
main
中定义缓冲区,否则它将在返回之前被销毁(除非您执行动态分配,但这是另一种情况)。

您不能返回函数内部创建的变量指针。变量d在主函数中不再有效

试试这个: 1.在主函数中创建变量d 2.并将其传递给原始输入函数

void raw_input(char *msg, char *d)
#包括
字符*原始输入(字符*味精);
int main(){
char*s;
s=原始输入(“此处的信息为:”);
printf(“返回完成…”);
printf(“%s”,s);
免费的;
返回0;
}
字符*原始输入(字符*味精){
char*d;
d=malloc(20)
如果(d==0)返回0;
printf(“%s”,msg);
scanf(“%19s”,d);
返回d;
}
试试这个,应该行得通。其他答案指出了你的错误,正如我所看到的……我太慢了;)

编辑:确定,发现错误…已修复;)

编辑2: Max建议可以使用结构,下面是一些代码:

#include<stdio.h>

struct mystring{
    char str[20];
};

struct mystring raw_input(char *msg);

int main() {
    struct mystring input;
    input = raw_input("Message Here Is: ");
    printf("Return Done..");
    printf("%s", input.str);
    return 0;
}

struct mystring raw_input(char *msg){
    struct mystring input;
        printf("%s", msg);
        scanf("%19s", input.str);
    return input;
}
#包括
结构mystring{
char-str[20];
};
struct mystring原始输入(char*msg);
int main(){
结构mystring输入;
输入=原始输入(“这里的消息是:”);
printf(“返回完成…”);
printf(“%s”,input.str);
返回0;
}
struct mystring原始输入(char*msg){
结构mystring输入;
printf(“%s”,msg);
scanf(“%19s”,input.str);
返回输入;
}
试试这个实验:

#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)
{
    int value = 0;
    char *d;
    printf("%s", msg);
    scanf("%s",&d);

    if (value)
        printf("value has become %08X\n", value);
    return d;
}
#包括
字符*原始输入(字符*味精);
main(){
char*s;
s=原始输入(“此处的信息为:”);
printf(“返回完成…”);
printf(s);;
}
字符*原始输入(字符*味精)
{
int值=0;
char*d;
printf(“%s”,msg);
scanf(“%s”、&d);
如果(值)
printf(“值已变成%08X\n”,值);
返回d;
}
使用长度为3、4、5、7、8、9、11、12、13等字符的输入消息执行多个实验。查看整数变量
值的结果。您将看到,由于误用
scanf()
而通过传递
d
的地址,您允许
scanf()
销毁函数的局部变量,包括返回地址


这让我们回到了这个网站的名称。

如前所述,您没有为
scanf
分配内存。但永远不要使用
scanf
;很难正确使用并避免缓冲区溢出。请使用
fgets

从comp.lang.c常见问题解答:

还有,虽然和你无关
#include<stdio.h>

char *raw_input(char *msg);

int main() {
    char *s;
    s = raw_input("Message Here Is: ");
    printf("Return Done..");
    printf("%s", s);
    free(s);
    return 0;
}

char *raw_input(char *msg){
    char *d;
        d = malloc(20)
        if(d==0) return 0;
        printf("%s", msg);
        scanf("%19s", d);
    return d;
}
#include<stdio.h>

struct mystring{
    char str[20];
};

struct mystring raw_input(char *msg);

int main() {
    struct mystring input;
    input = raw_input("Message Here Is: ");
    printf("Return Done..");
    printf("%s", input.str);
    return 0;
}

struct mystring raw_input(char *msg){
    struct mystring input;
        printf("%s", msg);
        scanf("%19s", input.str);
    return input;
}
#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)
{
    int value = 0;
    char *d;
    printf("%s", msg);
    scanf("%s",&d);

    if (value)
        printf("value has become %08X\n", value);
    return d;
}
*s = *raw_input("Message Here Is: ");
printf("Return Done..");
printf(s);
*s = *raw_input("Message Here Is: ");
printf("Return Done..");
printf("%s\n", s);
*s = *raw_input("Message Here Is: ");
s = raw_input("Message Here Is: ");
char *raw_input(char *msg){
    char *d;
    printf("%s", msg);
    scanf("%s",&d);
    return d;
}