1

Here's my code

#include <stdio.h>
#include <string.h>

int main(){
    char pal[8] = "ciaooaic";
    char pal1[7] = "ciaoaic";
    int lenPal = strlen(pal);
    int lenPal1 = strlen(pal1);
    printf("strlen('%s'): %d\n", pal, lenPal);
    printf("strlen('%s'): %d\n", pal1, lenPal1);
    return 0;
}

The problem is that when I run this code the output is:

strlen('ciaooaicP@'): 11
strlen('ciaoaic'): 7

The first string has also another non-printable char between P and @. I'm a noob, so maybe I missed something obvious. Can someone help me?

edit:

just give one extra space like char pal[9] = "ciaooaic"; char pal1[8] = "ciaoaic";

It works, but why? I understand that there should be a space for \0, but "ciaoaic" works without it...

5
  • just give one extra space like char pal[9] = "ciaooaic"; char pal1[8] = "ciaoaic"; Commented Nov 14, 2015 at 10:38
  • 2
    Because due to undefined behaviour your code could give any output (even correct output) . Commented Nov 14, 2015 at 10:43
  • When you initialize strings, e.g. char pal[] = "ciaooaic"; the compiler will include the null-terminator at the end (note: '\0' and 0 are equivalent). When you specify a size e.g. pal[8], you limit the size of the array to just that size. If you happen to fill them all up with characters and leave no space for a null, the compiler is happy because it trusts you know what you meant. If by happenstance, the next character following char pal[8] = "ciaooaic"; in memory is a 0, then you accidentally have a null-terminates string. Don't count on that regularly happening... Commented Nov 14, 2015 at 10:58
  • Neither pal nor pal1 is a string as defined by C11 §7.1.1 ¶1: A string is a contiguous sequence of characters terminated by and including the first null character. The term multibyte string is sometimes used instead to emphasize special processing given to multibyte characters contained in the string or to avoid confusion with a wide string. A pointer to a string is a pointer to its initial (lowest addressed) character. The length of a string is the number of bytes preceding the null character and the value of a string is the sequence of the values of the contained characters, in order. Commented Feb 29, 2020 at 15:00
  • See C11 §6.7.9 Initialization ¶14 for the verbiage that allows the non-string initialization: An array of character type may be initialized by a character string literal or UTF-8 string literal, optionally enclosed in braces. Successive bytes of the string literal (including the terminating null character if there is room or if the array is of unknown size) initialize the elements of the array. ¶2 is a constraint that states: No initializer shall attempt to provide a value for an object not contained within the entity being initialized. Commented Feb 29, 2020 at 15:26

3 Answers 3

4

1. You don't leave room for a null terminator, as you pass them to strlen(), therefore your code exhibits undefined behaviour -

char pal[8] = "ciaooaic";
char pal1[7] = "ciaoaic";

Leave a space for '\0'. Declare and initialize like this -

char pal[9] = "ciaooaic";
char pal1[8] = "ciaoaic";

2. And strlen() returns size_t not int , so write like this -

size_t lenPal = strlen(pal);
size_t lenPal1 = strlen(pal1);

and use %zu specifier to print both these variables.

Sign up to request clarification or add additional context in comments.

5 Comments

size_t is just unsigned int, why are they different?
@Dmaster: because an unsigned int is not an int. And size_t can also be an unsigned long.
@DMaster That is implementation defined what it will be type of and there are other unsigned types also .
Even size_t is not unsigned int, but that doesn't cause the problem, we can even cast it to short and it still shows the same. Why mention it in the answer?
@DMaster Point is that strlen returns size_t not int or unsigned int . That why I mentioned and I don't see any harm in it . And also , then it should be unsigned int specifically if you wan,t not int .
2

You have not kept space for the NULL terminating character \0.


Either increase the size of the array by 1

char pal[9] = "ciaooaic";
char pal1[8] = "ciaoaic";

OR

Do not specify the length at all

char pal[] = "ciaooaic";
char pal1[] = "ciaoaic";

Comments

0

Both the above answers are sufficient to solve your doubts. Increase the the length of both pal and pal1 by one as there there is no space for the assignment of the null character( '\0') at the end. However there is small trick to print the non null terminated character using printf

printf("strlen('%.*s'): %d\n",8, pal, lenPal);
printf("strlen('%.*s'): %d\n",7, pal1, lenPal1);

Link for the above trick:BRILLIANT

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.