Sprintf& SCANF

时间:2014-07-26 14:35:49

标签: c printf scanf

我一直试图使用本文中的示例找出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则会返回一个完整的错误列表。我可以使用一些帮助来弄清楚为什么这些代码行无法正常工作。

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所述,您希望%15schar onew[16];,因为16字节缓冲区可以包含15个非空格字符加上所需的终止空字节。顺便说一句,我实际上要么用例如明确初始化每个缓冲区。 <{1}}之前char onew[16]={0};或最好使用memset (onew, 0, sizeof(onew)); 清除每个人sscanf。我讨厌未初始化的本地缓冲区字符串。

第二个示例的main不应该在没有警告的情况下进行编译(如果使用gcc -Wall -g),那么永远不会使用sprintfsnprintf(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); }

请注意,我更改了stringafingers的类型并使用了%d ...

你应该将网站列入黑名单,告诉你这样的垃圾。

顺便说一句,要养成启用所有警告的好习惯。在编译器中调试信息。用GCC编译gcc -std=c99 -Wall -g。学习使用调试器gdb)并改进代码,直到您没有错误并且没有警告。