我制作这个节目::
#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功能。没有任何额外的打电话就是这样的
*s = *raw_input("Message Here");
我不想使用这个::
raw_input("Message Here Is: ", d);
....
只想返回用户将输入的字符串。
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;
}
现在,当我启动这个程序时,它打印信息,然后退出(结束)程序,而不是从用户那里得到任何消息???
答案 0 :(得分:5)
您没有为d
分配内存,因此在scanf
中使用它会导致未定义的行为。
实际上,情况甚至更糟:你将d
的地址传递给scanf
,然后填充从控制台读取的整数。实际上,您使用整数值初始化指针,因此指针指向丛林中的某个位置。因此解除引用它是未定义的行为。 [更新] :即使这不是全部:正如@Heath在下面指出的那样,这实际上允许您通过在控制台上输入足够长的输入来破坏您的调用堆栈: - ((< > [/更新] 强>
更不用说你试图从函数中返回一个局部变量,一旦它超出范围就会被销毁。这应该更好:
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);
}
足够公平,这并不能阻止缓冲区溢出......但这足以说明我的观点。
更新:,因此您希望在任何情况下都从char*
返回已分配的字符串(即raw_input()
指针)。 AFAIK你有3个选择:
答案 1 :(得分:2)
函数中的指针d
未初始化。 scanf
将填补任意记忆。相反,你需要传递一个缓冲区(字符数组)来填充它,缓冲区必须在main
中定义,否则它会在你返回它之前被销毁(除非你做动态分配,但是那是另一个故事。)
答案 2 :(得分:2)
#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;
}
试试这个,应该有效。其他答案指出你的错误,我可以看到......我要慢;)
编辑:好的,发现错误......修好了;)
EDIT2: 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;
}
答案 3 :(得分:2)
如上所述,您没有分配内存以用于scanf
。但永远不要使用scanf
;它很难正确使用并避免缓冲区溢出。使用fgets
。
来自comp.lang.c FAQ:Why does everyone say not to use scanf? What should I use instead?
此外,虽然与您的问题无关,但这段代码很危险:
*s = *raw_input("Message Here Is: ");
printf("Return Done..");
printf(s);
您将用户输入作为格式字符串直接传递给printf
,因此如果打印的字符串恰好包含%
个字符,则会受到格式字符串攻击的影响。更好:
*s = *raw_input("Message Here Is: ");
printf("Return Done..");
printf("%s\n", s);
另外,打印时可能需要一些换行符。也:
*s = *raw_input("Message Here Is: ");
不起作用,因为s
没有指向任何内容,因此您将取消引用垃圾指针。假设你修复raw_input
以返回一个已分配的字符串,它应该是:
s = raw_input("Message Here Is: ");
最后(也与你的问题无关):
char *raw_input(char *msg){
char *d;
printf("%s", msg);
scanf("%s",&d);
return d;
}
打印提示后,您应该致电fflush(stdout)
。见My program's prompts and intermediate output don't always show up on the screen, especially when I pipe the output through another program.
答案 4 :(得分:1)
尝试此实验:
#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;
}
使用输入消息执行多项体验,只要:3,4,5,7,8,9,11,12,13等字符长。查看整数变量value
的结果。您将看到由于您通过传递scanf()
的地址而误用d
,您允许scanf()
销毁函数的局部变量,包括返回地址。
这让我们回到了这个网站的名称。
答案 5 :(得分:0)
您无法返回已在函数内创建的变量的指针。变量d在main函数中不再有效。
试试这个: 1.在main函数中创建变量d 2.并将其传递给raw_input函数
void raw_input(char *msg, char *d)