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.
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.
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.
This question already has answers here:
Assigning strings to arrays of characters
(10 answers)
Closed 3 years ago.
I want to store a string "hello" in an array of characters char arr[10]
when I run the following code:
#include <stdio.h>
int main(void)
{
char arr[10] = "Hello";
printf("%s", arr);
}
The output is generated fine.
But when this code below is run, I get an error
#include <stdio.h>
int main (void)
{
char arr[10];
char * str = "Hello";
arr = str;
printf("%s", arr);
}
Why is that in the first case the string can be stored in the array and not in the second case?
Is there a way I can store "hello" in the second case?
You should use strncpy() or even better strlcpy() if you are on a BSD system or macOS and portability is not the main concern.
In C, char *p means a pointer to a character string. While writing the following
char arr[10];
char * str = "Hello";
arr = str;
you might have thought that the character string stored in the memory location pointed by str would be copied over to the buffer arr, but C does not do this for you.
The code below does what you want
#include <stdio.h>
#include <string.h>
#define BUFSIZ 10
int main(){
char arr[BUFSIZ];
const char *str=“Hello”; /* I used const here */
strncpy(arr, str, BUFSIZ);
printf(“%s\n”, arr);
return 0;
}
Use strncpy or strlcpy instead of strcpy. Documentation for strncpy is here.
The strcpy is the way to do it, as noted above. You get an error for
arr = str;
in your given code because you are attempting to assign an array, and C does not allow arrays to be assigned. In your first part, the declaration you give
char arr[10] = "Hello";
is legal because it is considered an initialization (since it's in a declaration), not an assignment. That is allowed.
C is not always a bundle of consistency.
To copy a string in C, use strcpy:
char arr[10];
char * str = "Hello";
strcpy(arr, str);
printf("%s\n", arr);
Don't forget to #include <string.h>, which is required for you to have access to this function.
char arr[10] means that arr can be changed;
char * str = "Hello" equals to const char* str = "Hello", so it can not be changed.
so arr = str will occur error.
You should check the memory allocation mechanism in C.
This is initialization of char array; there are special rules
char x[] = "foobar";
This is assignment to a pointer
char *p;
p = "foobar"; // char *p = "foobar"; initialization of pointer
There is no direct way to do assignment of a value to an array of char. You need to assign each individual element
char x[7];
x[0] = 'f'; x[1] = 'o'; x[2] = 'o';
x[3] = 'b'; x[4] = 'a'; x[5] = 'r'; x[6] = 0;
or use a function to do that for you
strcpy(x, "foobar");
I've been writing a C study program on encryption and met an unexpected problem:
When I include parameters into main() function (as int main(int argc, char* argv[])) and try to declare a separate array of chars in my code (char array[2] = {'a','b'};), which has nothing to do with main() arguments, that array somehow gets length of 8 instead of 2 and some junk is added to it when I try to print it out (e.g. ab ?iQ?).
Whereas if I declare main() without any parameters (int main()), the declared char array behaves normally: gets size of 2 and prints out like ab.
Do parameters in main() function set limits on minimum size of arrays in code?
Using strlen() on a char array without a nul termination byte causes undefined behavior.
A string in c, consists of a sequence of non-nul bytes terminated by a nul -> '\0' byte, so this
char array[2] = {'a','b'};
should be
char array[3] = {'a', 'b', '\0'};
for strlen() to work properly.
You can implement a strlen() like this
size_t stringlength(const char *string)
{
size_t length;
length = 0;
while (string[length] != '\0')
length++;
return length;
}
so if the '\0' is not there, it will keep reading from the array beond it's bounds cause the undefined behavior mentioned above.
Help me in solving 2 questions on pointers:
1)Please tell me why do I get 'segmentation fault' when I run following snippet
main()
{
char *str1 = "united";
char *str2 ="front";
char *str3;
str3 = strcat(str1,str2);
printf("\n%s",str3);
}
2)Why don't I get output in following code:
main()
{
char str[10] = {0,0,0,0,0,0,0,0,0,0};
char *s;
int i;
s = str;
for(i=0 ; i<=9;i++)
{
if(*s)
printf("%c",*s);
s++;
}
}
Thank u.
You should review how strcat works. It will attempt to rewrite the memory at the end of your str1 pointer, and then return the destination pointer back to you. The compiler only allocated enough memory in str1 to hold "united\0" (7 chars), which you are trying to fill with "unitedfront\0" (12 chars). str1 is pointing to only 7 allocated characters, so there's no room for the concatenation to take place.
*s will dereference s, effectively giving you the first character in the array. That's 0, which will evaluate to false.
1) compiles to something like:
const char _str1[7] = "united";
const char _str2[6] ="front";
char *str1 = _str1;
char *str2 = _str2;
strcat(str1,str2);
str3 = str1;
str1 points to a buffer which is exactly 7 bytes long and is filled with 6 characters. The strcat put another 5 bytes into that buffer. 7 bytes cannot hold 11 characters.
The C there is no magic! If you do not explicitly allocate space for something, no one else does it either.....
2) isn't going to print anything. It steps through an array, every element of which is 0. It then tests if the current item (*s) is not 0 (if(*s)) , and if so, prints that item as a character. However, since the item always is 0, it always fails to test.
for question 2, think about what the following line does:
if(*s)