简体   繁体   English

“ strlen”在C语言中给出不同的结果

[英]“strlen” giving different results in C

I have been learning about strings and the author of the book explained the given code. 我一直在学习字符串,这本书的作者解释了给定的代码。 I didn't understand why it is giving 11 characters to name and 31 characters to phrase of "PRAISE" in the output? 我不明白为什么在输出中给名称 “ PRAISE”赋予11个字符, 为短语赋予31个字符

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;
}

OUTPUT 输出值

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.

According to my knowledge, it should give the output like this 据我所知,它应该给出这样的输出

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.

Where I am getting it wrong? 我在哪里弄错了? Sorry if this is a stupid question!! 抱歉,这是一个愚蠢的问题!

The strlen function counts the number of character until a \\0 . strlen函数计算直到\\0为止的字符数。 You have 你有

#define PRAISE "You are an extraordinary being."

which means that the preproccessor replaces every instance of PRAISE with "You are an extraordinary being." 这意味着preproccessor替代的每个实例PRAISE"You are an extraordinary being." . The length of this string(returned by strlen ) is 31 which is what the program prints in the second last printf . 该字符串的长度(由strlen返回)为31,这是程序在倒数第二个printf打印的内容。

The reason why name is being 11 characters long by strlen is that the %s in the scanf scans everything until the first whitespace character(like spaces,newlines etc). name长为strlen的原因是11个字符,这是因为scanf中的%s扫描所有内容,直到第一个空格字符(如空格,换行符等)为止。 In your case, it scans "Serendipity" and stops scanning as the next character is a whitespace character(space). 在您的情况下,它扫描"Serendipity"并停止扫描,因为下一个字符是空白字符(空格)。 The length of "Serendipity" is 11. "Serendipity"的长度是11。

BTW, the correct format specifier for size_t (the type that strlen and sizeof returns) is %zu . 顺便说一句, size_tstrlensizeof返回的类型)的正确格式说明符是%zu

strlen computes the length of a string until a 0 character is met, not until a whitespace character. strlen计算字符串的长度,直到遇到一个0字符为止,直到一个空格字符为止。 A 0 character is a char with value zero and it is not a visible character. 0字符是值为零的字符,并且不是可见字符。 Maybe that is what is causing your confusion. 也许这就是引起您困惑的原因。 PRAISE is a string that consists of 31 characters and this explains the output. PRAISE是由31个字符组成的字符串,它解释了输出。

On the other hand you read Serendipity Chance using %s which reads until a whitespace character. 另一方面,您使用%s读取“ Serendipity Chance ,该机会读取直到出现空白字符。 Thus only the first part( Serendipity ) of this pair is read and it has length 11. 因此,仅读取该对的第一部分( Serendipity ),其长度为11。

There is a difference between functions strlen and scanf 函数strlenscanf之间有区别

Function scanf with format specifier %s reads characters from the standard input stream until a white space character will be encountered. 带有格式说明符%s功能scanf从标准输入流中读取字符,直到遇到空格字符为止。 Thus if you entered 因此,如果您输入

Serendipity Chance

this call of scanf scanf的此呼叫

scanf("%s", name);

will copy in name only character Serendipity . 将仅复制名称字符Serendipity

Function strlen counts characters until terminating zero will be encountered. strlen函数对字符进行计数,直到遇到零为止。 For example the value returned by strlen for this string literal 例如,strlen为该字符串文字返回的值

"Serendipity Chance"

will be equal to 18 because in memory the string literal is represented like 将等于18,因为在内存中字符串文字表示为

Serendipity Chance\0

The same is valid for string literal defined with preprocessor constant 这对于使用预处理程序常量定义的字符串文字有效

#define PRAISE "You are an extraordinary being."

Its size returned by strlen is equal to 31. strlen返回的大小等于31。

I think what's confusing you is that scanf("%s", name); 我认为让您感到困惑的是scanf("%s", name); only reads in data up to the first whitespace. 仅读取直到第一个空格的数据。 In your name that is "Serendipity", which is 11 characters. 您的名字叫“ Serendipity”,它是11个字符。 PRAISE is the entire string "You are an extraordinary being.", which is 31 characters long (plus trailing '\\0'). PRAISE是整个字符串“ You are a非凡的PRAISE 。”,该字符串长31个字符(后跟'\\ 0')。

When you printf("Hello, %s. %s\\n", name, PRAISE); 当您printf("Hello, %s. %s\\n", name, PRAISE); you clearly see "Hello, Serendipity ." 您清楚地看到“您好, 巧遇” where "Serendipity" is name . 其中“ Serendipity”是name And strlen(name) is right about it being 11 characters long. strlen(name)正确是大约11个字符的长度。

The other part of the input string is not read because scanf reads a sequence of non-whitespace characters ie up to the first blank char. 不会读取输入字符串的另一部分,因为scanf会读取一系列非空白字符,即直到第一个空白字符。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM