我一直试图使用本文中的示例找出sprintf和scanf:https://www.udemy.com/blog/sprintf-c/#respond
// example 1
#include <stdio.h>
int main() {
char *stringa = “We Are Dismantling a String”;
char *one, *two, *three, *four, *five;
sscanf(stringa, “%s %s %s %s %s”, one, two, three, four, five);
return(0);
}
和
// Example 2
#include <stdio.h>
int main() {
char *stringa[30];
int *fingers = 5;
sprintf(stringa, "Number of fingers making up a hand are %f", fingers);
puts(stringa);
return(0);
}
我无法在示例1中获取变量以进行初始化,而示例2则会返回一个完整的错误列表。我可以使用一些帮助来弄清楚为什么这些代码行无法正常工作。
答案 0 :(得分:4)
对于你的第一个程序,指针只是指针,因为它们未初始化,它们的值(即它们指向的位置)是不确定的。使用它们,尤其是作为写入目的地,可以使用undefined behavior。
要解决此问题,您需要分配内存并分配给指针,或者使用足够长的数组。
关于你的第二个程序,fingers
是一个指针,你告诉编译器将它指向地址 5
,而不是指向 Value 5
。
然后告诉printf
打印浮点值,并将指针作为参数赋予它。这将再次导致未定义的行为,因为printf
会将指针视为double
值,而不是指针。
要解决此问题,请不要将fingers
声明为指针,并使用正确的printf
格式"%d"
(对于带符号的十进制整数)。
我还建议您阅读该功能的一些参考资料,如下所示:
答案 1 :(得分:2)
要完成Jaochim Pileborg's answer,您应该使用数组,而不是指针,因此请将您的第一个main
编码为
int main() {
char *stringa = "We Are Dismantling a String";
char onew[16], twow[16], threew[16], fourw[16], fivew[16];
if (sscanf (stringa,
"%15s %15s %15s %15s %15s",
onew, twow, threew, fourw, fivew) < 5)
fprintf (stderr, "something got wrong\n");
return 0;
}
如Chux所述,您希望%15s
为char onew[16];
,因为16字节缓冲区可以包含15个非空格字符加上所需的终止空字节。顺便说一句,我实际上要么用例如明确初始化每个缓冲区。 <{1}}之前char onew[16]={0};
或最好使用memset (onew, 0, sizeof(onew));
清除每个人sscanf
。我讨厌未初始化的本地缓冲区字符串。
第二个示例的main
不应该在没有警告的情况下进行编译(如果使用gcc -Wall -g
),那么永远不会使用sprintf
但snprintf(3) (或者可能asprintf(3))。
int main() {
char stringa[30];
int fingers = 5;
snprintf(stringa, sizeof(stringa),
"Number of fingers making up a hand are %d", fingers);
puts(stringa);
return(0); }
请注意,我更改了stringa
,fingers
的类型并使用了%d
...
你应该将网站列入黑名单,告诉你这样的垃圾。
顺便说一句,要养成启用所有警告的好习惯。在编译器中调试信息。用GCC编译gcc -std=c99 -Wall -g
。学习使用调试器(gdb
)并改进代码,直到您没有错误并且没有警告。