【问题标题】:why printf is not showing string on removing & and not showing address in C?为什么 printf 在删除 & 时没有显示字符串,也没有在 C 中显示地址?
【发布时间】:2019-04-09 07:15:06
【问题描述】:
#include<stdio.h>

void main(){

char *r;
printf("Enter the string : ");
scanf("%s",&r); 
printf("\nThe string is : %s",&r);

}

我正在使用 DEV C++(tdm-gcc 4.9.2 64 位版本) 在 printf 语句和删除中将导致打印字符串,但它没有显示任何输出,这让我很困惑 我读到我们也可以在没有 & 的情况下使用扫描,但它在 C 中也不起作用

【问题讨论】:

  • 哦,天哪...您已将一个字符串读入堆栈上用于保存指针的内存区域。如果您删除了 scanfprintf 调用的 &amp;,这几乎是正确的,除非您需要首先通过分配一些内存来实际初始化指针。
  • 你没有分配任何内存
  • Malloc and scanf的可能重复
  • 关于:void main(){ main 函数只有两个有效签名。它们是:int main( void )int main( int argc, char *argv[] )
  • 关于:char *r;scanf("%s",&amp;r); 1) r 已经是一个指针,因此不需要 &amp;。 2) 指针r 未设置为指向应用程序拥有的任何内存,因此写入它指向的位置是未定义的行为。 4)写入指针(正如代码所做的那样)意味着指针将被溢出(取决于底层架构 4 或 8 个字节,这是未定义的行为 4)当使用格式说明符“%s”时,总是包含一个最大字符修饰符,它比输入缓冲区的长度小一,以避免任何缓冲区溢出( %s 总是附加一个 NUL 字节)

标签: c printf scanf


【解决方案1】:

char buf[64] 和 char *buf 有很大区别。

我建议你通过打印这两个声明的大小来了解区别。

EX:

    char *r;
    char buf[64];

printf(" Size of array :%d pointer :%d\n", sizeof(buf), sizeof(r));

字符 *r;是一个指针的纯声明,它保存一个 char 类型变量的地址。 char *r 是 char 指针,现在它指向垃圾值。 char buf[64],是64字节的char缓冲区,buf指向第一个字符。

char *r 指向未知/垃圾值。在使用这种方法之前,您应该分配内存。

char *r = (char *) malloc(32);
or
char buf[64];
char *r;

r = buf;  

---> 现在 'r' 指向 buf,它已经分配了内存。

现在,您可以理解其中的区别了。

【讨论】:

    【解决方案2】:

    %s 格式说明符到scanf 需要一个指向char 数组的第一个元素的指针。换句话说,char *。相反,您传递的是char **。使用错误的格式说明符会调用undefined behavior

    r定义为一个数组:

    char r[100];
    

    然后你可以将r 传递给scanf,它会衰减为指向第一个元素的指针:

    scanf("%99s", r);
    

    还要注意,我们在此处指定了最大长度,这样如果输入的字符过多,就不会有超出数组末尾的写入风险。

    printf类似,需要调用如下:

    printf("\nThe string is : %s",r);
    

    【讨论】:

    • 有趣的是,所有人类已知的编译器都会生成工作代码,即使您在示例中为r 加上地址运算符;-)。 (是的,这个工作代码当然是 UB 的一个特殊化身。)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-09-03
    • 2022-10-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多