-2

I have been trying to use sprintf to add " to the start and end of a integer, however when i use more than 10 digits the program returns the wrong number:

int data2 = 12345678910;
char data3[2];  
sprintf(data3,"\"%i\"", data2);  
send(data3);

The send function outputs the integer to the screen. The result i am getting back is :

"-108508098"

The send function works as i use it elsewhere and it does what it is suppose to.

MShields
  • 31
  • 1
  • 7

2 Answers2

3

Before your edit, your issue is not only with sprintf (which BTW you should not use, prefer snprintf), it is with integral numbers in C (they have a limited amount of bits, e.g. 64 bits at most on my Linux desktop....; read wikipages on computer number format & C data types).

Your use of sprintf is completely wrong (you've got a buffer overflow, which is an undefined behavior). You should code:

char buffer[32];
snprintf(buffer, sizeof(buffer), "%i", data2);
sendsomewhere(buffer);

Notice that on POSIX send needs 4 arguments. You should rename your function to sendsomewhere

You should read more about <stdint.h> and <limits.h>

You probably want to use bignums (or at least int64_t or perhaps long long to represent numbers like 12345678910). Don't reinvent bignums (they are difficult to implement efficiently). Use some library like gmplib

If 64 bits are enough for you (so if your numbers would always be between -263 i.e. −9223372036854775808 and 263-1 i.e. 9223372036854775807), consider using long long (or unsigned long long) numbers of C99 or C11:

long long data2 = 12345678910;
char buffer[32];
snprintf(buffer, sizeof(buffer), "%lld", data2);
sendsomewhere(buffer);

If 64 bits are not enough, you should use bigints (but some recent compilers might provide some _int128_t type for 128-bits ints)

Don't forget to enable all the warnings & debug info when compiling (e.g. with gcc -Wall -Wextra -g), then learn how to use the debugger (e.g. gdb)

Community
  • 1
  • 1
Basile Starynkevitch
  • 223,805
  • 18
  • 296
  • 547
-1
  1. data2 is overflown by the value to which you have initialized it to.
  2. data3 should be able to hold atleast 11 bytes if data2 is of int datatype (+1 for NULL termination), for which you have allocated only 2 bytes.

Here is an example code snippet:

#include <stdio.h>

int main(void)
{
    unsigned long long data2 = 12345678910;
    char data3[32];
    snprintf(data3, sizeof(data3), "\"%llu\"", data2);
    printf("%s\n", data3);
    return 0;
}
Santosh A
  • 5,173
  • 27
  • 37
  • 1
    No, `data3` should hold more than 4 characters when `sprintf`-ing an `int`. On my machine you need 10 characters to hold `INT_MAX`; So your example should have a wider `char data3[24];` to avoid truncation. – Basile Starynkevitch Jul 07 '15 at 11:52
  • 1
    Still wrong, the decimal representation of an `int` can take 10 chars. The decimal representation of a `long long` can take 22 chars (at least on my Linux/x86-64 desktop) – Basile Starynkevitch Jul 07 '15 at 12:17
  • 1) Why use `snprintf()` and not check its result before `printf("%s\n", data3);` not much safer than using `sprintf()`. 2) `char data3[9];` is too small for `long long`. Suggest `#define data2N (sizeof data2 * CHAR_BITS)/3+3` `char data3[data2N];` to right size `char3[]`. – chux - Reinstate Monica Jul 07 '15 at 14:30
  • 1
    @Basile Starynkevitch Minor: suspect your decimal representation of an `int` can take 11 `char` like "-2147483648" + 1 more for the null character. – chux - Reinstate Monica Jul 07 '15 at 14:33