【问题标题】:Problems getting the length of a string in c在c中获取字符串长度的问题
【发布时间】:2014-02-15 17:50:56
【问题描述】:

这是代码:

void main()
{   char strvek[500];

    printf("Mata in ett stort tal: ");
    scanf("%s", &strvek);

    size_t len1 = strlen(strvek);
    printf("%d",&len1);
}

程序结束打印 len1 的内存地址。我想将字符串的长度存储在 len1 中。如果输入“你好”,例如我想要整数 5。

【问题讨论】:

  • printf("%zu\n",len1);
  • scanf("%499[^\n]", strvek);

标签: c arrays strlen


【解决方案1】:

您的代码存在问题:

  • scanf 确实接受地址,但由于 strvek 是一个数组,因此在传递给函数时它会“衰减”为指针
  • 用户可以键入比缓冲区容纳的字符更多的字符以防止缓冲区溢出,并且
  • printf 不需要ints 的地址(您的代码具有未定义的行为)

这是解决前两个问题的方法:

scanf("%499s", strvek); // Limit the size to 499 chars + '\0'; no ampersand in front of strvec

这是解决最后一个问题的方法:

printf("%d", len1); // No ampersand

一开始可能有点难以记住何时在 I/O 函数中使用 & 符号。一般来说,请记住scanf 需要一个 & 符号,除了字符串,printf 不需要一个 & 符号,除了 %p 格式说明符(在这种情况下,您需要将指针转换为 void*)。

【讨论】:

  • @alk 你说得对,那是 OP 代码的复制粘贴。
【解决方案2】:

因为您在输出中打印了len1 的地址。 简单写:

printf("%d",len1);

【讨论】:

  • size_t 肯定是 long 而且肯定是 unsigned
【解决方案3】:

到目前为止,人们在其他答案中没有提到的原因是scanf 希望您传递值的地址,而 printf 则希望您自己传递值。

从某种意义上说,printf 不能被设计为将地址转换为要打印的值,这并没有技术原因。如果这是惯例,printf 将简单地查找该地址处的内容(使用指针取消引用运算符,*)...并打印出来。

不过有两件事:

  • 取消引用是不需要的“额外步骤”;因为仅拥有值本身的副本就足以将信息传输到printf。 C 喜欢尽可能避免额外的步骤。
  • 基于地址的约定禁止在没有地址的文字值上使用printf。你不能写printf("Value is %d", &10); 并让它打印Value is 10。这可以通过创建一个变量来存储值并传递变量的地址来解决......但正如我刚才所说,C 喜欢避免额外的步骤。

然而对于scanf,有需要地址而不是值的技术原因。它需要接收一个放置数据的地方,以便调用者稍后可以查看该数据。

例如,考虑读取整数。如果您传入一个零整数值(而不是整数变量的地址),而这就是 scanf 必须继续进行的全部内容......它如何获得它读回给您的值?

(在此处的特定示例中,对于字符数组,存在一个关于地址运算符缺乏必要性的微妙问题:请参阅How come an array's address is equal to its value in C?...但忽略它并专注于整数示例对于这个概念。:-P)

【讨论】:

    【解决方案4】:

    应该是

    char strvek[500];
    
    [...]
    
    scanf("%s", strvek);
    

    做得更好

    scanf("%499s", strvek);
    

    防止缓冲区溢出。

    scanning in a "string",即char 数组,传递给scanf() 数组本身时,让数组衰减到指向其第一个st 元素的指针,这使得不必使用&(地址)运算符。


    print out a size_t typed variable

    size_t len = ...;
    printf("%zu", len1);
    

    【讨论】:

      【解决方案5】:

      printf("%d",&len1) 打印地址,而printf("%d",len1) 打印长度本身。 & 运算符表示“地址”

      【讨论】:

      • size_t 肯定是 long 而且肯定是 unsigned
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-10-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多