【问题标题】:Why is the & operator used after using scanf? [closed]为什么使用scanf后使用&运算符? [关闭]
【发布时间】:2016-08-24 09:19:37
【问题描述】:
char string = "default";
printf("The default String is: %s", &string);
scanf("%s", &string);
printf("You entered: %s", &string);

第一个 printf 语句将 &string 打印为 X(?_?。第二个 printf,在 scanf 语句打印出我输入的字符串之后。

既然&var操作符的意思是“var的内存地址”,那么&string为什么会打印出输入的字符串呢?当我尝试仅使用“字符串”时,为什么会出现分段错误?

【问题讨论】:

  • 您的代码绝对充斥着未定义的行为:它的工作是偶然的。一个好的答案将是一个很长的答案。让我们拭目以待。
  • 最适合的行不是有效的 C。因此很难推断后续行。
  • 投票结束,因为注意编译器警告会完全消除这个问题的需要。
  • 很难相信第一行甚至可以编译。

标签: c printf scanf


【解决方案1】:

您已将string 声明为单个字符,但您用字符串填充它。这会调用未定义的行为。您应该将代码更改为:

char string [20] = "default";   //20 is random, you should use the maximum length of the input you may have
printf("The default String is: %19s", string);
scanf("%s", string);
printf("You entered: %s", string);

一般情况下,scanf 需要将内存地址作为参数,而在上面的代码中,string 是内存地址。您可以在this link 中阅读有关scanf 的更多信息。

【讨论】:

  • char *string = "default"; 会更正确。赋值改变了指针,分配的 20 个字符变得不可访问。不过,该程序在这两种情况下都有效。
  • @AhmadWabbi 你试过了吗?
  • 您声明字符数组的语法不正确。您还应该为scanf 使用"%19s" 格式,以免写入超出数组范围。
  • @JoachimPileborg 会让scanf 更有可能成功还是更少?
  • 人们对gets() 有强烈的感情,但是当出现scanf("%s", string); 的答案时,他们会赞成。 SMH。
【解决方案2】:
#include <stdio.h>
#include <string.h>

char chomp(char* s, char c){
    size_t l = strlen(s);
    if (!l) return 0;
    return s[l-1] = s[l-1]==c ? '\0' : s[l-1];
}

int main(){
    char string[] = "default"; /* sizeof(string) == strlen("default")+1 */
    printf("The default String is: %s\n", string); 
    //^ you want the array to decay to a char* here
    /*scanf("%s", &string); -- DANGEROUS 
    -- scanf doesn't know how much space you have in string*/

    fgets(string /*decay again*/,  sizeof(string), stdin);
    /* fgets does know because you've told it with sizeof(string)*/

    chomp(string, '\n');
    printf("You entered: %s", string);
    return 0;
}

【讨论】:

  • 虽然不常见,但fgets()之后,string[0]可能为0,l = strlen(s); s[l-1]是个问题。防御性编码确保fgets() 之后的第一个字符不是用户输入的空字符。
【解决方案3】:

这将是一个解决方案:

char string[20];
strcpy(string, "default");  
printf("The default String is: %s", string);
scanf("%19s", string);
printf("You entered: %s", string);

【讨论】:

  • strcpy(string, "default"); 不是必需的; char string[20] = "default"; 也可以。
  • @user694733 不,请阅读我与 Marievi 的 cmets
  • 我看到了你的评论。这是不正确的。 char string[20] 是一个数组,= "default" 是它的有效初始化器。 N1570 6.7.9 p14:“字符类型的数组可以由字符串文字或 UTF -8 字符串文字初始化,可选地括在大括号中。字符串文字的连续字节(包括终止空字符,如果有房间或如果数组的大小未知)初始化数组的元素。"
  • @user694733 你是对的。我仔细检查了。初始化器复制。它不是指针赋值。所以,不用strcpy,任务就够了
  • 19 in "The default String is: %19s" 没有什么价值。 scanf("%s", string); 缺少 19 与 gets(string); 一样糟糕。
猜你喜欢
  • 1970-01-01
  • 2016-02-28
  • 2013-01-22
  • 1970-01-01
  • 2017-02-12
  • 1970-01-01
  • 1970-01-01
  • 2014-01-14
  • 2022-01-11
相关资源
最近更新 更多