0

In C language i want to store the value of variable integer to another variable as string. How can i achieve this?

Example :

int num1 = 123456789;

I want to store the value of num1 as string in another variable.

Jerry
  • 1,005
  • 2
  • 13
  • Please take some time to read [the help pages](http://stackoverflow.com/help), take the SO [tour], and read [ask]. Also please read [how to write the "perfect" question](https://codeblog.jonskeet.uk/2010/08/29/writing-the-perfect-question/), especially its [checklist](https://codeblog.jonskeet.uk/2012/11/24/stack-overflow-question-checklist/). And if you want to post an answer, then please read about [how to write good answers](https://stackoverflow.com/help/how-to-answer) as well. – Some programmer dude Jul 26 '23 at 11:07
  • Ok, but what does `malloc` have to do with your question (mentioned in the title). What have you got so far? Is this question about storage)memory allocation or about conversion? Options for conversion include `sprintf` and `atoi` you could just look up the documentation for those, or did you want to actually code the conversion yourself? – Clifford Jul 26 '23 at 12:13

4 Answers4

2

The typical approach to determining the size of the string that you will need to store the value is to use snprintf twice. The first time, you pass a NULL pointer (the frist argument is actually irrelevant, but passing NULL makes it clear to the reader what is happening) with a zero limit so that no data is written, but you use the return value to learn the needed size. Then you allocate space and write the data. eg:

#include <stdio.h>
#include <stdlib.h>

int
main(void)
{
    long long digit = 1234567890;
    size_t len = snprintf(NULL, 0, "%lld", digit);
    char *ptr = malloc(len + 1);
    if( ptr == NULL ){
        perror("malloc");
        return 1;
    }
    sprintf(ptr, "%lld", digit);
    printf("%s\n", ptr);
    return 0;
}

Another completely reasonable approach, indeed perhaps more reasonable, is to simply allocate a big buffer. eg, just do char s[1024] and skip the malloc completely. If you want, you can check system limits at compile time and use a buffer that is tuned to the needed size, but there's really no advantage to doing that. By allocating 1024 bytes, you run the risk of your program failing when computers are large enough that the maximum value of a long long is more than 1023 characters when written as a string, but that shouldn't be a concern for quite some time. If that day occurs and a computer is built with a long long that has over 3000 bits, some trivial defensive programming makes it not a big deal:

#include <stdio.h>
#include <stdlib.h>

int
main(void)
{
    long long digit = 1234567890;
    size_t len = snprintf(NULL, 0, "%lld", digit);
    char a[1024];
    char *ptr = a;
    if( snprintf(ptr, sizeof a, "%lld", digit) >= sizeof a ){
        fprintf(stderr, "Value truncated\n");
        return 1;
    }
    printf("%s\n", ptr);
    return 0;
}
William Pursell
  • 204,365
  • 48
  • 270
  • 300
1

If you are required avoid to a 2 pass conversion of first finding the string size needed and then allocating the size, consider a 1 step approach that starts with a worst case size.


To form a string, first determine the maximum size of character array needed.

Number of decimal digits can be approximated with knowing the number of binary value bits in an int or sizeof(int)*CHAR_BIT - 1 scaled by log102 or 0.301...., which is just less than 28/93*1.

Thus the digits needed is not more than (sizeof(int)*CHAR_BIT - 1)*28/93 + 1. Adding 1 for the potential sign bit and 1 for the null character, we arrive at:

#define LOG10_2_N 28
#define LOG10_2_D 93
#define INT_STRING_SIZE ((sizeof(int)*CHAR_BIT - 1)*LOG10_2_N/LOG10_2_D + 3) 
char buf[INT_STRING_SIZE];

Now print into that.

int len = snprintf(buf, sizeof buf, "%d", num1);
assert (len > 0 && (unsigned) len < sizeof buf);
// Allocate a copy if desired.
return strdup(buf);

*1 Rare encoding will also have padding bits, yet that only makes our buffer size a tad too high. Rarely is this a concern.

chux - Reinstate Monica
  • 143,097
  • 13
  • 135
  • 256
  • Why the change from `LOG10_2_APPROX` to `LOG10_2_N / LOG10_2_D`? I see that `strdup` has finally landed in C23. – ad absurdum Jul 26 '23 at 22:24
  • 1
    @adabsurdum With `#define LOG10_2_APPROX 28/93`, The `xxx * LOG10_2_APPROX` relies `xxx * 28` being higher/equal priority than `28/93`. I do not want some one later incorrectly "improving" code with the seeming safe `xxx * (LOG10_2_APPROX)` . – chux - Reinstate Monica Jul 26 '23 at 22:33
  • @adabsurdum ... or employing the common practice of editing in a `()` around a `define` calculation. Consider that bug with `#define LOG10_2_APPROX (28/93)`. – chux - Reinstate Monica Jul 26 '23 at 22:43
  • 1
    Ah yes, one of the programmers' platitudes: if code is good, it will be better with added parentheses! – ad absurdum Jul 26 '23 at 23:05
0

The hint from https://cplusplus.com/reference/cstdlib/itoa/ might help. malloc(sizeof(int)*8+1). Use sprintf after malloc then.

S Dao
  • 555
  • 4
  • 7
-1

sprintf converts data type to string
log10(abs(digit)) works for negative but we have to add 1 extra bit for negative bit so,
len = (log10(abs(digit))) + 2
And for positive integers len = (log10(abs(digit))) + 1
if the integer is 0 so, for integer = 0 the len = 1.

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

int main() {
   long long digit = 1234567890;
   //size required to store the string
   size_t len;

   if(digit < 0) {
     len = (log10(abs(digit))) + 2;
   } else if(digit > 0){
     len = (log10(abs(digit))) + 1;
   } if (digit == 0) len = 1;

   char *ptr = malloc(len);
   //sprintf converts to string
   sprintf(ptr,"%lld",digit);
   printf("%s",ptr);
 }
Jerry
  • 1,005
  • 2
  • 13
  • Is this supposed to be an answer to your own question or is this your current approach for your problem? – Gerhardh Jul 26 '23 at 10:59
  • 2
    `sizeof(char *)` That's clearly wrong. You don't have a pointer to a pointer – Gerhardh Jul 26 '23 at 10:59
  • Is there a good way to convert int variable to string then please help me? – Jerry Jul 26 '23 at 11:02
  • @Gerhardh it's not wrong, just weird. As long as the resulting text fits into `sizeof(char*)` bytes. – Cubic Jul 26 '23 at 11:02
  • 1
    On current systems, `sizeof(char *)` will be at most eight bytes. That's not enough for an *eleven* character string. – Some programmer dude Jul 26 '23 at 11:02
  • 1
    On most contemporary machines `sizeof(char *)` is probably 4 or 8, neither of which is large enough to hold the string "1234567890". – William Pursell Jul 26 '23 at 11:03
  • 1
    And it doesn't really matter if you need to allocate dynamically or can use a plain array, don't skimp on the size. Assuming that `long long` stays at 64 bits for the foreseeable future you know how many digits it can contain. Add one for the minus sign (so it can handle negative numbers) and one for the string null-terminator, and round up to the nearest higher power of two, or 100, or similar, and use that as the size. – Some programmer dude Jul 26 '23 at 11:05
  • If that is your current approach, then you should add it to your question, not provide it as an answer. Please edit your question accordingly and delete this answer. – Gerhardh Jul 26 '23 at 11:05
  • 1
    `floor(log10(abs(digit))) + 1;` Did you test that with a few numbers? Negative numbers as well? What is the result for `0`, `5`, `-5`? Besides that, `abs` doesn't take a `long long`. – Gerhardh Jul 26 '23 at 12:14
  • `int len = digit != 0 ? (log10(abs(digit))) + 1 : 1; char *ptr = malloc(len);` allocates 1 too few when `digit < 0`. – chux - Reinstate Monica Jul 26 '23 at 22:24
  • I think digit != 0 will exact for zero ,not for negative and not for more than 0? – Jerry Jul 26 '23 at 22:28
  • @AniketRaj With current code, `digit = -123`, then `len` is 3. It needs to be 5 for `"-123"`. – chux - Reinstate Monica Jul 26 '23 at 22:38
  • @AniketRaj Why use `int abs(int)` with a `long long`? Are you using a c compiler or some other language? – chux - Reinstate Monica Jul 26 '23 at 22:47
  • @AniketRaj What variable do you want to use with `size_t`? – chux - Reinstate Monica Jul 26 '23 at 23:07
  • @chux-ReinstateMonica size_t for calculating the length of digit? – Jerry Jul 26 '23 at 23:09
  • Sure `size_t len` is fine. – chux - Reinstate Monica Jul 26 '23 at 23:10
  • @chux-ReinstateMonica i have updated my answer is it okay? – Jerry Jul 26 '23 at 23:11
  • @AniketRaj First save time and enable all warnings. Then re-compile. – chux - Reinstate Monica Jul 26 '23 at 23:13
  • At least 2 problems remain. One you can find with enabling all warnings. Review: How many byes does `"1234567890"` need to save as a _string_? – chux - Reinstate Monica Jul 27 '23 at 01:28
  • @Cubic technically it might be OK in that case, but logically I would still call it wrong to use the size of some unrelated data type instead of correct size just because it sometimes might just by accident be large enough. Also, the example clearly will *not* fit into that memory making it wrong again. – Gerhardh Jul 27 '23 at 12:19