C 从函数返回字符串会产生垃圾

C 从函数返回字符串会产生垃圾,c,string,scanf,C,String,Scanf,这个简单的程序有点麻烦。我可以通过将response[10]作为一个全局变量来解决这个问题,但我不想这样做。程序测试是否有正确的响应,但返回字符串是垃圾: #include <stdio.h> #include <string.h> char *user_string(char *Setting_Type[]); int main() { char *response; char *test_names[2] = {"Test", "test"}; printf("

这个简单的程序有点麻烦。我可以通过将response[10]作为一个全局变量来解决这个问题,但我不想这样做。程序测试是否有正确的响应,但返回字符串是垃圾:

#include <stdio.h>
#include <string.h>

char *user_string(char *Setting_Type[]);

int main()
{
char *response;
char *test_names[2] = {"Test", "test"};

printf("Enter \"Test\" or \"test\": ");
response = user_string(test_names);
printf("\nCorrect! Your input is: %s\n", response);

return 0;
}
char *user_string(char *Setting_Type[])
{
int loop = 1;
char response[10];
char *response_string;

while(loop = 1)
    {
    scanf("%s", &response);
    response_string = response;

    if(strcmp(response_string, Setting_Type[0]) != 0 && strcmp(response_string, Setting_Type[1]) != 0)
        printf("\nWrong! Please try again: ");
    else
        break;
    }

return response_string;
}
#包括
#包括
字符*用户\字符串(字符*设置\类型[]);
int main()
{
字符*响应;
char*test_名称[2]={“test”,“test”};
printf(“输入\“Test\”或\“Test\”:);
响应=用户字符串(测试名称);
printf(“\n正确!您的输入是:%s\n”,响应);
返回0;
}
字符*用户\字符串(字符*设置\类型[])
{
int循环=1;
字符响应[10];
字符*响应_字符串;
while(循环=1)
{
scanf(“%s”,响应(&R));
响应\字符串=响应;
if(strcmp(响应字符串,设置类型[0])!=0和strcmp(响应字符串,设置类型[1])!=0)
printf(“\n错误!请重试:”;
其他的
打破
}
返回响应字符串;
}

response
user\u string()
的本地数组,它将在函数返回时超出范围,您不能从
main()
使用它。您需要在
user\u string()
中为它存储
malloc()
,或者从
main()
传入一个缓冲区。这个问题有很多重复项。

您正在返回一个本地数组的地址,该数组在return语句之后不再存在

同样,这一行
scanf(“%s”,&response)
引入了缓冲区溢出的可能性。

您的
scanf()
函数需要编辑
scanf(“%s”,&response)
scanf(“%s”,响应)
这将解决部分问题

既然您不想使用globals,为什么不在其中添加另一个参数呢

字符*用户\字符串(字符*设置\类型[],字符*响应\字符串)

您必须为它分配内存,并在调用函数(
main()
)中释放它,但在这种情况下它可以工作。(在当前使用中,确实应该为它提供一些内存)

示例:[已测试,有效]

#include <ansi_c.h>
#include <stdio.h>
#include <string.h>

char *user_string(char *Setting_Type[], char *s);

int main()
{
    char *response;
    char *test_names[2] = {"Test", "test"};
    char *resp;

    resp = malloc(80);//I picked 80, you can pick something more appropriate
    response = malloc(80);//I picked 80, you can pick something more appropriate
    printf("Enter \"Test\" or \"test\": ");
    //user_string() returns a char *, so just call it in printf()
    printf("\nCorrect! Your input is: %s\n", user_string(test_names, response));
    free(resp);
    free(response);

    return 0;
}

char *user_string(char *Setting_Type[], char *response_string)
{
    int loop = 1;
    char response[10];

    while(loop == 1)
        {
        scanf("%s", response); //removed &
        strcpy(response_string,response);//changed from `=` to `strcpy()`

        if(strcmp(response_string, Setting_Type[0]) != 0 && strcmp(response_string, Setting_Type[1]) != 0)
            printf("\nWrong! Please try again: ");
        else
            break;
        }

    return response_string;
}
#包括
#包括
#包括
字符*用户\字符串(字符*设置\类型[],字符*s);
int main()
{
字符*响应;
char*test_名称[2]={“test”,“test”};
char*resp;
resp=malloc(80);//我选择了80,你可以选择更合适的
response=malloc(80);//我选择了80,你可以选择更合适的
printf(“输入\“Test\”或\“Test\”:);
//user_string()返回一个char*,所以只需在printf()中调用它
printf(“\n正确!您的输入是:%s\n”,用户字符串(测试名称,响应));
免费(resp);
自由(反应);
返回0;
}
字符*用户\字符串(字符*设置\类型[],字符*响应\字符串)
{
int循环=1;
字符响应[10];
while(循环==1)
{
scanf(“%s”,响应);//已删除&
strcpy(response_string,response);//从`=`更改为` strcpy()`
if(strcmp(响应字符串,设置类型[0])!=0和strcmp(响应字符串,设置类型[1])!=0)
printf(“\n错误!请重试:”;
其他的
打破
}
返回响应字符串;
}

您的意思是在条件语句中使用赋值运算符吗<代码>while(循环=1)
。应该是吗?:
while(loop==1)
代码中有几个问题需要解决,主要与字符串处理、范围问题以及内存分配和释放有关。在这篇评论中有很多需要解决的问题。见下面我的答案。@blastfurny-不同意sited的具体原因,因为OP在他的查询中不包括这个问题。我同意,他提出的问题直接涉及范围的根本问题,但与许多C语言新手一样,范围并不在他所观察的最前沿。了解范围最终会解决他的问题,但现在,了解字符串被乱码的原因,如何处理从函数调用到返回的字符串的工作或不工作的技术是允许此问题保持活动状态的充分理由。@Ryker确定问题是否重复不仅仅是这些问题是否在问同一件事;如果基本问题最终是相同的,它们也可以标记为重复。此外,如果您想获得真正的技术性,还存在“为什么我的字符串被乱码”的问题,这也是原因。更不用说应该编写
scanf(“%s”,response)
(no&for char*)@ryker由于
&response==response
,所以它可以双向工作。感谢您的详细回复。我只是在学习malloc,并不完全理解它。用户的输入不是只在响应[10]中输入10个字符,其余的进入标准输入吗?不客气,谢谢您的接受!在
user\u string()
中,响应[10]最多可以占用stdin中的9个字符,必须为nul终止符“\0”
scanf()
从stdin中引入数据留下一个字符,希望它符合格式字符串“%s”,在这种情况下,它将在该输入中附加“\0”。如果您在指针(例如响应字符串)中输入10个(或更多)字符,则会出现非致命警告“尝试写入字符串以外的内容”,如果您
strcpy()
所拥有的内容,则会出现致命错误。用这段代码试试,并在调试中使用断点,这样您就可以查看变量了。