C中的格式化输入

时间:2018-01-27 20:15:09

标签: c input scanf

有人可以帮我告诉我我的代码有什么问题。我试图向用户询问他/她的朋友的两个名字和他们的年龄。然后返回他们年龄的平均值。但输出并不像预期的那样。

2

3 个答案:

答案 0 :(得分:3)

两件事 -

  1. 在C字符串中基本上是空终止char数组。
  2. 您需要有足够的内存来容纳输入的字符,而'\0'则需要标记字符串的结尾。
  3. 您使用了一个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个字符。

    应用于变量的

    &运算符返回它的地址 - 在计算两个朋友的平均值之后,你需要打印它的值而不是它的地址。因此,请删除&printf3的{​​{1}}变量,以查看每个案例中列出的printf变量。只需将变量的值传递给&函数而不是地址。

    如果您想知道为什么scanf使用friend1friend2时没有使用scanf,那么您应该知道当数组传递给函数时(这里函数为friend1[0])它被转换为(称为数组衰减)指向第一个元素的指针。这里的第一个元素是&friend1[0],指向它的指针意味着指针的内容是scanf。这就是function sum(arr) { return arr.reduce((acc, current) => acc + current, 0); } 所期望的 - 它将存储输入数据的地址。

答案 1 :(得分:0)

声明friend1& friend2 char arraynames,如果您想将char friend1[50];/** take the char array of required size **/ char friend2[50]; 存储在其中

&

在扫描时,如果scanf被声明为friend1,则无需在char array中提供char array,因为printf("Please enter name of your friend...\n"); scanf("%s", friend1); 名称本身地址< /强>

friend2

&应用相同的内容。如果您要打印average的值,也请在打印时不使用 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);

app.directive("forceInput", function() {
  return {
    require: "ngModel",
    link: postLink
  }
  function postLink(scope, elem, attrs, ngModel) {
    attrs.$observe('forceInput', function(value) {
      if (!value) return;
      elem[0].value = value;
      ngModel.$setViewValue(value);
    })
  }
})

答案 2 :(得分:0)

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

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

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