uint64 to string in C - c

I have a uint64 value that I want to convert into a string because it has to be inserted as the payload of an HTTP POST request.
I've already tried many solutions (ltoa, this solution ) but my problem still remains.
My function is the following:
void check2(char* fingerprint, guint64 s_id) {
//stuff
char poststr[400] = "action=CheckFingerprint&sessionid=";
//convert s_id to, for example, char* myChar
strcat(poststr, myChar);
}
I want to convert s_id to char*. I've tried:
1) char ses[8]; ltoa(s_id,ses,10) but I have a segmentation fault;
2) char *buf; sprintf(buf, "%" PRIu64, s_id);
I'm working on a APIs, so I have seen that when this guint64 variable is printed, it has the following form:
JANUS_LOG(LOG_INFO, "Creating new session: %"SCNu64"\n", session_id);

sprintf is the right way to go with an unsigned 64 bit format specifier.
You'll need to allocate enough space for 16 hex digits and the null byte. Here I've allocated 20 bytes to accommodate a leading 0x as well and then I rounded it up to 20 for no good reason other than it feels better than 19.
char foo[20];
sprintf(foo, "0x%016" PRIx64, (uint64_t)numberToConvert);
will print the number in hex with leading 0x and leading zeros padded up to 16. You do not need the cast if numberToConvert is already a uint64_t

i have a uint64 value that i want to convert into char* because of it have to be inserted as payload of an HTTP POST request.
What you have is a fundamental misunderstanding.
To insert a text representation of your value into a document, you need to convert it to a sequence of characters, which is quite a different thing from a pointer to a character (char *). One of your options, which seems to be what you're really after, is to convert the value to a sequence of characters in the form of a C string -- that is, a null-terminated array of characters. You would then have or be able to obtain a pointer to the first character in the sequence.
That explains what's wrong with this attempted solution:
char *buf;
sprintf(buf, "%" PRIu64, s_id);
You are trying to write the string representation of your number into the array pointed-to by buf, but it doesn't point to one. Not having been initialized or assigned, its value is indeterminate.
Even if you your buf pointed to an array, it is essential that the array be long enough to accommodate all the digits of the value's decimal representation, plus a terminator. That's probably what's wrong with your other attempt:
char ses[8]; ltoa(s_id,ses,10)
An unsigned, 64-bit binary number may require up to 20 decimal digits, plus you need space for a terminator. The array you're providing is not nearly large enough, unless you can be confident that the actual values you're going to write will not exceed 9,999,999 (which is well within the range of a 32-bit integer).

Related

directly cast a char *nib as int hex

