I'm trying to write a function that prefixes a string with its length. I can't seem to assign a char[] to a char *. Mysteriously, if I print out some debugging code before the assignment, it works.
char *prefixMsgWLength(char *msg){
char *msgWLength;
int msgLength = strlen(msg);
if (msgLength == 0){
msgWLength = "2|";
}
else{
int nDigits = floor(log10(abs(msgLength))) + 1;
int nDigits2 = floor(log10(abs(msgLength + nDigits + 1))) + 1;
if (nDigits2 > nDigits){
nDigits = nDigits2;
}
msgLength += nDigits + 1;
char prefix[msgLength];
sprintf(prefix, "%d|", msgLength);
strcat(prefix, msg);
// if I uncomment the below, msgWLength is returned correctly
// printf("msg: %s\n", prefix);
msgWLength = prefix;
}
return msgWLength;
}
The problem in your code is
msgWLength = prefix;
here, you're assigning the address of a local variable (prefix) to the pointer and you try to return it.
Once the function finishes execution, the local variables will go out of scope and the returned pointer will be invalid.
You need to make prefix as a pointer and allocate memory dynamically, if you want it to retain it's existence after returning from the function.
String reallocation to the exact length can be very cumbersome in C. You'd probably be much better off just using a sufficiently large buffer. Here, I use limits.h to determine the size of a line buffer according to the system (LINE_MAX):
#include <stdio.h>
#include <limits.h>
#include <string.h>
int main()
{
/* Our message */
char const msg[] = "Hello, world!";
/* Buffer to hold the result */
char buffer[LINE_MAX];
/* Prefix msg with length */
snprintf(buffer, LINE_MAX, "%lu|%s", strlen(msg)+1, msg);
/* Print result */
printf("%s\n", buffer);
return 0;
}
we all know that to convert a value in a string we can do following
char* buffer = ... allocate a buffer ...
int value = 4564;
sprintf(buffer, "%d", value);
but what can we do if instead of character buffer i want to convert data to integer buffer, basically i want to do following
int* buffer = ... allocate a buffer ...
int value = 4564;
sprintf(buffer, "%d", value);
Thanks in advance
Be sure to define buffer as the value of 'value', and not a pointer to the address of 'value'. See below:
#include <stdlib.h>
#include <stdio.h>
#include <memory.h>
int main(int argc, char** argv)
{
/* Allocate memory. */
int* buffer = malloc(sizeof(int));
int value = 1000;
/* Sets the number stored in buffer equal to value. */
*buffer = value;
/* prints 1000 */
printf("%d\n", *buffer);
/* Change value to show buffer is not pointing to the address of 'value'. */
value = 500;
/* Still prints 1000. If we had used
int* buffer = &value, it would print 500. */
printf("%d\n", *buffer);
return 0;
}
I want to convert an ascii string of 16 bytes into 16 bytes hexadecimal integers. Kindly help. Here is my code:
uint stringToByteArray(char *str,uint **array)
{
uint i, len=strlen(str) >> 1;
*array=(uint *)malloc(len*sizeof(uint));
//Conversion of str (string) into *array (hexadecimal)
return len;
}
If you are looking for printing integer numbers in hexadecimal form, this might help:
#include <stdio.h>
int main() {
/* define ASCII string */
/* note that char is an integer number type */
char s[] = "Hello World";
/* iterate buffer */
char *p;
for (p = s; p != s+sizeof(s); p++) {
/* print each integer in its hex representation */
printf("%02X", (unsigned char)(*p));
}
printf("\n");
return 0;
}
If all you want is to turn a char array to an array of 1-byte integer numbers, then you are already done. char already is an integral number type. You can use the buffer you already have, or use malloc/memcpy to copy the data to a new one.
You might want to have a look at the explicit width integer types defined in stdint.h, e.g., uint8_t for a one byte unsigned integer.
A C-"string" of 16 characters length is 16bytes!
To have it converted to a "byte"-array (of 16 entries lenght) you might like to do the following:
#include <unistd.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
/* Copies all characters of str into a freshly allocated array pointed to by *parray. */
/* Returns the number of characters bytes copied and -1 on error. Sets errno accordingly. */
size_t stringToByteArray(const char * str, uint8_t **parray)
{
if (NULL == str)
{
errno = EINVAL;
return -1;
}
{
size_t size = strlen(str);
*parray = malloc(size * sizeof(**parray));
if (NULL == *parray)
{
errno = ENOMEM;
return -size;
}
for (size_t s = 0; s < size; ++s)
{
(*parray)[s] = str[s];
}
return size;
}
}
int main()
{
char str[] = "this is 16 bytes";
uint8_t * array = NULL;
ssize_t size = stringToByteArray(str, &array);
if (-1 == size)
{
perror("stringToByteArray() failed");
return EXIT_FAILURE;
}
/* Do what you like with array. */
free(array);
return EXIT_SUCCESS;
}
I am using the itoa() function to convert an int into string, but it is giving an error:
undefined reference to `itoa'
collect2: ld returned 1 exit status
What is the reason? Is there some other way to perform this conversion?
Use snprintf, it is more portable than itoa.
itoa is not part of standard C, nor is it part of standard C++; but, a lot of compilers and associated libraries support it.
Example of sprintf
char* buffer = ... allocate a buffer ...
int value = 4564;
sprintf(buffer, "%d", value);
Example of snprintf
char buffer[10];
int value = 234452;
snprintf(buffer, 10, "%d", value);
Both functions are similar to fprintf, but output is written into an array rather than to a stream. The difference between sprintf and snprintf is that snprintf guarantees no buffer overrun by writing up to a maximum number of characters that can be stored in the buffer.
Use snprintf - it is standard an available in every compilator. Query it for the size needed by calling it with NULL, 0 parameters. Allocate one character more for null at the end.
int length = snprintf( NULL, 0, "%d", x );
char* str = malloc( length + 1 );
snprintf( str, length + 1, "%d", x );
...
free(str);
Before I continue, I must warn you that itoa is NOT an ANSI function — it's not a standard C function. You should use sprintf to convert an int into a string.
itoa takes three arguments.
The first one is the integer to be converted.
The second is a pointer to an array of characters - this is where the string is going to be stored. The program may crash if you pass in a char * variable, so you should pass in a normal sized char array and it will work fine.
The last one is NOT the size of the array, but it's the BASE of your number - base 10 is the one you're most likely to use.
The function returns a pointer to its second argument — where it has stored the converted string.
itoa is a very useful function, which is supported by some compilers - it's a shame it isn't support by all, unlike atoi.
If you still want to use itoa, here is how should you use it. Otherwise, you have another option using sprintf (as long as you want base 8, 10 or 16 output):
char str[5];
printf("15 in binary is %s\n", itoa(15, str, 2));
Better use sprintf(),
char stringNum[20];
int num=100;
sprintf(stringNum,"%d",num);
Usually snprintf() is the way to go:
char str[16]; // could be less but i'm too lazy to look for the actual the max length of an integer
snprintf(str, sizeof(str), "%d", your_integer);
You can make your own itoa, with this function:
void my_utoa(int dataIn, char* bffr, int radix){
int temp_dataIn;
temp_dataIn = dataIn;
int stringLen=1;
while ((int)temp_dataIn/radix != 0){
temp_dataIn = (int)temp_dataIn/radix;
stringLen++;
}
//printf("stringLen = %d\n", stringLen);
temp_dataIn = dataIn;
do{
*(bffr+stringLen-1) = (temp_dataIn%radix)+'0';
temp_dataIn = (int) temp_dataIn / radix;
}while(stringLen--);}
and this is example:
char buffer[33];
int main(){
my_utoa(54321, buffer, 10);
printf(buffer);
printf("\n");
my_utoa(13579, buffer, 10);
printf(buffer);
printf("\n");
}
void itos(int value, char* str, size_t size) {
snprintf(str, size, "%d", value);
}
..works with call by reference. Use it like this e.g.:
int someIntToParse;
char resultingString[length(someIntToParse)];
itos(someIntToParse, resultingString, length(someIntToParse));
now resultingString will hold your C-'string'.
char string[something];
sprintf(string, "%d", 42);
Similar implementation to Ahmad Sirojuddin but slightly different semantics. From a security perspective, any time a function writes into a string buffer, the function should really "know" the size of the buffer and refuse to write past the end of it. I would guess its a part of the reason you can't find itoa anymore.
Also, the following implementation avoids performing the module/devide operation twice.
char *u32todec( uint32_t value,
char *buf,
int size)
{
if(size > 1){
int i=size-1, offset, bytes;
buf[i--]='\0';
do{
buf[i--]=(value % 10)+'0';
value = value/10;
}while((value > 0) && (i>=0));
offset=i+1;
if(offset > 0){
bytes=size-i-1;
for(i=0;i<bytes;i++)
buf[i]=buf[i+offset];
}
return buf;
}else
return NULL;
}
The following code both tests the above code and demonstrates its correctness:
int main(void)
{
uint64_t acc;
uint32_t inc;
char buf[16];
size_t bufsize;
for(acc=0, inc=7; acc<0x100000000; acc+=inc){
printf("%u: ", (uint32_t)acc);
for(bufsize=17; bufsize>0; bufsize/=2){
if(NULL != u32todec((uint32_t)acc, buf, bufsize))
printf("%s ", buf);
}
printf("\n");
if(acc/inc > 9)
inc*=7;
}
return 0;
}
Like Edwin suggested, use snprintf:
#include <stdio.h>
int main(int argc, const char *argv[])
{
int n = 1234;
char buf[10];
snprintf(buf, 10, "%d", n);
printf("%s\n", buf);
return 0;
}
If you really want to use itoa, you need to include the standard library header.
#include <stdlib.h>
I also believe that if you're on Windows (using MSVC), then itoa is actually _itoa.
See http://msdn.microsoft.com/en-us/library/yakksftt(v=VS.100).aspx
Then again, since you're getting a message from collect2, you're likely running GCC on *nix.
see this example
#include <stdlib.h> // for itoa() call
#include <stdio.h>
int main() {
int num = 145;
char buf[5];
// convert 123 to string [buf]
itoa(num, buf, 10);
// print our string
printf("%s\n", buf);
return 0;
}
see this link having other examples.
itoa() function is not defined in ANSI-C, so not implemented by default for some platforms (Reference Link).
s(n)printf() functions are easiest replacement of itoa(). However itoa (integer to ascii) function can be used as a better overall solution of integer to ascii conversion problem.
itoa() is also better than s(n)printf() as performance depending on the implementation. A reduced itoa (support only 10 radix) implementation as an example: Reference Link
Another complete itoa() implementation is below (Reference Link):
#include <stdbool.h>
#include <string.h>
// A utility function to reverse a string
char *reverse(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;
}
// Implementation of itoa()
char* itoa(int num, char* str, int base)
{
int i = 0;
bool isNegative = false;
/* Handle 0 explicitely, otherwise empty string is printed for 0 */
if (num == 0)
{
str[i++] = '0';
str[i] = '\0';
return str;
}
// In standard itoa(), negative numbers are handled only with
// base 10. Otherwise numbers are considered unsigned.
if (num < 0 && base == 10)
{
isNegative = true;
num = -num;
}
// Process individual digits
while (num != 0)
{
int rem = num % base;
str[i++] = (rem > 9)? (rem-10) + 'a' : rem + '0';
num = num/base;
}
// If number is negative, append '-'
if (isNegative)
str[i++] = '-';
str[i] = '\0'; // Append string terminator
// Reverse the string
reverse(str);
return str;
}
Another complete itoa() implementatiton: Reference Link
An itoa() usage example below (Reference Link):
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
int a=54325;
char buffer[20];
itoa(a,buffer,2); // here 2 means binary
printf("Binary value = %s\n", buffer);
itoa(a,buffer,10); // here 10 means decimal
printf("Decimal value = %s\n", buffer);
itoa(a,buffer,16); // here 16 means Hexadecimal
printf("Hexadecimal value = %s\n", buffer);
return 0;
}
if(InNumber == 0)
{
return TEXT("0");
}
const int32 CharsBufferSize = 64; // enought for int128 type
TCHAR ResultChars[CharsBufferSize];
int32 Number = InNumber;
// Defines Decreasing/Ascending ten-Digits to determine each digit in negative and positive numbers.
const TCHAR* DigitalChars = TEXT("9876543210123456789");
constexpr int32 ZeroCharIndex = 9; // Position of the ZERO character from the DigitalChars.
constexpr int32 Base = 10; // base system of the number.
// Convert each digit of the number to a digital char from the top down.
int32 CharIndex = CharsBufferSize - 1;
for(; Number != 0 && CharIndex > INDEX_NONE; --CharIndex)
{
const int32 CharToInsert = ZeroCharIndex + (Number % Base);
ResultChars[CharIndex] = DigitalChars[CharToInsert];
Number /= Base;
}
// Insert sign if is negative number to left of the digital chars.
if(InNumber < 0 && CharIndex > INDEX_NONE)
{
ResultChars[CharIndex] = L'-';
}
else
{
// return to the first digital char if is unsigned number.
++CharIndex;
}
// Get number of the converted chars and construct string to return.
const int32 ResultSize = CharsBufferSize - CharIndex;
return TString{&ResultChars[CharIndex], ResultSize};
i have an array (char data[16]) and i want to get data from user in hex digits so the array looks like :
data[0]=0x887f76b1
data[1]=0x8226baac
...
when the user input was : 887f76b18226baac ...
thank you very very much.
Basically, you will want to read the first 8 characters of the string and convert them to a decimal format. There are utilities available for doing this. For example:
const char * data = "887f76b18226baac";
char buff[9] = {0};
unsigned long x = 0, y = 0;
sscanf(data, "%8s", buff);
x = strtoul(buff, NULL, 16);
sscanf(data + 8, "%8s", buff);
y = strtoul(buff, NULL, 16);
Realize that I elided all of the error checking there. Both sscanf and strtoul return error values (or provide mechanisms for checking for error). In cases where you are converting values it is wise to check for these error cases.
Edit: As mentioned in the comments, you will not be able to store these values in a char array. You will want to have an array of the proper data type (for my example you would use unsigned long array[16])
I think you want something along the lines of the following:
#include <stdio.h>
#include <string.h>
#define MAX_BUFFER 1024
int main(int argc, char **argv)
{
char *input = "887f76b18226baac";
unsigned char data[MAX_BUFFER];
char tmp[3]; /* sue me for using magic numbers :) */
int i = 0, offset = 0;
memset(data, 0, sizeof(data));
while(sscanf(input + offset, "%2s", tmp) != EOF && i < MAX_BUFFER) {
data[i++] = strtoul(tmp, NULL, 16);
offset += 2;
}
return(0);
}
I'm assuming here that you absolutely need to store your input on a character array. If you wish to fit 0x887f76b1 into one array element, you'll need to use unsigned long, as ezpz suggested.