itoa providing 7-bit output to character input - c

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.

Related

How to check whether a hexadecimal number(%x) starts with a certain number or not in C?

I'm working on an operating system related project now and there is one step which requires to check whether a hexadecimal number starts with 3 or not, using C.
Currently my idea is to convert that hexadecimal number into a string and check the initial character but just cannot find out any documentation for doing that. Anybody has any idea? Maybe just a hint.
There are lots of methods to convert a number to a hex string (sprintf comes to mind; How can I convert an integer to a hexadecimal string in C? list a few more) – but, why should you?
A full hex number is formed by converting each nibble (4 bits) to a hexadecimal 'digit'. To get just the first, you can divide your value by 16 until you have reached the final (= 'first', in the left-to-right notation common for both decimal and hexadecimal values) digit. If that's a 3 you are done.
Assuming value is an unsigned number:
while (value > 15)
value >>= 4;
and then check if value == 3.
Your idea is not bad, you can use sprintf, it functions like printf/fprintf but instead of printing
on screen (or to be more precise: writing into a FILE* buffer), it stores the contents in a char buffer.
char value[16]; // more than enough space for 4 byte values
int reg = 0x3eef;
sprintf(value, "%x", reg);
if(value[0] == '3')
printf("The hexadecimal number 0x%s starts with a 3.\n", value);

uint64 to string in 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).

K&R 1-7 is it solvable by using putchar() instead of printf?

There are many questions about this exercise all over the internet, but I couldn't find any solution (nor any hint) on how to solve this exercise using 'putchar'.
Write a program to print the value of EOF.
I can easily get a working answer to this:
printf("%d", EOF);
I'd like to know if there are any known (or logical) answers using 'putchar' (as I guess that was the whole purpose of the exercise, being located at the end of a paragraph on 'getchar' and 'putchar')
Writing:
putchar(EOF);
or
int c;
c = EOF;
putchar(c);
the program just launches and closes itself without showing any text.
putchar converts its argument to unsigned char before it's outputted (and it's a character which is written, not the result of a decimal conversion). As EOF is negative, this conversion isn't value-preserving. Commonly, EOF has the value -1, with 8-bit char, that conversion results in 255, that is, putchar(EOF) is equivalent to putchar('\xff'), which isn't a printable character (assuming an ASCII system). Piping the output to hexdump -C would make the output visible.
Without using printf and friends, a function outputting a decimal number for an int can be written. Basically,
print a '-' if the value is negative
for every decimal digit, starting from the highest-valued:
convert the digit's value to a character (e.g. 7 should become '7')
try to print the result (with putchar, for example)
if that fails, return an error indicator
Hint: The division and modulus operators, / and %, will be useful.
The digits '0' ... '9' are ascending (and contiguous); so for the conversion from the digit's value to a character, adding '0' yields the desired result (3 + '0' is '3', for example).
Care must be taken to avoid integer overflow, even if corner cases like INT_MIN are passed to the function. -INT_MIN may result in an overflow (and in fact does on pretty much every system), a positive number, on the other hand, can always be negated. A value of 0 may need special handling.
(Alternatively, the number can be converted to a string first which then can be outputted. A char array of size 1 + sizeof(int)*CHAR_BIT/3+1 + 1 is big enough to hold that string, including minus sign and 0-terminator.)
If you get stuck, the (non-standard) itoa function does something similar, looking for example implementations may give some ideas.
EOF is not a char which can be printed as you expected. So putchar(EOF) doesn't print any values, as it prints only char.
Hence use printf("%d", EOF) which outputs integer -1.
putchar(int char) So if you pass a ASCII value to this API you get a corresponding character printed on the screen but EOF evaluates to -1 which is not a printable ASCII character so you don't see anything or might see some junk.
As per the man page of putchar(),
int putchar(int c);
putchar(c); is equivalent to putc(c,stdout).
and
putc() is equivalent to fputc() .......fputc() writes the character c, cast to an unsigned char, to stream.
This, putchar() is supposed to output the char representation of the ASCII value supplied as it's argument.
So, if the value of EOF is a non printable character [in ASCII], you won't see anything ["without showing any text"] on stdout.

Difference between binary zeros and ASCII character zero

