2

I have written this program which accepts a string as an input and return the length of it.

#include<stdio.h>
#include<string.h>
#define MAX 100

int main()
{
    char a[MAX];
    int len;
    printf("Enter a string: ");
    fgets(a, MAX, stdin);

    len = strlen(a);
    printf("Length of the string = %d", len);

    return 0;
}

Since the function strlen() doesn't count null character i.e. '\0', why is my output always 1 more than the characters of input string?

For Example -

Enter a string: Aryan
Length of the string = 6
Process returned 0 (0x0)   execution time: 4.372 s
Press any key to continue.
Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
Aryan Soni
  • 76
  • 10

2 Answers2

9

The function fgets can append to the entered string the new line character '\n' if there is a space in the supplied array.

From the C Standard (7.21.7.2 The fgets function)

2 The fgets function reads at most one less than the number of characters specified by n from the stream pointed to by stream into the array pointed to by s. No additional characters are read after a new-line character (which is retained) or after end-of-file. A null character is written immediately after the last character read into the array

Thus in this call of strlen

len = strlen(a);

the new line character is also counted.

You need to remove it as for example

a[ strcspn( a, "\n" ) ] = '\0';

or

char *p = strchr( a, '\n' );
if ( p != NULL ) *p = '\0';
Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
  • Oh so it is happening because there is extra space in the given array! Let me try this... Edit: This worked like charm! Can you suggest a simpler approach, if that's okay with you? – Aryan Soni Jan 21 '22 at 08:11
  • 2
    `a[ strcspn( a, "\n" ) ] = '\0';` is the simplest approach of getting rid of the `\n`. – Jabberwocky Jan 21 '22 at 08:23
4

The fgets() call includes the newline read from the input stream. This is useful, because it allows you to check if the line was read completely. If the input did not have a newline as last character, then the line read was incomplete.

int main()
{
    char a[MAX];
    size_t len;   // being precise with your types is a good habit
    printf("Enter a string: ");
    fgets(a, MAX, stdin);

    len = strlen(a);

    if ( a[len - 1] == '\n' )
    {
        // Usually you don't want the newline in there.
        a[--len] = '\0';
        // --len above corrected the length.
        printf("Length of the string = %zu\n", len);
    }
    else
    {
        printf("Length of the string longer than %d\n", MAX - 1);
        // You can repeat fgets() until you get the whole line,
        // or keep reading (and throwing away) from input until
        // you get a newline. It really depends on how you want
        // to handle the error.
    }

    return 0;
}
DevSolar
  • 67,862
  • 21
  • 134
  • 209
  • Thank you for your answer but honestly, there are some things which I didn't understand. Your code works absolutely fine but since I am new to C, it will take time to digest this! Still, kudos to you buddy! – Aryan Soni Jan 21 '22 at 08:45
  • 1
    @AryanSoni Just ask, I am happy to help. – DevSolar Jan 21 '22 at 11:47
  • I wanted to know what this `if else` statement does. Like, the use of `--len` is new for me. And also `size_t`. – Aryan Soni Jan 22 '22 at 17:02
  • 1
    @AryanSoni: `size_t` is the actual return value of `strlen()`; a typedef (a kind of alias) for an unsigned integer. (Because string lengths cannot be negative.) Once I have determined `len`, I check if the character at position `[ len - 1 ]` is a newline. The expression `a[ --len ] = '\0'` could be also written as `len = len - 1; a[ len ] = '\0';` i.e. reducing `len` by one and replacing the newline with a null byte -- shortening the string by that one character. – DevSolar Jan 22 '22 at 18:28
  • Explained very amazingly! Thanks a lot, man. – Aryan Soni Jan 26 '22 at 07:53
  • 1
    @AryanSoni: My pleasure. Have fun! – DevSolar Jan 26 '22 at 09:08