简体   繁体   English

scanf和char变量问题

[英]scanf and char variable problems

Okay, I'm reading C for dummies , and once again I am having scanf problems. 好的,我正在阅读C的假人 ,而我又遇到了scanf问题。 I wrote another questioner earlier with the similar problem but the fix will not work here. 较早之前,我曾写过另一个发问者,也遇到类似的问题,但此解决方法在这里不起作用。 Every time I compile, gcc always says: 每次编译时,gcc总是说:

MADLIB1.C: In function 'int main()': MADLIB1.C:在函数'int main()'中:
MADLIB1.C:19:27: warning: format '%s' expects argument of type 'char*', but argument 2 has type 'char ( )[20]' [-Wformat] MADLIB1.C:19:27:警告:格式'%s'需要类型为'char *'的参数,但是参数2具有类型'char( )[20]'[-Wformat]
MADLIB1.C:21:22: warning: format '%s' expects argument of type 'char ', but argument 2 has type 'char ( )[20]' [-Wformat] MADLIB1.C:21:22:警告:格式'%s'期望类型为'char ',但是参数2的类型为'char( )[20]'[-Wformat]
MADLIB1.C:23:23: warning: format '%s' expects argument of type 'char ', but argument 2 has type 'char ( )[20]' [-Wformat] MADLIB1.C:23:23:警告:格式'%s'期望的参数类型为'char ',但是参数2的类型类型为'char( )[20]'[-Wformat]
MADLIB1.C:25:27: warning: format '%s' expects argument of type 'char ', but argument 2 has type 'char (*)[20]' [-Wformat] MADLIB1.C:25:27:警告:格式'%s'期望类型为'char ',但是参数2的类型为'char(*)[20]'[-Wformat]
MADLIB1.C:31:52: error: expected '}' at end of input MADLIB1.C:31:52:错误:输入结尾处应为'}'

Here's my code: 这是我的代码:

/*
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);
}

You should not use address-of for arrays, they are already pointers: 您不应该对数组使用address-of,它们已经是指针:

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

When you use address-of, ei, & , it becomes char **, which is not what scanf expects. 当使用address-of,ei & ,它变成char **,这不是scanf期望的。

also, for this example it is safer to do: 同样,对于此示例,这样做更安全:

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

to protect against overflows. 防止溢出。

    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); 

can be

   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); 

No need for prepending a & before them. 无需在前面加上& %s expects a char * which will be satisfied without adding a & itself. %s期望不添加&本身就能满足的char *

No need to pass the address of address of char array. 无需传递char数组地址的地址。 ie Just modify the scanf statements as follows 即只需修改scanf语句,如下所示

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

the syntax of your code you have written : scanf("%s",&food); 您编写的代码的语法:scanf(“%s”,&food); doesn't make any sense because to take input in a string(char array) you don't need to prefix the array name with &. 这没有任何意义,因为在字符串(char数组)中接受输入时,不需要在数组名称前加上&。 further to avoid buffer overflow you should use 进一步避免缓冲区溢出,您应该使用
scanf("ONE_LESS_THEN_THE_SIZE_OF_CHAR_ARRAY%s",food); scanf(“ ONE_LESS_THEN_THE_SIZE_OF_CHAR_ARRAY%s”,食物); in case of food you should use scanf("%19s",food); 如果是食物,则应使用scanf(“%19s”,food);

An array in C is not a separate data type. C中的数组不是单独的数据类型。 It is similar to a pointer. 它类似于一个指针。 For example, when i write 例如,当我写

int a[20];

It reserves 20*4 = 80 bytes for storing 20 integers. 它保留20 * 4 = 80字节用于存储20个整数。 Now, 'a' points to the first word of these 20 allocated integers ie 'a' contains the address of the first word. 现在,“ a”指向这20个分配的整数中的第一个单词,即“ a”包含第一个单词的地址。 It applies similarly to any array which in your case is of type char. 它类似地适用于任何情况下为char类型的数组。 Internally, adjective is of type char *. 在内部,形容词是char *类型的。

Now when in scanf you say &adjective, you are actually giving the address of 'char *adjective', which is not a string array and hence data types do not match. 现在,在scanf中,您说&adjective时,实际上是在给出'char * adjective'的地址,该地址不是字符串数组,因此数据类型不匹配。

I do not know how far you have progressed with your reading, but these things will become much clearer to you once you read about pointers and arrays. 我不知道您的阅读进度如何,但是一旦您阅读了有关指针和数组的内容,这些事情对您来说就会变得更加清晰。

When you read from the keyboard using scanf , characters are placed in a buffer and the arguments to scanf extract from that buffer so in the case of scanf("%s",adjective); 当您使用scanf从键盘上读取字符时,字符将放置在缓冲区中,而scanf的参数将从该缓冲区中提取出来,因此在scanf("%s",adjective); when you enter a string "ABC" and press ENTER the ENTER character(s) ( CR[LF] ) are also placed in the buffer. 当您输入字符串“ ABC”并按ENTERENTER字符( CR[LF] )也将放置在缓冲区中。 The %s extracts the string "ABC" but the ENTER remains. %s提取字符串“ ABC”,但仍保留ENTER。 Next time you do scanf() the ENTER is still in the buffer and will just return without reading anything. 下次执行scanf()ENTER仍在缓冲区中,并且仅返回而不会读取任何内容。

in the beginning you would be better off using fgets() to read strings to avoid the hassle of working with the input buffer directly and will not crash if you enter a larger string than the array can hold. 开始时,最好使用fgets()读取字符串,以避免直接使用输入缓冲区的麻烦,并且如果输入的字符串大于数组可以容纳的范围,则不会崩溃。

if ( fgets( adjective, sizeof(adjective), stdin) )
{
  if ( fgets( ...
  {

Don't use an extra '&' during scanf . scanf期间不要使用多余的“&”。 The name of an array string is itself the base address of string - ie adjective == &(adjective[0]) . 数组字符串的名称本身就是字符串的基地址-即adjective == &(adjective[0]) So you don't need the extra '&' before adjective n other arrays. 因此,在形容其他数组之前,不需要多余的“&”。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM