Coldplay
Coldplay

Reputation: 143

"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?

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!!

Upvotes: 1

Views: 888

Answers (5)

Spikatrix
Spikatrix

Reputation: 20244

The strlen function counts the number of character until a \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.". The length of this string(returned by strlen) is 31 which is what the program prints in the second last 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). In your case, it scans "Serendipity" and stops scanning as the next character is a whitespace character(space). The length of "Serendipity" is 11.

BTW, the correct format specifier for size_t(the type that strlen and sizeof returns) is %zu.

Upvotes: 3

Vlad from Moscow
Vlad from Moscow

Reputation: 311126

There is a difference between functions strlen and scanf

Function scanf with format specifier %s reads characters from the standard input stream until a white space character will be encountered. Thus if you entered

Serendipity Chance

this call of scanf

scanf("%s", name);

will copy in name only character Serendipity.

Function strlen counts characters until terminating zero will be encountered. For example the value returned by strlen for this string literal

"Serendipity Chance"

will be equal to 18 because in memory the string literal is represented like

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.

Upvotes: 2

zennehoy
zennehoy

Reputation: 6866

I think what's confusing you is that scanf("%s", name); only reads in data up to the first whitespace. In your name that is "Serendipity", which is 11 characters. PRAISE is the entire string "You are an extraordinary being.", which is 31 characters long (plus trailing '\0').

Upvotes: 1

edmz
edmz

Reputation: 8492

When you printf("Hello, %s. %s\n", name, PRAISE); you clearly see "Hello, Serendipity." where "Serendipity" is name. And strlen(name) is right about it being 11 characters long.

The other part of the input string is not read because scanf reads a sequence of non-whitespace characters i.e up to the first blank char.

Upvotes: 0

Ivaylo Strandjev
Ivaylo Strandjev

Reputation: 71009

strlen computes the length of a string until a 0 character is met, not until a whitespace character. A 0 character is a char with value zero and it is not a visible character. Maybe that is what is causing your confusion. PRAISE is a string that consists of 31 characters and this explains the output.

On the other hand you read Serendipity Chance using %s which reads until a whitespace character. Thus only the first part(Serendipity) of this pair is read and it has length 11.

Upvotes: 2

Related Questions