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;
}