Strange problem with variable in C program [closed] - c

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed last year.
Improve this question
This code is to change decimal "n" to binary that I wrote like this:
#include<stdio.h>
#include<string.h>
int main(){
char str[] = "";
int a = 5;
int n = 5;
while(n > 0){
if (n % 2 == 0) {
strcat(str,"0");
} else {
strcat(str, "1");
}
n = n / 2;
}
strrev(str);
printf("%s", str);
return 0;
}
The problem here is, when I tried to debug and see the variable changing, the "a" changed in a very strange way, although I don't do anything to "a". Why is it like that?

The array str, because it doesn't have an explicit size, is sized to exactly store what it is initialized with. And because an empty string only contains 1 character, namely a terminating null byte, your array is 1 element in size.
This means str isn't large enough to hold any string that's not an empty string, so using strcat on it causes the function to write past the end of the array, triggering undefined behavior. In this case, it manifests as writing into another variable which happens to be adjacent to the array in memory.
The array must be sized properly to hold whatever string it might hold, i.e.:
char str[33] = "";
This gives you enough space to store the binary representation of any nonnegative 32 bit integer.

char str[] = "";
Since there's no explicit length given, the array is given the length of the "" initializer, which contains a single \0 character. This declaration is equivalent to:
char str[1] = {'\0'};
There is no space reserved for additional characters. When you do strcat(str,...) it writes past the end of the array and triggers undefined behavior.
You can fix this by allocating extra space:
char str[100] = "";
Or if you don't like an arbitrary 100 and want the exact size that can handle all numbers:
char str[sizeof n * CHAR_BIT + 1] = "";

Related

Char array in C yields extra characters than required [duplicate]

This question already has an answer here:
What are null-terminated strings?
(1 answer)
Closed 7 months ago.
I have this simple program in which I initialize a string with "HELLO". I need the output to be printed as HLOEL, i.e) all the even indexes (0,2,4) followed by the odd ones (1,2). I could not infer what's wrong with my code, but it yields "HLOELHLO" instead of "HLOEL". Could someone explain what is happening here?
#include <stdio.h>
int main() {
int i,loPos=0,hiPos=0;
char *str="HELLO";
char lo[2];
char hi[3];
for(i=0;i<5;i++)
{
if(i%2==0)
{
hi[hiPos++]=str[i];
}
else
{
lo[loPos++]=str[i];
}
}
printf("%s%s",hi,lo);
return 0;
}
Thanks in Advance!
After the for loop, you need to put string terminating 0 bytes to the new strings, and also make sure they habe room for it:
char lo[2+1];
char hi[3+1];
for(...) {
}
hi[hiPos] = '\0';
Lo[loPos] = '\0';
Otherwise any string functions will have buffer overflow, causing undefined behavior. Generally they will keep reading bytes until by chance they encounter byte with value 0. But as always with undefined behavior, even this can cause your program to do anything.
because C style string need extra one char '\0' as its end. With your code,
the memory layout around two arrays maybe looks like:
lo[0], lo[1], hi[0], hi[1], hi[2], something else equal 0,
printf stops when it meets a '\0'
you should declare arrays as:
char lo[3];
char hi[4];
lo[2] = '\0';
hi[3] = '\0';

