convert int to string without using standard library (stdio.h)

C

ceeques

Hi

I am a novice in C. Could you guys help me solve this problem -

I need to convert integer(and /short) to string without using sprintf
(I dont have standard libray stdio.h).

for instance:-
int i =2;
char ch 'A'

My result should be a string ==> "A2"

Results are not going to a standard output - I have a function to
readout/display string from memory.

Thanks,
cQ
 
S

spibou

ceeques said:
Hi

I am a novice in C. Could you guys help me solve this problem -

I need to convert integer(and /short) to string without using sprintf
(I dont have standard libray stdio.h).

for instance:-
int i =2;
char ch 'A

My result should be a string ==> "A2"

I don't understand what you're trying to do. Please
provide more examples. Also write down what your
function should accept as arguments and what its
return type should be. And also try to avoid syntax
errors like char ch 'A' ; it makes it harder to see what
your aim is.
Results are not going to a standard output - I have a function to
readout/display string from memory.

Ok , so where results should go then ?
 
C

ceeques

Thanks for the repy:

I need to convert number (int, short) to a string but cannot use
sprintf as I am using an embedded system. I want to mix text and
number in a display function on the system's output (It doesn't support
printf) but it does have a text to screen function that accepts
strings. I would like to display counters with a message along with it.


Hope my question is clear now.

Thanks in advance,
cQ
 
P

pete

ceeques said:
Hi

I am a novice in C. Could you guys help me solve this problem -

I need to convert integer(and /short) to string without using sprintf
(I dont have standard libray stdio.h).

for instance:-
int i =2;
char ch 'A'

My result should be a string ==> "A2"

Results are not going to a standard output - I have a function to
readout/display string from memory.

/* BEGIN new.c */

#include <stdio.h>

void itoa(int n, char *s);
static char *sput_u(unsigned n, char *s);
static char *sput_up1(unsigned n, char *s);

int main(void)
{
char string[3] = "";
int i = 2;
char ch = 'A';

string[0] = ch;
itoa(i, string + 1);
puts(string);
return 0;
}

void itoa(int n, char *s)
{
if (0 > n) {
*s++ = '-';
*sput_up1(-(n + 1), s) = '\0';
} else {
*sput_u(n, s) = '\0';
}
}

static char *sput_u(unsigned n, char *s)
{
unsigned digit, tenth;

tenth = n / 10;
digit = n - 10 * tenth;
if (tenth != 0) {
s = sput_u(tenth, s);
}
*s = (char)(digit + '0');
return s + 1;
}

static char *sput_up1(unsigned n, char *s)
{
unsigned digit, tenth;

tenth = n / 10;
digit = n - 10 * tenth;
if (digit == 9) {
if (tenth != 0) {
s = sput_up1(tenth, s);
} else {
*s++ = '1';
}
*s = '0';
} else {
if (tenth != 0) {
s = sput_u(tenth, s);
}
*s = (char)(digit + '1');
}
return s + 1;
}

/* END new.c */
 
M

Mark McIntyre

Thanks for the repy:

I need to convert number (int, short) to a string but cannot use
sprintf as I am using an embedded system. I want to mix text and
number in a display function on the system's output (It doesn't support
printf) but it does have a text to screen function that accepts
strings. I would like to display counters with a message along with it.


Hope my question is clear now.

If you have a single-digit number, you can convert it into the
equivalent character by adding '0'
int i = 4;
char x = i + '0'; // x will be '4'

If you have more than one digit, you would have to apply this logic
iteratively over each digit in turn.

To handle floating point types, you'd need to convert to scaled
integers, and re-insert the decimal point as appropriate.
--
Mark McIntyre

"Debugging is twice as hard as writing the code in the first place.
Therefore, if you write the code as cleverly as possible, you are,
by definition, not smart enough to debug it."
--Brian Kernighan
 
D

Default User

ceeques said:
(e-mail address removed) wrote:
Thanks for the repy:

Please don't top-post, your reply belongs following or interspersed
with properly trimmed quotes. See most of the other posts here for
examples.
(text rearranged)
I need to convert number (int, short) to a string but cannot use
sprintf as I am using an embedded system. I want to mix text and
number in a display function on the system's output (It doesn't
support printf) but it does have a text to screen function that
accepts strings. I would like to display counters with a message
along with it.

Review the requests made above. Show the function signature and provide
examples.



Brian
 
W

websnarf

ceeques said:
I am a novice in C. Could you guys help me solve this problem -

I need to convert integer(and /short) to string without using sprintf
(I dont have standard libray stdio.h).

for instance:-
int i =2;
char ch 'A'

My result should be a string ==> "A2"

See if this can help you:

#include <string.h>

char * itostrappend (char * str, int v, int base) {
char d[2];
int rem = v % base;
if (rem < 0) {
strcat (str, "-");
v = -(v / base);
rem = -rem;
} else v /= base;
d[0] = "0123456789abcdefghijklmnopqrstuvwxyz"[rem];
d[1] = '\0';
if (v) str = itostrappend (str, v, base);
strcat (str, d);
return str + strlen (str);
}

void itostr (char * str, int v, int base) { /* Simple wrapper */
str[0] = '\0';
itostrappend (str, v, base);
}

Its not very fast, but it works, and its performance is O(log(v))
(exercise to the reader.) Unfortunately it also requires O(log(v))
stack space.
 
O

Old Wolf

ceeques said:
Hi

I am a novice in C. Could you guys help me solve this problem -

I need to convert integer(and /short) to string without using sprintf
(I dont have standard libray stdio.h).

for instance:-
int i =2;
char ch 'A'

My result should be a string ==> "A2"

Double check that you don't have sprintf in your system libraries
(even if perhaps you don't have the header for it). Also, look for
'itoa' in your system libraries.

If not, download a public domain implementation of sprintf.
 
O

Old Wolf

ceeques said:
I need to convert integer(and /short) to string without using sprintf

#include <string.h>

char * itostrappend (char * str, int v, int base) {
char d[2];
int rem = v % base;
if (rem < 0) {
strcat (str, "-");
v = -(v / base);
rem = -rem;
} else v /= base;
d[0] = "0123456789abcdefghijklmnopqrstuvwxyz"[rem];
d[1] = '\0';
if (v) str = itostrappend (str, v, base);
strcat (str, d);
return str + strlen (str);
}

void itostr (char * str, int v, int base) { /* Simple wrapper */
str[0] = '\0';
itostrappend (str, v, base);
}

Is that supposed to be a serious answer?
 
M

Morris Dovey

ceeques (in (e-mail address removed))
said:

| Thanks for the repy:
|
| I need to convert number (int, short) to a string but cannot use
| sprintf as I am using an embedded system. I want to mix text and
| number in a display function on the system's output (It doesn't
| support printf) but it does have a text to screen function that
| accepts strings. I would like to display counters with a message
| along with it.

char *itos(char *s,int i)
{ char *r = s;
int t;
if (i < 0)
{ i = -i;
*s++ = '-';
}
t = i;
do ++s; while (t /= 10);
*s = '\0';
do *--s = '0' + i % 10; while (i /= 10);
return r;
}

Will convert i to a properly terminated digit string beginning at s
and will prepend a '-' if the value of i is less than zero. It will
return a pointer to the start of the string.
 
M

Mark McIntyre

What's your problem with it?

Its hideously obfuscated, and completely unsuitable for the OP's level
of understanding. It seems more grandstanding than helpful. Perhaps
you meant it differently.
--
Mark McIntyre

"Debugging is twice as hard as writing the code in the first place.
Therefore, if you write the code as cleverly as possible, you are,
by definition, not smart enough to debug it."
--Brian Kernighan
 
E

Eric Sosman

Morris said:
char *itos(char *s,int i)
{ char *r = s;
int t;
if (i < 0)
{ i = -i;
*s++ = '-';
}
t = i;
do ++s; while (t /= 10);
*s = '\0';
do *--s = '0' + i % 10; while (i /= 10);
return r;
}

Will convert i to a properly terminated digit string beginning at s
and will prepend a '-' if the value of i is less than zero. It will
return a pointer to the start of the string.

Something's strange: On my machine this works most of
the time, but once it gave "-./,),(-*,(" as the digit string.
Any idea why? (The value of i was negative and large when
the peculiar output occurred: -2147483648, to be precise.)
 
W

websnarf

Mark said:
Its hideously obfuscated,

Its too short to be obfuscated. I didn't ram things on one line, and I
didn't use side-effects in unexpected ways, I didn't abuse the
preprocessor, and there is nothing mysterious in the algorithm used.
The algorithm is also extremely clear:

