I need to figure out how to append an int to a string, so basically i need to convert the int to a string 1st, but I cant figure out how. :rolleyes: any help would be greatly appreciated. thank you, courtney

Recommended Answers

All 21 Replies

Greetings,

This process is not hard since the default libraries included a function to do this. It's called itoa().

» char *itoa(int value, char *buffer, int radix);
Converts an integer value to a null-terminated string using the specified radix and stores the result in the given buffer.
If radix is 10 and value is negative the string is preceded by the minus sign (-). With any other radix, value is always considered unsigned.
buffer should be large enough to contain any possible value: (sizeof(int)*8+1) for radix=2, i.e. 17 bytes in 16-bits platforms and 33 in 32-bits platforms.
Further information can be found here.

Here is an example of how to use this function:

#include <stdlib.h>	// for itoa() call
#include <stdio.h>	// for printf() call

int main() {
	int num = 123;
	char buf[5];

	// convert 123 to string [buf]
	itoa(num, buf, 10);

	// print our string
	printf("%s\n", buf);

	return 0;
}

I hope this helps,
- Stack Overflow

This process is not hard since the default libraries included a function to do this. It's called itoa().

And itoa is nonstandard. A standard function is sprintf.

#include <stdio.h>
   
   int main(void)
   {
      const char base[] = "filename";
      char filename [ FILENAME_MAX ];
      int number = 42;
      sprintf(filename, "%s%d", base, number);
      printf("filename = \"%s\"\n", filename);
      return 0;
   }
   
   /* my output
  filename = "filename42"
  */
sprintf(filename, "%s%d", base, number);

Ah, yes. Though remember sprintf() does not calculate for buffer overflow. sprintf() doesn't flush any file buffer, in fact it doesn't have any buffer associated with it. sprintf() operates on a character buffer (not quite the same thing). If you overflow that buffer you can crash the system.

A safer version of sprintf() is snprintf() which unfortunately isn't very standard yet. It appears in various forms from many compiler vendors and was finally standardized in C99 and will hopefully make it as part of standard C++ in the next standard of C++. Until then you just have to dig up the unstandard version of it if you have one.

If you have no unstandard version of snprintf() you're sort of out of luck. You can of course always write your own version of sprintf() but it can be quite tricky unless you have your compiler's version of sprintf().

Here is an open-source version of snprintf() and others if interested:
snprintf.c - a portable implementation snprintf (etc...)

Writing your own version of itoa() on the contrary is quite simple. Just for reference, here is an example of how itoa() works:

#include <stdio.h>
//#include <string.h>

// Function declarations
// typedef __w64 unsigned int size_t
size_t strlen(const char *);
char *strrev(char *);
char *itoa(int, char *, int);

int main() {
	int num = 123;
	char buf[5];

	itoa(num, buf, 10);

	printf("%s\n", buf);

	return 0;
}

size_t strlen(const char *string) {
	const char *s;

	s = string;
	while (*s)
		s++;
	return s - string;
}

char *strrev(char *str) {
	char *p1, *p2;

	if (!str || !*str)
		return str;

	for (p1 = str, p2 = str + strlen(str) - 1; p2 > p1; ++p1, --p2) {
		*p1 ^= *p2;
		*p2 ^= *p1;
		*p1 ^= *p2;
	}

	return str;
}

char *itoa(int n, char *s, int b) {
	static char digits[] = "0123456789abcdefghijklmnopqrstuvwxyz";
	int i=0, sign;
    
	if ((sign = n) < 0)
		n = -n;

	do {
		s[i++] = digits[n % b];
	} while ((n /= b) > 0);

	if (sign < 0)
		s[i++] = '-';
	s[i] = '\0';

	return strrev(s);
}

It isn't perfect, but it gets the job done.


- Stack Overfow

>Though remember sprintf() does not calculate for buffer overflow.
Neither does itoa. ;)

>A safer version of sprintf() is snprintf() which unfortunately isn't very standard yet.
It is standard, but the standard just isn't widely implemented yet. As it is, C89 is the dominant C standard, and snprintf is nothing more than an extension on many compilers.

>Writing your own version of itoa() on the contrary is quite simple.
Yes, but doing it correctly is not as trivial as some would have you believe.

>*p1 ^= *p2;
>*p2 ^= *p1;
>*p1 ^= *p2;
It's beyond me why people still use this.

» Neither does itoa.
Exactly, though now there is a working prototype. It wouldn't be hard for someone to modify it and make it safer. It is alot better off than re-writing sprintf().

» It is standard, but the standard just isn't widely implemented yet.
Standard only in C99.

» It's beyond me why people still use this.
Bitwise XOR Operator ^
a^b: 1 if both bits are different. 3 ^ 5 is 6.


- Stack Overflow

» It's beyond me why people still use this.
Bitwise XOR Operator ^
a^b: 1 if both bits are different. 3 ^ 5 is 6.

Yes, I think several of us know this swap trick. To others it may be confusing. It might even be confusing to the compiler such that it doesn't optimize as well as the straightforward approach. Other hacks too.

>>I need to figure out how to append an int to a string
>Ah, yes. Though remember sprintf() does not calculate for buffer overflow.

You must be on a platform with some really huge ints :lol: (whose decimal representation size, by the way, can be accounted for at compile time).

