Grant
Grant

Reputation: 532

Using itoa() results in: "assignment makes pointer from integer without a cast"

I am working on BCD (Binary Coded Decimal) in C and in charge of writing the different bcd functions.

I need to encode an integer i into buffer char *s of size n. The function returns 0 on success or -1 in case of an overflow (encoding i requires a buffer larger than n).

Here is the function: int bcd_encode(int i, int n, char *s)

and a sample input: assert(bcd_encode(a, 128, s) == 0);

I am writing the code for the function bcd_encode and correct me if I am wrong but I believe in a function and only in a function if you were to have some func(char x[]) and char func(char *x) they would be the same thing? So you can look at both of them as a char array. If it were outside the function definition char x[]; would be an char array and char *x; would be a pointer.

int bcd_encode(int i, int n, char *s){  
    int j = 0;  
    s = itoa(i, s, n+1);  
}

But this returns a warning "assignment makes pointer from integer without a cast" and a undefined symbol for itoa. I've tried a few different variations from

*s = itoa(i); s = itoa(i); s = itoa(i, s, n+1);

Any help would be appreciated. Thanks in advance!

Upvotes: 1

Views: 3663

Answers (4)

Martin Beckett
Martin Beckett

Reputation: 96147

itoa() is undefined means you are missing the header file

 #include <stdlib.h> 

If it's not defined the complier assumes the unknown function itoa() returns an int (for stupid historical reasons).

Always listen to compiler warnings - they are your friend !

Upvotes: 0

Jonathan Leffler
Jonathan Leffler

Reputation: 754570

You said:

... and correct me if I am wrong but I believe in a function and only in a function if you were to have some func(char x[]) and char func(char *x) they would be the same thing? So you can look at both of them as a char array. If it were outside the function definition char x[]; would be an char array and char *x; would be a pointer.

It would be better to regard them both as pointers (rather than both as arrays) inside the function, but you've got the key point - in function argument lists, the distinctions between arrays and pointers are blurred, but elsewhere pointers and arrays are different.

In the code, since itoa() is assumed to return an integer in the absence of information to the contrary, you cannot store that in a pointer or as a pointer (without using a sledgehammer cast, which would leave your code broken).

What does itoa() return? It isn't a standard C function (as in, not in ISO/IEC 9899:1999, nor in POSIX). Wikipedia suggests it returns no value, so you should not be assigning its value anywhere. Linux has it as a non-standard extension in <stdlib.h> with a different interface that returns a char * (which is the value of its second argument). You can safely ignore the return value; in fact, you can also do the assignment (after including the header) but the assignment is a no-op. You do need to know that the function is non-standard, that it has a variety of definitions, and therefore you have to be aware of what is correct for your platform, or avoid using it (maybe by using snprintf() instead).


Quoting the linked Linux manual page:

char* itoa (int __val, char * __s, int __radix)

Convert an integer to a string.

The function itoa() converts the integer value from val into an ASCII representation that will be stored under s. The caller is responsible for providing sufficient storage in s.

Note:
The minimal size of the buffer s depends on the choice of radix. For example, if the radix is 2 (binary), you need to supply a buffer with a minimal length of 8 * sizeof (int) + 1 characters, i.e. one character for each bit plus one for the string terminator. Using a larger radix will require a smaller minimal buffer size. Warning:
If the buffer is too small, you risk a buffer overflow. Conversion is done using the radix as base, which may be a number between 2 (binary conversion) and up to 36. If radix is greater than 10, the next digit after '9' will be the letter 'a'.

If radix is 10 and val is negative, a minus sign will be prepended.

The itoa() function returns the pointer passed as s.

You don't want to use n+1 as the radix.

Upvotes: 1

Jim Balter
Jim Balter

Reputation: 16406

The function returns 0 on success or -1 in case of an overflow (encoding i requires a buffer larger than n).

And yet you aren't doing that.

int j = 0;

What's that for?

s = itoa(i, s, n+1);

Why are you assigning to s?

I've tried a few different variations from

*s = itoa(i); s = itoa(i); s = itoa(i, s, n+1);

Trying things randomly until you stumble upon one that works is not a good approach to programming.

Assigning to either s or *s is inappropriate here and shows a poor understanding of C; I strongly advise obtaining more instruction in the language. Once you have done that, you can use snprintf, e.g.,

#include <stdio.h>
int bcd_encode(int i, int n, char *s){  
    int r = snprintf(s, n, "%d", i);
    return r < n? 0 : -1;  
}

assuming that s is supposed to be NUL-terminated and that n includes the NUL -- those details aren't specified in your description.

BTW, that's not what "BCD" means -- see http://en.wikipedia.org/wiki/Binary-coded_decimal

Upvotes: 1

payne
payne

Reputation: 14187

#include <stdlib.h>

Without that include, the compiler doesn't know anything about itoa() and will assume it returns an int.

Upvotes: 1

Related Questions