1. Break down the number into last digit and upper digits.
2. Deal with negative numbers, by normalizing to a positive number.
3. Figure out the last digit.
4. Recursively output the upper digits unless they are 0.
5. Append the last digit.

The only thing really tricky is how the normalization happens -- step 2
happens *after* step 1, in order to avoid the 2s complement INT_MIN
problem.
[...] and completely unsuitable for the OP's level
of understanding.

What do you know of the OP's level of understanding? Even if it is
over his head, he's got something to study, hasn't he? I don't see
that there's anything in the solution that either the poster doesn't
need for the solution or isn't worthwhile to know anyways.
[...] It seems more grandstanding than helpful.

As opposed to one solution being incorrect, another broken down into a
half dozen sub-functions and you going off into some floating point
divergence (I'd like to see *your* solution to FP->char w/o the std
library).

Modulo a missing * in the OP's question, I have answered the OP's
question fairly exactly, and correctly.
 
M

Morris Dovey

Eric Sosman (in (e-mail address removed)) said:

| Morris Dovey wrote:
|
|| char *itos(char *s,int i)
|| { char *r = s;
|| int t;
|| if (i < 0)
|| { i = -i;
|| *s++ = '-';
|| }
|| t = i;
|| do ++s; while (t /= 10);
|| *s = '\0';
|| do *--s = '0' + i % 10; while (i /= 10);
|| return r;
|| }
||
|| Will convert i to a properly terminated digit string beginning at s
|| and will prepend a '-' if the value of i is less than zero. It will
|| return a pointer to the start of the string.
|
| Something's strange: On my machine this works most of
| the time, but once it gave "-./,),(-*,(" as the digit string.
| Any idea why? (The value of i was negative and large when
| the peculiar output occurred: -2147483648, to be precise.)

Interesting indeed. Could it have been a problem with the target
string area not being large enough to contain the result string? Even
at the boundary point where i = -i might produce a problem, I would
still expect to see an initial sequence of digits.

The problem value is 0xFFFFFFFF80000000 - so there might be a problem
with division of the largest int value if your int size is 32.

It is strange.
 
E

Eric Sosman

Morris Dovey wrote On 07/18/06 10:07,:
Eric Sosman (in (e-mail address removed)) said:

| Morris Dovey wrote:
|
|| char *itos(char *s,int i)
|| { char *r = s;
|| int t;
|| if (i < 0)
|| { i = -i;
|| *s++ = '-';
|| }
|| t = i;
|| do ++s; while (t /= 10);
|| *s = '\0';
|| do *--s = '0' + i % 10; while (i /= 10);
|| return r;
|| }
||
|| Will convert i to a properly terminated digit string beginning at s
|| and will prepend a '-' if the value of i is less than zero. It will
|| return a pointer to the start of the string.
|
| Something's strange: On my machine this works most of
| the time, but once it gave "-./,),(-*,(" as the digit string.
| Any idea why? (The value of i was negative and large when
| the peculiar output occurred: -2147483648, to be precise.)

Interesting indeed. Could it have been a problem with the target
string area not being large enough to contain the result string? Even
at the boundary point where i = -i might produce a problem, I would
still expect to see an initial sequence of digits.

The problem value is 0xFFFFFFFF80000000 - so there might be a problem
with division of the largest int value if your int size is 32.

It is strange.

Not so very strange, actually (I was attempting irony,
but apparently only achieved rust-y ...). The problem is
that INT_MIN may have no corresponding positive int value,
so the computation of `-INT_MIN' overflows. What happens
next is up to the implementation, but on two's complement
systems it is often the case that `-INT_MIN' produces the
value INT_MIN all over again. If this happens, `i = -i'
in the code above does not produce a positive value; `i'
will still be large and negative.

The next piece of the puzzle depends on the behavior
of the modulus operator with negative numbers. In C90, it
is conceivable that you could get lucky: `-13 % 10' could
produce 7 as a result, if `-13 / 10' produces -2. But C90
also allows `-13 % 10' to produce -3 and `-13 / 10' to
produce -1. C99 tightened the rules to *require* the latter,
in part for consistency with other languages and in part
because practically every implementation already did it that
way anyhow. So it's almost a sure bet that `negative % 10'
produces a remainder somewhere between -9 and 0.

The weird characters I reported happen to have (on my
system) encodings that lie just before that of the digit '0'.
Strangeness explained.

