用scanf读取字符串

时间:2011-03-23 14:40:55

标签: c scanf

我对某些事情有点困惑。我的印象是,用scanf()读取C字符串的正确方法是

(不用担心可能的缓冲区溢出,这只是一个简单的例子)

char string[256];
scanf( "%s" , string );

但是,以下似乎也有效,

scanf( "%s" , &string );

这只是我的编译器(gcc),纯粹的运气还是别的什么?

2 个答案:

答案 0 :(得分:124)

数组“衰减”为指向其第一个元素的指针,因此scanf("%s", string)等同于scanf("%s", &string[0])。另一方面,scanf("%s", &string)将指针传递给char[256],但它指向同一位置。

然后scanf,当处理其参数列表的尾部时,将尝试拉出char *。当你通过string&string[0]时,这是正确的事,但是当你传入&string时,你依赖于语言标准不能保证的东西,即指针&string&string[0] - 指向不同类型和大小的对象的指针,从同一个地方开始 - 以相同的方式表示。

我不相信我曾经遇到过一个不起作用的系统,实际上你可能很安全。尽管如此,这是错误的,它可能会在某些平台上失败。 (假设示例:一个“调试”实现,其中包含每个指针的类型信息。我认为符号系统“Lisp Machines”上的C实现做了类似的事情。)

答案 1 :(得分:-7)

我认为以下内容是准确的,可能有所帮助。 如果您发现任何错误,请随时更正。我是C的新人。

char str[]  
  1. char类型的值数组,在内存中有自己的地址
  2. char类型的值数组,在内存中有自己的地址 与数组中的元素一样多的连续地址
  3. 包括终止空字符'\0' &str&str[0]str,这三个表示内存中相同的位置,即第一个元素的地址数组str

    char * strPtr =& str [0]; //声明和初始化

  4. 或者,您可以将其拆分为两个:

    char *strPtr; strPtr = &str[0];
    
    1. strPtr是指向char
    2. 的指针
    3. strPtr点数组str
    4. strPtr是一个在内存中有自己地址的变量
    5. strPtr是一个存储地址&str[0]
    6. 值的变量 内存中的
    7. strPtr自己的地址与它存储的内存地址不同(内存中的数组地址a.k.a& str [0])
    8. &strPtr代表strPtr本身的地址
    9. 我认为您可以将指针指针声明为:

      char **vPtr = &strPtr;  
      

      使用strPtr指针的地址声明并初始化

      或者你可以分成两部分:

      char **vPtr;
      *vPtr = &strPtr
      
      1. *vPtr指向strPtr指针
      2. *vPtr是一个在内存中有自己地址的变量
      3. *vPtr是一个存储地址& strPtr
      4. 值的变量
      5. 最终评论:你不能str++str地址是const,但是 你可以做strPtr++