I don't understand why there are random char after abc. what is the reason? How to print out only abc? Thanks!
#include <stdio.h>
int main()
{
char arr[3];
char(*ptr)[3]; // declare a pointer to an array
arr[0] = 'a';
arr[1] = 'b';
arr[2] = 'c';
ptr = &arr;
printf("%s\n", arr);
//printf("%s\n", ptr);
return 0;
}
The string need to be terminated with a \0. Make sure to allocate enough space to store the terminator as well.
#include <stdio.h>
int main()
{
char arr[4];
char(*ptr)[4]; // declare a pointer to an array
arr[0] = 'a';
arr[1] = 'b';
arr[2] = 'c';
arr[3] = '\0'; // <-- terminator
ptr = &arr;
printf("%s\n", arr);
//printf("%s\n", ptr);
return 0;
}
Note that using char arr[4] you will have random content in your array. If instead you would use
char arr[4] = "abc";
This will lead to
char arr[4] = {'a', 'b', 'c', 0};
See how the other places are filled with a 0 so you don't have to set it yourself.
The reason of the random characters is that you are trying to output the array as a string using the conversion specifier %s.
But the character array arr does not contain a string (a sequence of characters terminated by the zero character '\0').
So to output it using the function printf you can do for example the following way:
printf( "%*.*s\n", 3, 3, arr );
From the C Standard (7.21.6.1 The fprintf function)
4 Each conversion specification is introduced by the character %.
After the %, the following appear in sequence:
— An optional precision that gives ... the maximum number of bytes to
be written for s conversions.
String must be terminated with 0 .
So you have to declare 4 element array.
char arr[4] = "abc";
The strlen function wich all printf function family uses, reads string till 0 value is found.
So strlen returned length of memory block that starts at your array beginning and ends with first zero.
This can cause undefined behavior.
Related
Hi i am fairly new in C language and i was trying to understand the strings. As i know, strings are just an array of characters and there shouldn't be a difference between char a[]= "car" and char a[] = {'c','a','r'}.
When i try to print the string as:
char a[] = "car";
char b[] = "testing the cars";
printf("%s", a);
the output is just car and there's no problem.But when i try to print it as:
char a[] = {'c','a','r'};
char b[] = "testing the cars";
printf("%s", a);
it's printing the b too. Can you explain what's the reason of it?
The %s specifier of printf() expects a char* pointer to a null-terminated string.
In the first case, a and b are both null-terminated. Initializing a char[] array of unspecified size with a string literal will include the literal's null-terminator '\0' character at the end. Thus:
char a[] = "car";
is equivalent to:
char a[] = {'c', 'a', 'r', '\0'};
In the second case, a is NOT null-terminated, leading to undefined behavior, as printf("%s", a) will read past the end of a into surrounding memory until it eventually finds a '\0' character. It just happens that, in your case, b exists in that memory following a, but that is not guaranteed, the compiler can put b wherever it wants.
When returning the length and the size of an empty string in C, the values differ. Why is that so?
char b[7];
printf("String Length: %d", strlen(b)); // Returns 22
printf("String Size: %d", sizeof(b)); // Returns 7
This is due to the fact that the allocated space of your array isn't cleared.
So on the stack where you char b[7]; is placed there is random data.
The strlen() function starts on you the memory location b[0] to search for an end character '\0'.
In your case the first '\0' character is found and the 23rd location resulting in a length of 22. This number of 22 is undefined behaviour and can be different everytime you run your code.
If you initialize your array with '\0' at b[0] it will return a length of 0.
The reason why strlen and sizeof gives different results is that the sizeof operator gives you the size of the array itself (in bytes) while the strlen function counts the number of "characters" until it finds a string null-terminator.
Even if you initialized the array (like e.g. char b[7] = "a";) the strlen function would give a different result from the sizeof operator.
There's simply no way you can make both give the same result without having undefined behavior one way or another.
Now as for why strlen returns 22 in your case, it's because uninitialized local variables, even arrays, really are uninitialized. Their values and contents are indeterminate and could be seen as random or garbage. Your array just happen to not have a random null-terminator inside it.
When you pass a pointer to the first element of the array to the strlen function, it will continue to look for the null-terminator even if it goes out of bounds. And in your specific case there just happens to be a byte corresponding to the null-terminator after strlen have counted 22 "random" or "garbage" characters.
When returning the length and the size of an empty string in C, the
values differ. Why is that so?
If the array does not have the static storage duration then it does not contain a string even empty. It is just uninitialized and has indeterminate value. So using the function strlen results in undefined behavior.
Pay attention to that these calls
printf("String Length: %d", strlen(b));
printf("String Size: %d", sizeof(b));
have undefined behavior because there are used incorrect conversion specifiers. You have to use %zu instead of %d.
You could declare the array like
char b[7] = "";
or like
char b[7] = { '\0' };
or even like
char b[7] = { [6] = '\0' };
In these cases the array indeed contains an empty string and the function strlen will return 0.
In any case the function strlen and the operator sizeof return different values because the function strlen does not count the terminating zero of a string stored in an array.
Consider the following demonstrative program
#include <stdio.h>
#include <string.h>
int main(void)
{
char s[] = "Hello";
printf( "strlen( s ) = %zu\n", strlen( s ) );
printf( "sizeof( s ) = %zu\n", sizeof( s ) );
return 0;
}
Its output is
strlen( s ) = 5
sizeof( s ) = 6
One [fixed-size] array can hold different length strings (at different times, of course)
char t[10]; x = sizeof t; /* 10 */
x = strlen(t); /* BANG: t is not valid */
t[0] = '\0'; x = strlen(t); /* 0 */
strcpy(t, "1"); x = strlen(t); /* 1 */
strcpy(t, "12345678"); x = strlen(t); /* 8 */
strcpy(t, "123456789"); x = strlen(t); /* 9 */
strcpy(t, "1234567890"); /* BANG */
I am a beginner of c. Today when i write a c program, I find some strange thing.
What i want it to show is abc, but it show abcefg. I want to know why it's so shown.
the code is:
#include <stdio.h>
int main() {
char a[3] = "abc";
char b[3] = "efg";
printf("%s", a);
return 0;
}
It's answer is not abc but abcefg
Strings in C are zero terminated with '\0'. "abc" actually is { 'a', 'b', 'c', '\0' }, which is 4 chars. Your array a only has room for 3 chars so the '\0' isn't stored. When printf() tries to print the string stored in a it reads and prints one character a time until it encounters a terminating '\0', but there is none. So it continues reading and printing. And it happens that b is right next to a in memory, so the content of b gets printet as well.
Cure:
#include <stdio.h>
int main(void)
{
char a[4] = "abc";
char b[4] = "efg";
printf("%s", a);
}
or, even better, don't specify a size for the arrays at all. Let the compiler figure out the correct size based on the initializer "abc":
#include <stdio.h>
int main(void)
{
char a[] = "abc";
char b[] = "efg";
printf("%s", a);
}
char a[3] = "abc"; misses space for the 0-terminator, so printf will read out of bounds (undefined behavior) into the next memory location , where it finds the b array (by luck).
You should use char a[4] = "abc"; or char a[] = "abc";.
When you do not write an array size, the compiler will evaluate the minimum size from the initialization.
char b[3] = "efg"; has the same problem, but it seems that you are lucky enough to have a 0 byte afterwards.
#include <stdio.h>
int main()
{
char*m ;
m="srm";
printf("%d",*m);
return 0;
}
The output is 115. Can someone explain why it gives 115 as output?
*m is the same as m[0], i.e. the first element of the array pointed to by m which is the character 's'.
By using the %d format specifier, you're printing the given argument as an integer. The ASCII value of 's' is 115, which is why you get that value.
If you want to print the string, use the %s format specifier (which expects a char * argument) instead and pass the pointer m.
printf("%s\n", m);
You have a few problems here,
the first one is that you're trying to add three bytes to a char, a char is one byte.
the second problem is that char *m is a pointer to an address and is not a modifiable lvalue. The only time you should use pointers is when you are trying to point to data
example:
char byte = "A"; //WRONG
char byte = 0x61; //OK
char byte = 'A'; //OK
//notice that when setting char byte = "A" you will recieve an error,
//the double quotations is for character arrays where as single quotes,
// are used to identify a char
enter code here
char str[] = "ABCDEF";
char *m = str;
printf("%02x", *m); //you are pointing to str[0]
printf("%02x", *m[1]); //you are pointing to str[1]
printf("%02x", *m[1]); //you are pointing to str[1]
printf("%02x", *(m + 1)); //you are still pointing to str[1]
//m is a pointer to the address in memory calling it like
// *m[1] or *(m + 1) is saying address + one byte
//these examples are the same as calling (more or less)
printf("%02x", str[0]); or
printf("%02x", str[1]);
Pointers and arrays act similarly .Array names are also pointers pointing to the first element of the array.
You have stored "srm" as a character array with m pointing to the first element.
"%d" will give you the ASCII value of the item being pointed by the pointer.
ASCII value of "s" is 115.
if you increment your pointer (m++) then print it's ascii value , output will be ascii value of "r" - 114.
#include <stdio.h>
int main()
{
char *m ;
m="srm";
m++; //pointing to the 2nd element of the array
printf("%d",*m); //output = 114
return 0;
}
Hi I'm new to programming.
In the following code str is a pointer to a character, so str should contain the address of the character 'h'. Therefore %p should be used to print that address. But I don't understand how %s is used for printing a pointer parameter.
#include<stdio.h>
int main (){
char s[] = "hello";
char *str = s;
int a[] = {1, 2, 3, 4, 5};
int *b = a;
printf("%s\n", str); // I don't understand how this works ?
printf("%c\n", *str); // This statement makes sense
printf("%c\n", *(str + 1)); // This statement also makes sense.
printf("%p\n",str); // This prints the address of the pointer str. This too makes sense.
printf("%d\n",*b); // makes sense, is the same as the second print.
// printf("%d",b); // I don't understand why str pointer works but this gives a compile error
return 0;
}
char s[] = "hello";
Declares an array of zero-terminated characters called s. Its the same as writing
char s[6] = { 'h', 'e', 'l', 'l', 'o', '\0' };
As you can see, the quotation marks are a shorthand.
char *str = s;
This declares str to be a pointer to a character. It then makes str point to the first character in s. In other words, str contains the address of the first character in s.
int a[] = {1, 2, 3, 4, 5};
Declares an array of integers. It initializes them to the values 1-5, inclusive.
int *b = a;
Declares b to be a pointer to an int. It then makes b point to the first int in a.
printf("%s\n", str);
The %s specifier accepts the address of the first character in the string. printf then walks from that address, printing the characters it sees, until it sees the \0 character at the end.
printf("%c\n", *str);
This prints the first character in str. Since str is pointing to a character (the first character in the string), then *str should obtain the character being pointed at (the first character in the string).
printf("%c\n", *(str + 1));
This prints the second character in str. This is the long way of writing str[1]. The logic behind this is pointer arithmetic. If str is the address of a character, then str + 1 is the address of the next character in the array. Since (str + 1) is an address, it may be dereferenced. Thus, the * obtains the character 1 character past the first character of the array.
printf("%p\n",str);
The %p specifier expects a pointer, just like %s would, but it does something else. Instead of printing the contents of a string, it simply prints the address the pointer is containing, in hex.
printf("%d\n",*b);
This prints the first int in the array pointed to by b. This is equivalent to writing b[0].
printf("%d",b);
b is an int *, not an int, which is what %d expects. If you were trying to print the address of the first element of the array, the specifier would be %p, not %d. Also, this line should not generate a compiler error. Instead, it should have been a runtime undefined behavior, since the compiler does not know what a printf format string is.