To make a long story short: "Emit a minus sign and then
convert the absolute value" is *not* a reliable strategy
for converting integers to digit strings.
 
M

Mark McIntyre

Its too short to be obfuscated. I didn't ram things on one line, and I
didn't use side-effects in unexpected ways, I didn't abuse the
preprocessor, and there is nothing mysterious in the algorithm used.

Ya reckon? "somestring"[var] is generally mysterious to newbies;
The algorithm is also extremely clear:

For martians.
[...] and completely unsuitable for the OP's level
of understanding.

What do you know of the OP's level of understanding?

I can read his original post. Come on, be sensible.
Even if it is
over his head, he's got something to study, hasn't he?

Yeah, right, like the GTOR.
[...] It seems more grandstanding than helpful.

As opposed to one solution being incorrect, another broken down into a
half dozen sub-functions

Like I said, grandstanding. I gave you the benefit before, now I know.
and you going off into some floating point divergence

You're amusing, in a weird sort of a way.

--
Mark McIntyre

"Debugging is twice as hard as writing the code in the first place.
Therefore, if you write the code as cleverly as possible, you are,
by definition, not smart enough to debug it."
--Brian Kernighan
 
M

Morris Dovey

Eric Sosman (in 1153233525.240054@news1nwk) said:

| Morris Dovey wrote On 07/18/06 10:07,:
|| Eric Sosman (in (e-mail address removed)) said:
||
||| Something's strange: On my machine this works most of
||| the time, but once it gave "-./,),(-*,(" as the digit string.
||| Any idea why? (The value of i was negative and large when
||| the peculiar output occurred: -2147483648, to be precise.)
||
|| Interesting indeed. Could it have been a problem with the target
|| string area not being large enough to contain the result string?
|| Even at the boundary point where i = -i might produce a problem, I
|| would still expect to see an initial sequence of digits.
||
|| The problem value is 0xFFFFFFFF80000000 - so there might be a
|| problem with division of the largest int value if your int size is
|| 32.
||
|| It is strange.
|
| Not so very strange, actually (I was attempting irony,
| but apparently only achieved rust-y ...). The problem is
| that INT_MIN may have no corresponding positive int value,
| so the computation of `-INT_MIN' overflows. What happens
| next is up to the implementation, but on two's complement
| systems it is often the case that `-INT_MIN' produces the
| value INT_MIN all over again. If this happens, `i = -i'
| in the code above does not produce a positive value; `i'
| will still be large and negative.
|
| The next piece of the puzzle depends on the behavior
| of the modulus operator with negative numbers. In C90, it
| is conceivable that you could get lucky: `-13 % 10' could
| produce 7 as a result, if `-13 / 10' produces -2. But C90
| also allows `-13 % 10' to produce -3 and `-13 / 10' to
| produce -1. C99 tightened the rules to *require* the latter,
| in part for consistency with other languages and in part
| because practically every implementation already did it that
| way anyhow. So it's almost a sure bet that `negative % 10'
| produces a remainder somewhere between -9 and 0.
|
| The weird characters I reported happen to have (on my
| system) encodings that lie just before that of the digit '0'.
| Strangeness explained.
|
| To make a long story short: "Emit a minus sign and then
| convert the absolute value" is *not* a reliable strategy
| for converting integers to digit strings.

I recognized the irony; but was paying closer attention to the
context. The OP is involved in a situation involving a lot of
judgement calls to resolve trade-offs, as illustrated by the decision
to not use printf(). If this boundary value problem is significant in
his judgement, he will need to determine appropriate mods (use
unsigned types, promote to wider type within the function, etc); but
can use the code provided as a starting point.

From where I sit (blissfully ignorant of his project context) all I
can meaningfully offer is the starting point...
 
H

Herbert Rosenau

Hi

I am a novice in C. Could you guys help me solve this problem -

I need to convert integer(and /short) to string without using sprintf
(I dont have standard libray stdio.h).

for instance:-
int i =2;
char ch 'A'

My result should be a string ==> "A2"

Results are not going to a standard output - I have a function to
readout/display string from memory.

Get paper and a pen. Do what you describes above by hand.

Remember what you have done and write a function that does exactly the
same.
Do it now. It helps you to understund how programming is done.

--
Tschau/Bye
Herbert

Visit http://www.ecomstation.de the home of german eComStation
eComStation 1.2 Deutsch ist da!
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,013
Latest member
KatriceSwa

Latest Threads

Top