in pure and portable c.
So I am having trouble casting what has to be a variable, from a variable. char *nib to int hex. The idea being I had a char *nib ="ab"; or "0xab" or anything that directly represents two characters as a char *. then casting it as a integer. and writing it to a file to get a one to one write. so I start with char *nib="0xab"; then I write it as a int presumably, and to a hexdump or edit and the result is just ab.
I've been able to do this as a constant directly declaring... but the nib is always static.
this has to be a one to one starting with a two char string or nib. Not converting anything, purly casting.
So can you write it directly to a file without converting it? three look up tables seems like a bit much for a value what has the name length
There is no way to cast 2 characters (2 bytes) into one byte because cast does not change binary representation of the value.
The closest you can get to casting string that looks like hex to some value that will show something similar is use 0-15 characters via escape sequence like char* nib = "\x0A\x0B" and cast ( *((short*)nib)) that to 2-byte value (0x0A0B in this case) and store that to a file (I'm not sure if there is portable integer type of 2 bytes - short often is 2 bytes wide but does not have to be 2 bytes). Unfortunately I don't think there is a portable way to store 2 byte integer value to a file as different architectures may have different byte order.
Writing string value character by character is likely safest approach. Or convert string to int a usual way and use your own read/write code for integers to ensure portability.

itoa providing 7-bit output to character input

I am trying to convert a character to its binary using inbuilt library (itoa) in C(gcc v-5.1) using example from Conversion of Char to Binary in C , but i'm getting a 7-bit output for a character input to itoa function.But since a character in C is essentially an 8-bit integer, i should get an 8-bit output.Can anyone explain why is it so??
code performing binary conversion:
enter for (temp=pt;*temp;temp++)
{
itoa(*temp,opt,2); //convert to binary
printf("%s \n",opt);
strcat(s1,opt); //add to encrypted text
}
PS:- This is my first question in stackoverflow.com, so sorry for any mistakes in advance.
You could use printf( "%2X\n", *opt ); to print a 8-bit value as 2 hexadecimal symbols.
It would print the first char of opt. Then, you must increment the pointer to the next char with opt++;.
The X means you want it to be printed as uppercase hexadecimal characters (use x for lowercase) and the 2 will make sure it will print 2 symbols even if opt is lesser than 0x10.
In other words, the value 0xF will be printed 0x0F... (actually 0F, you could use printf( "%#2X\n", *opt ); to print the 0x).
If you absolutely want a binary value you have to make a function that will print the right 0 and 1. There are many of them on the internet. If you want to make yours, reading about bitwise operations could help you (you have to know about bitwise operations if you want to work with binaries anyways).
Now that you can print it as desired (hex as above or with your own binary function), you can redirect the output of printf with the sprintf function.
Its prototype is int sprintf( char* str, const char* format, ... ). str is the destination.
In your case, you will just need to replace the strcat line with something like sprintf( s1, "%2X\n", *opt); or sprintf( s1, "%s\n", your_binary_conversion_function(opt) );.
Note that using the former, you would have to increment s1 by 2 for each char in opt because one 8-bit value is 2 hexadecimal symbols.
You might also have to manage s1's memory by yourself, if it was not the case before.
Sources :
MK27's second answer
sprintf prototype
The function itoa takes an int argument for the value to be converted. If you pass it a value of char type it will be promoted to int. So how would the function know how many leading zeros you were expecting? And then if you had asked for radix 10 how many leading zeros would you expect? Actually, it suppresses leading zeros.
See ASCII Table, note the hex column and that for the ASCII characters the msb is 0. Printable ASCII characters range from 0x20 thru 0x7f. Unicode shares the characters 0x00 thru 0x7f.
Hex 20 thru 7f are binary 00100000 thru 01111111.
Not all binary values are printable characters and in some encodings are not legal values.
ASCII, hexadecimal, octal and binary are just ways of representing binary values. Printable characters are another way but not all binary values can be displayed, this is the main data that needs to be displayed or treated as character text is generally converted to hex-ascii or Base64.

Separated integers with comma delimiters and sscanf

I need help with sscanf.
I have a data file. I read it line by line.
One line is look like this: 23,13,45;
I want to read the integers.
I try this code:
unsigned char a,b,c;
sscanf(line,"%d,%d,%d;",&a,&b,&c);
But this is not working, only the first number read, the others is 0.
This is because %d expects a pointer to a 4-byte integer, and you are passing a pointer to a 1-byte char. Because variables a, b and c are stored in the order of decreasing memory addresses, sscanf first fills a with 23, at the same time filling 3 other bytes of stack memory with zeros (this is a memory violation, BTW). Then it fills b with 13, also filling a and two other bytes with zeros. In the end it fills c with 45, also filling a and b and one other byte with zeros. This way you end up with zeros in both b and a, and an expected value only in c.
Of course this is only one possible scenario of what can happen, as it depends on the architecture and compiler.
A proper way to read 4 integers would be to use int instead of unsigned char, or change the format specifier.
Correct format specifier for unsigned char is %hhu.
Other than that I don't see any problem as long as line does contain the string in the format you expect.

How to convert "\003" to int in C

How to convert "\003" to int in C? I have following code.
void* message="\003";
char* bptr;
printf("%ld",strtol((char*)message,&bptr,10));
It is showing 0 as output.
The string literal "\003" specifies a string consisting of two characters; the first has the value 3, and the second is the implicit '\0' null character terminator.
The character with the value 3 is typically not a printable character. In particular, it's not the digit '3'.
If you want to extract the int value 3 from that string, you can do it like this:
int result = ((char*)message)[0];
But that doesn't seem like a particularly useful thing to do.
I have to wonder (1) why you declared message as void* rather than as char*, and (2) why you're using a string containing the control character '\003' to represent the integer value 3.
The usual way to represent an integer value as a string represents the integer 3 as "3", not as '\003'. You can certainly represent (small) integer values as single bytes, but that would generally use a single char or unsigned char object, not a string or array. Finally, there are ways to represent arbitrary numbers as sequences of bytes, but if you're doing that you haven't told us the details of your representation; for example, what string would represent the integer value 1000?

Printing hex integer by casting to char* and using "%s" in sprintf

I'm reading in two 32 bit registers and trying to put it inside a string buffer using the following:
sprintf (buffer, "%s-%s", ((char*)(in32(REGISTER1))) , (char*)(in32(REGISTER2)));
Can the hex value read in from the registers not be typecast as a pointer to a char and be printed into the buffer as above?
As craig65535 implies in a comment above, the problem is most likely with this phrase:
the hex value read in from the registers
I doubt that you're reading in a hex value; rather, you're reading in an integer. If you want to store a hex representation of that integer in a string, you'd use the %X format specifier:
sprintf (buffer, "%08X-%08X", in32(REGISTER1), in32(REGISTER2));
(The 8 means "use a width of eight characters"; the 0 means "left-pad with zeroes if the value is such that the width is less than eight".)
The only way you could validly cast to char * is if the integer value in the register is actually a pointer to some memory location where you've stored a string; but that is clearly not the case here.
sprintf(buffer, "%08x-%08x", REGISTER1, REGISTER2);
-- that's assuming you want the register addresses in your buffer. If your intention is to read the contents of the registers, adjust accordingly. The point though is you cannot simply call a number a char* and get the number out of it, but sprintf() (and all printf-like functions) can convert value bases for you.
As the others answers suggest, you can convert your integer to a string hex representation with sprintf using %X.
But as you didn't said what compiler you use or what the length of integer or long is, you could get unexpected results.
On a 16bit controller sprintf (buffer, "%08X-%08X", in32(REGISTER1),in32(REGISTER2)); would fail.
This should work on the most plattforms, as sprintf assume long values as arguments, and the arguments are always casted to longs.
sprintf (buffer, "%08lX-%08lX", (long)in32(REGISTER1), (long)in32(REGISTER2));

Resources