1

好的,我正在阅读C for dummies,我又遇到了scanf问题。我早些时候写了另一个问题类似的问题,但修复在这里不起作用。每次我编译时,gcc 总是说:

MADLIB1.C:在函数“int main()”中:
MADLIB1.C:19:27:警告:格式“%s”需要“char*”类型的参数,但参数 2 的类型为“char ( )[20]” [-Wformat]
MADLIB1.C:21:22:警告:格式“%s”需要“char
”类型的参数,但参数 2 的类型为“char ( )[20]”[-Wformat]
MADLIB1.C:23: 23:警告:格式“%s”需要“char
”类型的参数,但参数 2 的类型为“char ( )[20]”[-Wformat]
MADLIB1.C:25:27:警告:格式“%s”需要'char
' 类型的参数,但参数 2 的类型为 'char (*)[20]' [-Wformat]
MADLIB1.C:31:52: 错误:输入结束时预期为 '}'

这是我的代码:

/*
MADLIBI.C Source Code
Written by Arshad Husain
*/

#include <stdio.h>

int main()
{

    char adjective[20];
    char food[20];
    char chore[20];
    char furniture[20];

    /* Get the words to use in the madlib */

    printf("Enter an adjective");     /* prompt */
    scanf("%s",&adjective);
    printf("Enter a food");
    scanf("%s",&food);
    printf("Enter a household chore (past tense):");
    scanf("%s",&chore);
    printf("Enter an item of furniture");
    scanf("%s",&furniture);

    /* Display the output */

    printf("\n\nDon't touch that %s %s!\n", adjective, food);
    printf("I just %s the %s!\n", chore, furniture);

    return(0);
}
4

7 回答 7

3

您不应该对数组使用 address-of,它们已经是指针:

printf("Enter an adjective");     /* prompt */
scanf("%s",adjective);

当你使用 address-of, ei, 时&,它变成了 char **,这不是 scanf 所期望的。

此外,对于这个例子,这样做更安全:

scanf("%19s",adjective); /* maximum 19 chars */

以防止溢出。

于 2012-07-11T06:32:26.170 回答
1
    printf("Enter an adjective");     
   /* prompt */ scanf("%s",&adjective); 
   printf("Enter a food"); 
   scanf("%s",&food); 
   printf("Enter a household chore (past tense):"); 
   scanf("%s",&chore); 
   printf("Enter an item of furniture"); 
   scanf("%s",&furniture); 

   printf("Enter an adjective");     
   /* prompt */ scanf("%s",adjective); 
   printf("Enter a food"); 
   scanf("%s",food); 
   printf("Enter a household chore (past tense):"); 
   scanf("%s",chore); 
   printf("Enter an item of furniture"); 
   scanf("%s",furniture); 

无需&在它们之前添加 a 。%s期望在char *不添加&自身的情况下满足 a。

于 2012-07-11T06:33:47.690 回答
1

您编写的代码的语法:scanf("%s",&food); 没有任何意义,因为要在字符串(字符数组)中输入输入,您不需要在数组名称前加上 &。为了进一步避免缓冲区溢出,您应该使用
scanf("ONE_LESS_THEN_THE_SIZE_OF_CHAR_ARRAY%s",food); 如果是食物,你应该使用 scanf("%19s",food);

于 2012-07-11T06:49:22.490 回答
1

无需传递 char 数组的地址。即只需修改scanf语句如下

scanf("%s",adjective);
scanf("%s",food);
scanf("%s",chore);
scanf("%s",furniture);
于 2012-07-11T06:37:56.537 回答
0

C 中的数组不是单独的数据类型。它类似于指针。例如,当我写

int a[20];

它保留 20*4 = 80 个字节用于存储 20 个整数。现在,'a' 指向这 20 个分配的整数的第一个字,即'a' 包含第一个字的地址。它同样适用于在您的情况下为 char 类型的任何数组。在内部,形容词的类型是 char *。

现在,当你在 scanf 中说 &adjective 时,实际上是在给出 'char *adjective' 的地址,它不是字符串数组,因此数据类型不匹配。

我不知道你在阅读方面取得了多大的进步,但是一旦你阅读了指针和数组,这些事情就会变得更加清晰。

于 2012-07-11T06:36:21.423 回答
0

当您使用 键盘从键盘读取时scanf,字符被放置在缓冲区中,并且scanf要从该缓冲区中提取的参数,因此在scanf("%s",adjective);您输入字符串“ABC”并按下字符()的情况下,(ENTER)也被放置在缓冲区中. %s 提取字符串“ABC”,但 ENTER 保留。下次你这样做时,它仍然在缓冲区中,只会返回而不读取任何内容。ENTERCR[LF]scanf()ENTER

一开始最好使用fgets()读取字符串来避免直接使用输入缓冲区的麻烦,并且如果输入的字符串大于数组可以容纳的字符串,也不会崩溃。

if ( fgets( adjective, sizeof(adjective), stdin) )
{
  if ( fgets( ...
  {
于 2012-07-11T06:46:39.147 回答
0

期间不要使用额外的“&” scanf。数组字符串的名称本身就是字符串的基地址——即adjective == &(adjective[0])。所以你不需要在形容词n其他数组之前额外的'&'。

于 2012-07-11T07:33:30.317 回答