1

I am new to C and i am trying to store Integer in a string.Can anyone put lights on how i could do this.

my code:

char *str = (char *)malloc(5 * sizeof(char));
str[0] = 'h';

sprintf(&str[1], "%d", 34);
str[2] = 'e';


expected output: h34e
output: h3e
YasinYA
  • 109
  • 2
  • 6
  • @JohnnyMopp, the string gets terminated later. sorry i meant to sprint – YasinYA Apr 27 '18 at 21:58
  • @JohnnyMopp becaue it's using the wrong index (2 instead of 3), the string remains '\0'-terminated, because `sprintf` writes the '\0'-terminating byte at index 3. So in this case, the code does not yield undefined behaviour. – Pablo Apr 27 '18 at 22:09
  • Possible duplicate of [How to convert an int to string in C](https://stackoverflow.com/questions/8257714/how-to-convert-an-int-to-string-in-c) – MFisherKDX Apr 27 '18 at 22:23

3 Answers3

3

You don't need malloc for that tiny amount of memory, a char str[5] would also do the job in this case. Also bear in mind that you shouldn't cast malloc. And sizeof(char) is always 1, so you can omit that as well. You should also always check the return value of malloc:

char *str = malloc(5);
if(str == NULL)
{
    // error handling
}

And don't forget to free the memory.

But I'm digressing now. The problem in your code problem is that

str[2] = 'e';

is overwriting the 4 in "h34". That's why the output is h3e. After the sprintf call the memory looks like this:

index     0     1     2     3      4
       +-----+-----+-----+------+-----+
       | 'h' | '3' | '4' | '\0' | ??? |
       +-----+-----+-----+------+-----+

The correct index is 3, not 2:

char str[5];
str[0] = 'h';

sprintf(&str[1], "%d", 34);
str[3] = 'e';
str[4] = '\0'; // making sure to terminate string

puts(str); // output is h34e

If you append a character, you must not forget to set the '\0'-terminating byte. That's what I'm doing in str[4] = '\0'. In your example you were "lucky" because you didn't overwrite the '\0'-terminating byte, so the string was still terminated correctly.

Also snprintf takes the length as well, without the length you should use sprintf. In this case you can use sprintf because you know the size of the buffer and the length of the number, you know that you are not going to write beyond the limits, that's why in this case it's OK to use sprintf instead of snprintf.

But of course you can do that in two lines of code:

char str[5];
sprintf(str, "h%de", 34);

But I also like your original code because it forces you to think about how to access elements of the array with indices and how strings are stored in memory. As an exercise this is good. For more serious projects, I wouldn't create strings in such a way. I'd use the one-liner solution.

Barmar
  • 741,623
  • 53
  • 500
  • 612
Pablo
  • 13,271
  • 4
  • 39
  • 59
  • @user3121023 yes, but this is a nice excessive for learning how to use array indices, that's why I used the same code as the OP. – Pablo Apr 27 '18 at 22:04
  • Casting of the malloc does not matter. It did matter 20 years ago when functions without the prototype were allowed. Now if you use less than 20 years old compiler and do not stick to the obsolete pre c99 standards - it is safe. – 0___________ Apr 27 '18 at 22:41
  • 1
    @PeterJ_01 still, it's bad C style. See https://stackoverflow.com/questions/605845/do-i-cast-the-result-of-malloc we link to this page at least 100 times every day for a reason. – Pablo Apr 27 '18 at 22:49
  • @Barmar thanks for fixing my grammar and typos, boy I had a lot of them this time. I usually read my answers before posting, but this time I missed a lot of errors. – Pablo Apr 27 '18 at 22:57
  • You're welcome. My main reason for editing was the confusing "don't have to forget" statement. At first I thought you wrote that you don't have to add the null byte and got it backwards. – Barmar Apr 27 '18 at 23:04
  • 1
    @Pablo old obsolete topic. You may not like it but it is only your personal opinion nowadays. You can link it even billion times a day, but it was the truth when malloc could be called without the stdlib.h included. Now it is not possible as you will get the error. The rest is only about someone's liking. Same as sizeof into or sizeof(int) – 0___________ Apr 27 '18 at 23:15
  • You might want to advise the use of `snprintf` instead of `sprintf` for safer programming, with better protection against undefined behavior. – chqrlie Apr 28 '18 at 09:52
2

You can do it using int snprintf(char *str, size_t size, const char *format, ...) in one line like this:

snprintf(str, 5, "h%de", 34);

snprintf will terminate your string with \0.

medalib
  • 937
  • 1
  • 6
  • 7
1

You can use itoa() function. This function in C language converts int data type to string data type(Null terminated string). Syntax for this function is given below.

char *  itoa ( int value, char * str, int base );

The third parameter base specify the conversion base. For example:- if base is 2, then it will convert the integer into its binary compatible string or if base is 16, then it will create hexadecimal converted string form of integer number.

Note: There may be a chance that itoa() function does not work as this function is not a standard function.

aditya jain
  • 31
  • 1
  • 7