scanf和char变量问题

时间:2012-07-11 06:30:49

标签: c scanf

好的,我正在读 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);
}

7 个答案:

答案 0 :(得分:3)

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

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

当你使用地址,e.i。,&时,它变成了char **,这不是scanf所期望的。

另外,对于这个例子,它更安全:

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

防止溢出。

答案 1 :(得分: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); 

无需在它们之前添加&%s预计char *会在不添加&的情况下得到满足。

答案 2 :(得分:1)

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

scanf("%s",adjective);
scanf("%s",food);
scanf("%s",chore);
scanf("%s",furniture);

答案 3 :(得分:1)

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

答案 4 :(得分:0)

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

int a[20];

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

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

我不知道你的阅读进展有多远,但是一旦你阅读了指针和数组,这些事情就会变得更加清晰。

答案 5 :(得分:0)

使用scanf从键盘读取时,字符放在缓冲区中,scanf的参数从该缓冲区中提取,因此在输入字符串时scanf("%s",adjective);ENTER “ABC”并按ENTER CR[LF]个字符(scanf())也会放在缓冲区中。 %s提取字符串“ABC”,但ENTER仍然存在。下次执行ENTER fgets()时,if ( fgets( adjective, sizeof(adjective), stdin) ) { if ( fgets( ... { 仍在缓冲区中,只会返回而不会读取任何内容。

在开始时,最好使用{{1}}来读取字符串以避免直接使用输入缓冲区的麻烦,并且如果输入的字符串大于数组所能容纳的字符串,则不会崩溃。

{{1}}

答案 6 :(得分:0)

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