gcc (GCC) 4.8.1
c89
Hello,
I was reading a book about pointers. And using this code as a sample:
memset(buffer, 0, sizeof buffer);
Will fill the buffer will binary zero and not the character zero.
I am just wondering what is the difference between the binary and the character zero. I thought it was the same thing.
I know that textual data is human readable characters and binary data is non-printable characters. Correct me if I am wrong.
What would be a good example of binary data?
For added example, if you are dealing with strings (textual data) you should use fprintf. And if you are using binary data you should use fwrite. If you want to write data to a file.
Many thanks for any suggestions,
The quick answer is that the character '0' is represented in binary data by the ASCII number 48. That means, when you want the character '0', the file actually has these bits in it: 00110000. Similarly, the printable character '1' has a decimal value of 49, and is represented by the byte 00110001. ('A' is 65, and is represented as 01000001, while 'a' is 97, and is represented as 01100001.)
If you want the null terminator at the end of the string, '\0', that actually has a 0 decimal value, and so would be a byte of all zeroes: 00000000. This is truly a 0 value. To the compiler, there is no difference between
memset(buffer, 0, sizeof buffer);
and
memset(buffer, '\0', sizeof buffer);
The only difference is a semantic one to us. '\0' tells us that we're dealing with a character, while 0 simply tells us we're dealing with a number.
It would help you tremendously to check out an ascii table.
fprintf outputs data using ASCII and outputs strings. fwrite writes pure binary data. If you fprintf(fp, "0"), it will put the value 48 in fp, while if you fwrite(fd, 0) it will put the actual value of 0 in the file. (Note, my usage of fprintf and fwrite were obviously not proper usage, but shows the point.)
Note: My answer refers to ASCII because it's one of the oldest, best known character sets, but as Eric Postpichil mentions in the comments, the C standard isn't bound to ASCII. (In fact, while it does occasionally give examples using ASCII, the standard seems to go out of its way to never assume that ASCII will be the character set used.). fprintf outputs using the execution character set of your compiled program.
If you are asking about the difference between '0' and 0, these two are completely different:
Binary zero corresponds to a non-printable character \0 (also called the null character), with the code of zero. This character serves as null terminator in C string:
5.2.1.2 A byte with all bits set to 0, called the null character, shall exist in the basic execution character set; it is used to terminate a character string.
ASCII character zero '0' is printable (not surprisingly, producing a character zero when printed) and has a decimal code of 48.
Binary zero: 0
Character zero: '0', which in ASCII is 48.
binary data: the raw data that the cpu gets to play with, bit after bit, the stream of 0s and 1s (usually organized in groups of 8, aka Bytes, or multiples of 8)
character data: bytes interpreted as characters. Conventions like ASCII give the rules how a specific bit sequence should be displayed by a terminal, a printer, ...
for example, the binary data (bit sequence ) 00110000 should be displayed as 0
if I remember correctly, the unsigned integer datatypes would have a direct match between the binary value of the stored bits and the interpreted value (ignore strangeness like Endian ^^).
On a higher level, for example talking about ftp transfer, the destinction is made between:
the data should be interpreted as (multi)byte characters, aka text (this includes non-character signs like a line break)
the data is a big bit/bytestream, that can't be broken down in smaller human readable bits, for example an image or a compiled executable
in system every character have a code and zero ASCII code is 0x30(hex).
to fill this buffer with zero character you must enter this code :
memset(buffer,30,(size of buffer))

C Compatibility Between Integers and Characters

How does C handle converting between integers and characters? Say you've declared an integer variable and ask the user for a number but they input a string instead. What would happen?
The user input is treated as a string that needs to be converted to an int using atoi or another conversion function. Atoi will return 0 if the string cannot be interptreted as a number because it contains letters or other non-numeric characters.
You can read a bit more at the atoi documentation on MSDN - http://msdn.microsoft.com/en-us/library/yd5xkb5c(VS.80).aspx
Uh?
You always input a string. Then you parse convert this string to number, with various ways (asking again, taking a default value, etc.) of handling various errors (overflow, incorrect chars, etc.).
Another thing to note is that in C, characters and integers are "compatible" to some degree. Any character can be assigned to an int. The reverse also works, but you'll lose information if the integer value doesn't fit into a char.
char foo = 'a'; // The ascii value representation for lower-case 'a' is 97
int bar = foo; // bar now contains the value 97
bar = 255; // 255 is 0x000000ff in hexadecimal
foo = bar; // foo now contains -1 (0xff)
unsigned char foo2 = foo; // foo now contains 255 (0xff)
As other people have noted, the data is normally entered as a string -- the only question is which function is used for doing the reading. If you're using a GUI, the function may already deal with conversion to integer and reporting errors and so in an appropriate manner. If you're working with Standard C, it is generally easier to read the value into a string (perhaps with fgets() and then convert. Although atoi() can be used, it is seldom the best choice; the trouble is determining whether the conversion succeeded (and produced zero because the user entered a legitimate representation of zero) or not.
Generally, use strtol() or one of its relatives (strtoul(), strtoll(), strtoull()); for converting floating point numbers, use strtod() or a similar function. The advantage of the integer conversion routines include:
optional base selection (for example, base 10, or base 10 - hex, or base 8 - octal, or any of the above using standard C conventions (007 for octal, 0x07 for hex, 7 for decimal).
optional error detection (by knowing where the conversion stopped).
The place I go for many of these function specifications (when I don't look at my copy of the actual C standard) is the POSIX web site (which includes C99 functions). It is Unix-centric rather than Windows-centric.
The program would crash, you need to call atoi function.

Resources