" strlen的"在C中给出不同的结果

时间:2015-04-07 12:34:08

标签: c string

我一直在学习字符串,本书的作者解释了给定的代码。我不明白为什么它会在输出中给 11个字符命名 31个字符到" PRAISE"

INPUT

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h> /* provides strlen() prototype */
#define PRAISE "You are an extraordinary being."
int main(void)
{
    char name[40];
    printf("What's your name? ");
    scanf("%s", name);
    printf("Hello, %s. %s\n", name, PRAISE);
    printf("Your name of %u letters occupies %u memory cells.\n",
        strlen(name), sizeof name);
    printf("The phrase of praise has %u letters ",
        strlen(PRAISE));
    printf("and occupies %u memory cells.\n", sizeof PRAISE);

    getchar();
    getchar();
    return 0;
}

输出

What's your name? Serendipity Chance
Hello, Serendipity. You are an extraordinary being.
Your name of 11 letters occupies 40 memory cells.
The phrase of praise has 31 letters and occupies 32 memory cells.

根据我的知识,它应该给出这样的输出

What's your name? Serendipity Chance
Hello, Serendipity. You are an extraordinary being.
Your name of 11 letters occupies 40 memory cells.
The phrase of praise has 3 letters and occupies 32 memory cells.

我错了? 对不起,如果这是一个愚蠢的问题!!

5 个答案:

答案 0 :(得分:3)

strlen函数计算\0之前的字符数。

#define PRAISE "You are an extraordinary being."

表示前处理程序用PRAISE替换"You are an extraordinary being."的每个实例。此字符串的长度(由strlen返回)为31,这是程序在第二个printf中打印的内容。

name长度为strlen长度为11个字符的原因是%s中的scanf扫描所有内容,直到第一个空格字符(如空格,换行符等) )。在您的情况下,它扫描"Serendipity"并停止扫描,因为下一个字符是空白字符(空格)。 "Serendipity"的长度为11。

顺便说一句,size_tstrlensizeof返回的类型)的正确格式说明符是%zu

答案 1 :(得分:2)

strlen计算字符串的长度,直到满足0个字符,直到空白字符为止。 0字符是值为零的char,它不是可见字符。也许这就是造成你困惑的原因。 PRAISE是一个由31个字符组成的字符串,这解释了输出。

另一方面,您使用Serendipity Chance阅读%s,其读取直到空白字符。因此,只读取该对的第一部分(Serendipity),其长度为11.

答案 2 :(得分:2)

函数strlenscanf

之间存在差异

格式说明符为scanf的函数%s从标准输入流中读取字符,直到遇到空格字符。 因此,如果您输入

Serendipity Chance

scanf的这个调用

scanf("%s", name);

只会在名称中复制字符Serendipity

函数strlen计算字符,直到遇到终止为零。例如,strlen为此字符串文字返回的值

"Serendipity Chance"

将等于18,因为在内存中字符串文字表示为

Serendipity Chance\0

对于使用预处理器常量

定义的字符串文字,它也是有效的
#define PRAISE "You are an extraordinary being."

strlen返回的大小等于31。

答案 3 :(得分:1)

我认为令人困惑的是scanf("%s", name);只读取数据直到第一个空格。在你的名字是“Serendipity”,这是11个字符。 PRAISE是整个字符串“你是一个非凡的存在。”,长度为31个字符(加尾随'\ 0')。

答案 4 :(得分:0)

当你printf("Hello, %s. %s\n", name, PRAISE);时 你清楚地看到&#34;你好, Serendipity 。&#34;在哪里&#34; Serendipity&#34;是name。并且strlen(name)对于它长达11个字符是正确的。

输入字符串的另一部分未被读取,因为scanf读取一系列非空白字符,即第一个空白字符。