>It wouldn't be hard for someone to modify it and make it safer.
Don't forget that someone would also have to modify it to make it correct as well as safer. :) I was implying previously that your code has a bug.

» It is standard, but the standard just isn't widely implemented yet.
>Standard only in C99.
Yes, that would be the standard that isn't widely implemented yet. Unless you know of any others that is. ;)

>Bitwise XOR Operator ^
>a^b: 1 if both bits are different. 3 ^ 5 is 6.
I'm well aware of what it does and how it does it. What confuses me is why people still think that it's a neat trick. The XOR swap is difficult to get right because of obscurity, and when it is right, it isn't very flexible. On top of that, it may not be as efficient as you think.

I need to figure out how to append an int to a string, so basically i need to convert the int to a string 1st, but I cant figure out how. :rolleyes: any help would be greatly appreciated. thank you, courtney

hope this helps :

int i = 42; // number to convert
char buffer[3]; // 3 digit buffer
char* output; //output string (already filled with something)
 
sprintf(buffer, "%d", i);
strcat(output, buffer);

Don't new people bother looking at dates? This thread is only 3 years old... :eek:

Don't new people bother looking at dates? This thread is only 3 years old... :eek:

Only... ? ;)

> char* output; //output string (already filled with something)
> strcat(output, buffer);
It's not like it's a really good answer to a long standing problem.

sprintf()

Three years later you repeat post #3. What would we do without your guidance?

old but .. how method to do it at microcontrollers (16bit) ? for msp430 in stdlib.h there is no itoa() in CCS IDE

write your own similar to this. You won't need to write a complete implementation if all you need it to convert an integer to string. In that case its the same as atoi()

at link is showed input/output of function but no pseudocode to implementation .-. useless...

And in this thread (the 4th post, to be precise) is a full working implementation. Hmm...

also find some code for ftoa() but there is some bugs or what...

ftoa() is a significantly more difficult function to write than itoa(). itoa() really is as simple as this:

char *itoa(int value, char *s, int radix)
{
    const char *digits = "0123456789abcdefghijklmnopqrstuvwxyz";
    unsigned long ulvalue = value;
    char *p = s, *q = s;
    char temp;

    if (radix == 10 && value < 0) {
        *p++ = '-';
        q = p;
        ulvalue = -value;
    }

    do {
        *p++ = digits[ulvalue % radix];
        ulvalue /= radix;
    } while (ulvalue > 0);

    *p-- = '\0';

    while (q < p) {
        temp = *q;
        *q++ = *p;
        *p-- = temp;
    }

    return s;
}

The corresponding ftoa() appears functional on the surface, and will work for the most part:

char *ftoa(double value, char *s, int precision)
{
    char *p = s, *q = s, *end;
    double ipart, fpart;
    char temp;

    if (value < 0) {
        *p++ = '-';
        q = p;
    }

    fpart = modf(fabs(value), &ipart);

    /* Build the integer part of the mantissa */
    while (fabs(ipart - 0) > 1) {
        *p++ = (char)(fmod(ipart, 10) + '0');
        ipart /= 10;
    }

    if (p == s || (!isdigit(s[0]) && p == s + 1)) {
        /* There were no digits before the decimal point; force 0 */
        *p++ = (char)(fmod(ipart, 10) + '0');
    }

    end = p;
    *p-- = '\0';

    while (q < p) {
        temp = *q;
        *q++ = *p;
        *p-- = temp;
    }

    *end++ = *localeconv()->decimal_point;

    /* Build the fractional part of the mantissa */
    while (--precision >= 0) {
        fpart *= 10;
        *end++ = (char)(fmod(fpart, 10) + '0');
    }

    *end = '\0';

    return s;
}

But it's naive in that floating point isn't so simple that this approach will do more than approximate the digits. There are a number of degenerate edge cases where the string representation isn't accurate relative to the stored value.

A correct and accurate algorithm to convert floating point values to strings is much more complex of a problem. Here are some links that highlight the issues and a full implementation that does work in all cases (though it assumes IEEE floating point):

How to print floating point numbers accurately.
Why does dtoa contain so much code?
http://www.netlib.org/fp/dtoa.c

pity that useful functions are not implemented in compiler :-/

If compilers had to implement every piddling function that someone found useful in the form that they found most useful, they'd be bloated piles of shit. You should be pleased that your embedded compiler isn't bloated with unessential things, because that's what makes it usable for the microcontroller.

hm.. at link is showed input/output of function but no pseudocode to implementation .-. useless.

I assumed you are a competent programmer, one who knew how to think on his/her own but maybe that was reaching a lot on my part.

Both thanks for answer, I am beginer (only) in C, I am learning embedded C and I am discovering basic principles. Still searching for book where is lightly explained programattors techniques (for operations with number, bytes, sending via interface, operation with data into buffers,...) and other (for you) known stuffs :-)

If you haven't done it aleady, search amazon.com for C programming books. First learn how to write standard C language programs on your pc. Once you have done that you can delve into embedded programming. I started writing embedded programs about 10 years ago and it was my experience that there are almost no books on the topic. The only one I found was from Microsoft Press. There are some differences between standard C and embedded C, but not a lot. The biggest difference I found was in stdio.h. Of course it will depend on which device you want to write for.

yes, printf is markant different between PC and MCU (PC: printf to monitor, MCU:to display,Uart,...).. I also have some books but its a problem to have a good book with good examples, so Im searching on the Internet

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.