【问题标题】:Formatted input in CC中的格式化输入
【发布时间】:2018-01-27 20:15:09
【问题描述】:

有人可以帮忙告诉我我的代码有什么问题吗?我想问用户他/她朋友的两个名字和他们的年龄。然后返回他们年龄的平均值。但输出不如预期。

#include <stdio.h>

int main(void){
    char friend1;
    char friend2;
    float age1;
    float age2;
    float average;

    printf("Please enter name of your friend...\n");
    scanf("%s", &friend1);
    printf("How old is %s?\n",&friend1);
    scanf("%f", &age1);

    printf("Enter name of one more friend!\n");
    scanf("%s",&friend2);
    printf("How old is %s?\n", &friend2);
    scanf("%f", &age2); 

    average = (age1+age2)/2;

    printf("Average age of your friends %s and %s is %4.2f years old\n"  ,&friend1,&friend2,&average);
    return 0;
}

【问题讨论】:

  • 那输出是什么?

标签: c input scanf


【解决方案1】:

两件事-

  1. 在 C 中,字符串基本上都是以 null 结尾的 char 数组。
  2. 您需要有足够的内存来保存输入的字符和'\0' 来标记字符串的结尾。

您使用了一个char 变量并将其地址传递给scanfscanf 尝试存储输入名称,但它会访问一些不应导致 undefined behavior 的内存。

正确的方法是使用可能存在的最大数量char 的数组。你也会对friend2 变量做同样的事情。

#define MAXLETTERS 10 

char friend1[MAXLETTERS ];
if( scanf("%9s",friend1) == 1){
   // got name in friend1
}

注意%9s - 为什么是9?因为我们将从输入中获得9 字符,最后一个(第10 个)将是\0 字符。 scanf("%s",friend1) 的问题是%s 匹配任何长度的任何字符串,而scanf() 不知道何时停止阅读。只要它可以根据格式字符串解析输入,它就会读取,因此它写入friend1 的字符多于10 字符 - 留给我们buffer overflow 的可能性。 通过指定9,我们告诉scanf不要阅读超过9的字符。

&amp; 运算符在应用于变量时返回它的地址 - 在计算两个朋友的平均值之后,您需要打印它的值而不是地址。因此,为每个案例中列出的3 变量删除printf 中的&amp;。只需将变量的值传递给printf 函数而不是地址。

如果您想知道为什么在 scanffriend1friend2 中没有使用 &amp; - 那么您应该知道当一个数组被传递给一个函数时(这里的函数是 scanf ) 它被转换为(称为数组衰减)指向第一个元素的指针。这里的第一个元素是friend1[0],指向它的指针意味着指针的内容是&amp;friend1[0]。这就是scanf 所期望的——它将存储输入数据的地址。

【讨论】:

  • 恭喜达到20k!
  • 同意。很遗憾#define MAXLETTERS 10 找不到通往scanf("%9s",friend1) 的路。如果printf 格式说明符中的* 字段宽度可以在scanf 中具有类似的运行时使用,那就太好了。但事实并非如此,*scanf 不一样。
  • @JonathanLeffler.: 谢谢
【解决方案2】:

friend1 & friend2 声明为char array,如果您想将names 存储到它们中,如下所示

char friend1[50];/** take the char array of required size **/
char friend2[50];

在扫描时,如果friend1 被声明为char array,则无需在scanf 中提供&amp;,因为char array 本身就是地址

printf("Please enter name of your friend...\n");
scanf("%s", friend1);

friend2 应用相同的方法。此外,如果您想打印average 的值,请不要在打印时使用&amp;

替换

 printf("Average age of your friends %s and %s is %4.2f years old\n"  ,&friend1,&friend2,&average);

printf("Average age of your friends %s and %s is %4.2f years old\n"  ,friend1,friend2,average);

【讨论】:

    【解决方案3】:

    由于 scanf 需要一个字符串(指向 char 的指针),请尝试切换到一个 char 数组。

    char friend1[20]; 
    char friend2[20];
    

    如果字符串少于 19 个字符,则可能是一个有效示例。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-05-17
      • 2015-06-07
      • 2010-12-30
      • 1970-01-01
      • 2022-01-06
      • 2017-02-10
      • 1970-01-01
      • 2021-08-17
      相关资源
      最近更新 更多