How can I assign part of a string to a variable in C language [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 2 years ago.
Improve this question
I'm trying to solve homework and I'm stuck in this problem because I'm used to Python, not C.
I want a piece of code that can put the last 2 chars in a word to a variable.
For example
Word: Hello
newVar = "lo"
Word: Sorry
newVar = "ry"
Please keep it simple, and if you wanna use something please try to explain it.
Lets create the string for you:
char word[] = "Hello";
If we "draw" the string how it looks like in memory it will be like this:
+-----+-----+-----+-----+-----+------+
| 'H' | 'e' | 'l' | 'l' | 'o' | '\0' |
+-----+-----+-----+-----+-----+------+
Now to get the end of the string, the last 'l' and 'o' we can simply create a pointer to the last 'l':
char *pointer_to_last_l = &word[3];
This pointer can be used as any other null-terminated string:
printf("end of string is %s\n", pointer_to_last_l);
If you really need to make a copy, then create a new array and use strcpy to copy from the character you want.
A "string" in C is nothing more than a sequence of characters, terminated by the special null character (not to be confused with a null pointer).
When you pass a string to a function, what you really pass is a pointer to the first character in such a sequence. Typically this is a pointer to the first character in an array.
But there is nothing to say that the pointer must be to the first character in the array. If we take the printf call from above:
printf("end of string is %s\n", pointer_to_last_l);
The variable pointer_to_last_l is pointing to the fourth character in the array. So the printf function will think that the string you pass is only "lo".
So to copu this sub-string to a new array that's the pointer you use as source:
char new_word[8]; // Enough space for a small string
strcpy(new_word, &word[3]);
char *copyLastTwo(char *buff, const char *str)
{
if(buff && str)
{
size_t len = strlen(str);
len = len < 2 ? 0 : len - 2;
strcpy(buff, str + len);
}
return buff;
}
int main(void)
{
char newvar[3];
copyLastTwo(newvar, "Hello");
printf("Last two: %s\n", newvar);
}

Converting string to char* [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 6 years ago.
Improve this question
When I try to convert a char[] to char* there are unneeded characters added to the char* variable
int keySize = getKeySize(key2);
char* key = (char*)malloc(sizeof(keySize));
int i;
char s[keySize-1];
int i2;
for(i2=0; i2<keySize; i2++)
{
s[i2] = getCharacter(key2, i2);
}
strncpy(key, s, keySize);
There is no string data type in C programming language. Strings in C are represented as array of characters.
Note: C-Strings are actually character array terminated by '\0' character. That means, last character in any C-String in C will be used to store a '\0' character which marks the end of the string. To store n characters in C-String in C, you should define a character array of size (n+1).
Why should we terminated it by '\0'?
The '\0' termination is what differentiates a char array from a c-string in C programming language. Most string-manipulating functions (like strcpy) relies on '\0' character to know when the string is finished (and its job is done!), and won't work with simple char-array (eg. they'll keep on working past the boundaries of the array, and continue until it finds a '\0' character somewhere in memory - often corrupting memory as it goes).
Therefore, storing a '\0' character (at the end) is necessary if you want to use functions of #include <string.h> like strcpy() as they rely on '\0' character to mark the end of the character array.
'\0' is defined to be a null character - that is a character with all bits set to zero (and thus has a value 0). This has nothing to do with pointers. Read more about it here.
In your program, you want two character arrays key (dynamically allocated) and s to hold a copy of another character array key2 of size keysize. Then, both character arrays should be of atleast keysize + 1 (+1 to hold a '\0' character) size.
Change:
char* key = (char*)malloc(sizeof(keySize));
To:
char* key = malloc(keySize+1); // Don't Type-Cast malloc
And
Change:
char s[keySize-1];
To
char s[keySize+1];
While allocating, you should allocate one more than the size. Currently you are allocating 4 bytes only.
char* key = (char*)malloc(keySize+1);
//instead of
char* key = (char*)malloc(sizeof(keySize));
s should have a size of keySize+1
char s[keySize+1];
// instead of
char s[keySize-1];
What about this?
There are some errors about the dimension of s, I suggest you tu use strncpy
#include <string.h>
int main(){
//bla bla ...
int keySize = getKeySize(key2);
char* key = malloc(keySize+1);;
int i2;
for(i2=0; i2<keySize; i2++){
s[i2] = getCharacter(key2, i2);
}
char s[keySize+1];
strncpy(s, key, sizeof s - 1);
s[keySize] = '\0';
r
return 0;
}
Anyway more information about it please,I supposed you wanted this

C - How can I concatenate an array of strings into a buffer?

I am trying to concatenate a random number of lines from the song twinkle twinkle. Into the buffer before sending it out because I need to count the size of the buffer.
My code:
char temp_buffer[10000];
char lyrics_buffer[10000];
char *twinkle[20];
int arr_num;
int i;
twinkle[0] = "Twinkle, twinkle, little star,";
twinkle[1] = "How I wonder what you are!";
twinkle[2] = "Up above the world so high,";
twinkle[3] = "Like a diamond in the sky.";
twinkle[4] = "When the blazing sun is gone,";
twinkle[5] = "When he nothing shines upon,";
srand(time(NULL));
arr_num = rand() % 5;
for (i=0; i<arr_num; i++);
{
sprintf(temp_buffer, "%s\n", twinkle[i]);
strcat(lyrics_buffer, temp_buffer);
}
printf("%s%d\n", lyrics_buffer, arr_num);
My current code only prints 1 line even when I get a number greater than 0.
There are two problems: The first was found by BLUEPIXY and it's that your loop never does what you think it does. You would have found this out very easily if you just used a debugger to step through the code (please do that first in the future).
The second problem is that contents of non-static local variables (like your lyrics_buffer is indeterminate. Using such variables without initialization leads to undefined behavior. The reason this happens is because the strcat function looks for the end of the destination string, and it does that by looking for the terminating '\0' character. _If the contents of the destination string is indeterminate it will seem random, and the terminator may not be anywhere in the array.
To initialize the array you simply do e.g.
char lyrics_buffer[10000] = { 0 };
That will make the compiler initialize it all to zero, which is what '\0' is.
This initialization is not needed for temp_buffer because sprintf unconditionally starts to write at the first location, it doesn't examine the content in any way. It does, in other words, initialize the buffer.
Update the buffer address after each print after initializing buffer with 0.
char temp_buffer[10000] = {0};
for (i=0; i<arr_num; i++) //removed semicolon from here
{
sprintf(temp_buffer + strlen(temp_buffer), "%s\n", twinkle[i]);
}
temp_buffer should contain final output. Make sure you have enough buffer size
You don't need strcat

Strange characters at the end of string

I want to fill a string with '_' so I have
while (i < length) {
myWord[i] = 95;
i++;
}
length is const int typed by user. but when i type printf("%s",myWord); it's output is '____#S' or '____#' or sometimes it's output is good.
Where is a problem? Thank you :)
A String must end with a \0 char
while (i < length) {
myWord[i] = 95;
i++;
}
myWorkd[i] = 0;
Allowing the user to enter in the length of the string is prone to error. What if the user enters in 99999 and the length is actually 10? Boom. Undefined behavior.
If you had used a string literal, it would have been automatically null-terminated by default. char arrays are not automatically null-terminated.
What happens if a string that isn't null-terminated gets passed to
strlen()? Undefined Behavior. strlen(), when given such a beast,
will keep searching memory until it a) finds a null character; or b)
hits an address that causes a memory protection fault of some sort (or
worse). strlen(), at least, is read-only; so it won't corrupt data.
http://c2.com/cgi/wiki?NonNullTerminatedString
Since you don't know the size of the array, a safer alternative would be to figure it out yourself:
int elements_in_x = sizeof(x) / sizeof(x[0]);
For the specific case of char, since sizeof(char) == 1, sizeof(x) will yield the same result.
If you only have a pointer to an array, then there's no way to find the number of elements in the pointed-to array. You have to keep track of that yourself. For example, given:
char x[10];
char* pointer_to_x = x;
there is no way to tell from just pointer_to_x that it points to an array of 10 elements. You have to keep track of that information yourself.
Most probably you forget to terminate your string with NUL (\0) character.

Resources