I have to write a byte in hex to a file but I have a problem. For example.
If I have:
unsigned char a = 0x0;
and I write to a file using fwrite:
FILE *fp = fopen("file.txt",wb);
fwrite(&a,sizeof(unsigned char),1,fp);
fclose(fp);
When I open file I always see 20h, why not 00h?
So, I try to use:
fprintf(fp,"%x",a);
In this case I see 0h, but I need a full byte, not a nibble.
What should I do?
The first example is hard to believe, it ought to generate a file with a single byte with the value 0 in it. That's not really a text file though, so I guess your tools might fool you.
The second attempt is better, assuming you want a text file with a text representation of the value in it. To make it two hexadecimal digits, specify a width and padding:
fprintf(fp, "%02x", a);
Please note that there is no such thing as "a hex value". A value is a value; it can be represented as hex, but that's not part of the value. 100 decimal is the same thing as 64 in hex, and 1100100 in binary. The base only matters when representing the number as a string of digits, the number itself can't "be hex".
Related
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);
I have been searching for this similar issue on internet but haven't found any good solution. I am in ubuntu and I am receiving serial hex data on serial port. I have connected my system using null modem cable to windows system and windows system is running docklight software which is sending hex data like below:
2E FF AA 4F CC 0D
Now by saving the data, I do not mean that I want to print data on terminal. I just want to save this data as it is in a buffer so that I an later process it.
To read the data I am doing
res = read (fd, buf, sizeof buf)
//where buf is
unsigned char buf[255];
At this point after reading, buf contains some random chars. From some links on internet, I got a way to convert it into hex:
unsinged char hexData[255];
for (int i = 0; i < res; i++)
{
sprintf((char*)hexData+i*2, "%02X", buf[i]);
}
Now this hexData contains 2EFFAA4FCC0D, which is ok for my purpose. (I do not know if it is the right way of doing it or not). Now lets say I want to convert E from the hexData into decimal. But at this point, E will be considered as character not a hex so may be I'll get 69 instead of 14.
How can I save hex data in a variable. Should I save it as array of chars or int. Thanks.
You already have data in binary form in buf
But if you still need to convert hex to decimal, you can use sscanf
sscanf(&hexBuf[i],"%02X",&intVar);// intVar is integer variable
It wll convert hex byte formed by hexBuf[i] and hexBuf[i+1] to binary in intVar, When you printf intVar with %d you will get to see the decimal value
You can store intVar as element of unsigned character array
You may want to think about what you're trying to achieve.
Hexadecimal is just a representation. The byte you are receiving could be shown as hexadecimal pairs, as binary octet or as a series of (more or less) printable characters (what you see if you print your unsigned char array).
If what you need is storing only the hexadecimal representation of those bytes, convert them to hexadecimal as you are doing, but remember you'll need an array twice as big as your buffer (since a single byte will be represented by two hexadecimal characters once you convert it).
Usually, the best thing to do is to keep them as an array of bytes (chars), that is, your buf array, and only convert them when you need to show the hexadecimal representation.
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.
I have a C program that writes to a file using fwrite(..) and the result is not consistent with the function's arguments I provide.
uint32_t x = 1009716161;
FILE * file = fopen("helloop.txt", "wb+");
rewind(file);
fwrite( &x, sizeof(uint32_t), 1, file);
fclose(file);
When I check the file afterward it seems to contains symbols that does not translate into anything
>cat helloop.txt
>Á/<
as I should be getting this
>cat helloop.txt
>000000003C2F0BC1
I checked the file's permissions and I chmodded it
chmod 777 helloop.txt
The way I see it I have a 1 element of size 32 bit integer that I want to write to file,
what am I doing wrong ?
Your program did exactly what you told it to.
In general, if a program you've written seems to be misbehaving, you shouldn't jump to the conclusion that the operating system, the compiler, or the runtime library is at fault. It's far more likely that there's a bug in your program, or that you've misunderstood something. That remains true no matter how many years of experience you have.
The value 1009716161, expressed in hexadecimal, is 0x3c2f0bc1. When you write that value to a binary file, you write 4 8-bit bytes, with values 0x3c, 0x2f, 0x0b, and 0xc1. In ASCII, those are '<', '/', and two characters outside the printable ASCII range. The order in which they're written depends on the endianness your system, but the contents you report seem consistent with that.
I"m not sure why you'd expect to see 000000003C2F0BC1. That's 16 byte when you only wrote 4 bytes to the file. Furthermore, binary files do not contain an ASCII rendering of the hexadecimal representation of the data you wrote -- they just contain the data.
If you examine the file by converting it from raw binary to hexadecimal (by using the hexdump or od -x command if your system has it), you should see something recognizable.
And if you open the file in binary mode and use fread to read the data back into a uint32_t object, you should get the original value 1009716161 back -- which is the whole point.
cat helloop.txt
Á/<
cat prints character data. It doesn't print a 4-byte value in a file as a 32-bit integer.
as I should be getting this
cat helloop.txt
000000003C2F0BC1
No you shouldn't, not with cat. You'd have to write the character string "000000003C2F0BC1" to the file if you expect to get that. The file would probably be 16 characters long. I'd bet right now if you run ls -l helloop.txt you'll see size 4 because you wrote a uint32_t binary integer to the file.
what am I doing wrong ?
As far as I can tell, the only thing you've done wrong is expecting cat to print out your uint32_t as a hexadecimal representation. (Though I did not check your hex value, so that may be incorrect as well)
See if you have hexdump on your Linux machine, it may give you better results.
EDIT: If you actually DO want to print a uint32_t as a hex string, you can use fprintf(..., "%x", x) with the x or X format specifier, but keep in mind this is not compatible with fwrite/fread, so to read it back in you'll have to read in the string and convert back from hex to int.
I want to ask few questions about bits and bytes as I am very confused.
For example, suppose I have a short int x = 345;. I know that short take 16 bits, so when I write the short in a file it is written as char '3' , '4' ,'5' each containing 1 bytes so total of 24 bits.
Is there a way to write the number (short integer) in file as short integer taking 16 bits?
Also am I right in my concept? What will be the difference in writing to my file if the file is binary or text in terms of bytes?
Yes, there is a way.
uint16_t sh = 345;
fwrite(&sh, sizeof(sh), 1, fp);
In the case you mentioned 345 is written as text (for example ASCII if that's what you use). In the example I posted, the binary representation of sh is written in the file and it will take only 2 bytes.
What will be the difference in writing to my file if the file is
binary or text in terms of bytes?
Text write (fprintf)
0000000: 00110011 00110100 00110101
3 4 5
Binary write (fwrite)
0000000: 01011001 00000001
#Little endian. Read as: 00000001 01011001 = 345
If interoperabillity is an issue (i.e. you want to send the file to another machine) the text format is a superior choice as it's portable.
If you write the value as a string, it will occupy at least three bytes for the three digits; there would often be a newline or space as well to mark the end of the value.
Yes, you can write the value as 2 bytes. One way would be:
fwrite(&x, sizeof(x), 1, fp);
The difference between binary and text is that you can transport the text between different types of machine with almost complete impunity and all the machines will interpret the data the same way. The binary file can only be interpreted on machines that have the same endian-ness (big-endian or non-Intel vs little-endian or Intel). On the other class of machines, you have to swap the order of the bytes to get the binary data interpreted correctly.