This question already has answers here:
How can I convert an integer to a hexadecimal string in C?
(7 answers)
Closed 11 days ago.
How to print numbers in HEX with printf in C?
static void ReadReg_SI5338(uint8_t *pBuffer)
{
uint8_t ret;
ret = HAL_I2C_Master_Transmit(&hi2c2, SI5338_ADDR, pBuffer, 1, 5);
if ( ret != HAL_OK )
{
printf("Error Tx\r\n");
}
else
{
ret = HAL_I2C_Master_Receive(&hi2c2, SI5338_ADDR, pBuffer, 1, 5);
if ( ret != HAL_OK )
{
printf("Error Rx\r\n");
}
else
{
printf(pBuffer[0], "\r\n");
}
}
}
The code works, it reads correct values, but prints garbage in terminal. I'd like to have it in format "0x38", "0x01", etc. But i don't know how to do it.
To print numbers in hex in C, use:
printf("%#04x", number);
#: means include a 0x before the number
04: mean padd the number with 2 zeros (aka if the number is 1, it will print 0x01 instead of 0x1, 4 cuz 2 for 0x)
x: hex specifier
printf("%#02x\r\n", pBuffer[0])
For some reason it don't prints anything without \r\n.
Related
What I need to do is to read binary inputs from a file. The inputs are for example (binary dump),
00000000 00001010 00000100 00000001 10000101 00000001 00101100 00001000 00111000 00000011 10010011 00000101
What I did is,
char* filename = vargs[1];
BYTE buffer;
FILE *file_ptr = fopen(filename,"rb");
fseek(file_ptr, 0, SEEK_END);
size_t file_length = ftell(file_ptr);
rewind(file_ptr);
for (int i = 0; i < file_length; i++)
{
fread(&buffer, 1, 1, file_ptr); // read 1 byte
printf("%d ", (int)buffer);
}
But the problem here is that, I need to divide those binary inputs in some ways so that I can use it as a command (e.g. 101 in the input is to add two numbers)
But when I run the program with the code I wrote, this provides me an output like:
0 0 10 4 1 133 1 44 8 56 3 147 6
which shows in ASCII numbers.
How can I read the inputs as binary numbers, not ASCII numbers?
The inputs should be used in this way:
0 # Padding for the whole file!
0000|0000 # Function 0 with 0 arguments
00000101|00|000|01|000 # MOVE the value 5 to register 0 (000 is MOV function)
00000011|00|001|01|000 # MOVE the value 3 to register 1
000|01|001|01|100 # ADD registers 0 and 1 (100 is ADD function)
000|01|0000011|10|000 # MOVE register 0 to 0x03
0000011|10|010 # POP the value at 0x03
011 # Return from the function
00000110 # 6 instructions in this function
I am trying to implement some sort of like assembly language commands
Can someone please help me out with this problem?
Thanks!
You need to understand the difference between data and its representation. You are correctly reading the data in binary. When you print the data, printf() gives the decimal representation of the binary data. Note that 00001010 in binary is the same as 10 in decimal and 00000100 in binary is 4 in decimal. If you convert each sequence of bits into its decimal value, you will see that the output is exactly correct. You seem to be confusing the representation of the data as it is output with how the data is read and stored in memory. These are two different and distinct things.
The next step to solve your problem is to learn about bitwise operators: |, &, ~, >>, and <<. Then use the appropriate combination of operators to extract the data you need from the stream of bits.
The format you use is not divisible by a byte, so you need to read your bits into a circular buffer and parse it with a state machine.
Read "in binary" or "in text" is quite the same thing, the only thing that change is your interpretation of the data. In your exemple you are reading a byte, and you are printing the decimal value of that byte. But you want to print the bit of that char, to do that you just need to use binary operator of C.
For example:
#include <stdio.h>
#include <stdbool.h>
#include <string.h>
#include <limits.h>
struct binary_circle_buffer {
size_t i;
unsigned char buffer;
};
bool read_bit(struct binary_circle_buffer *bcn, FILE *file, bool *bit) {
if (bcn->i == CHAR_BIT) {
size_t ret = fread(&bcn->buffer, sizeof bcn->buffer, 1, file);
if (!ret) {
return false;
}
bcn->i = 0;
}
*bit = bcn->buffer & ((unsigned char)1 << bcn->i++); // maybe wrong order you should test yourself
// *bit = bcn->buffer & (((unsigned char)UCHAR_MAX / 2 + 1) >> bcn->i++);
return true;
}
int main(void)
{
struct binary_circle_buffer bcn = { .i = CHAR_BIT };
FILE *file = stdin; // replace by your file
bool bit;
size_t i = 0;
while (read_bit(&bcn, file, &bit)) {
// here you must code your state machine to parse instruction gl & hf
printf(bit ? "1" : "0");
if (++i >= 7) {
i = 0;
printf(" ");
}
}
}
Help you more would be difficult, you are basically asking help to code a virtual machine...
This question already has answers here:
Extra leading zeros when printing float using printf?
(2 answers)
Closed 5 years ago.
I am trying recreate a sample LC-3 simulator as an assignment, and part of that is to have a 4 digit integer. My code is as follows:
while (read_success != NULL && !done) {
// If the line of input begins with an integer, treat
// it as the memory value to read in. Ignore junk
// after the number and ignore blank lines and lines
// that don't begin with a number.
//
words_read = sscanf(buffer, "%04d", &value_read);
// if an integer was actually read in, then
// set memory value at current location to
// value_read and increment location. Exceptions: If
// loc is out of range, complain and quit the loop. If
// value_read is outside -9999...9999, then it's a
// sentinel -- we should say so and quit the loop.
if (value_read < -9999 || value_read > 9999)
{
printf("Sentinel read in place of Memory location %d: quitting loop\n", loc);
break;
}
else if (value_read >= -9999 && value_read <= 9999)
{
cpu -> mem[loc] = value_read;
printf("Memory location: %02d set to %04d \n", loc, value_read);
cpu -> count++;
loc++;
value_read = NULL;
}
if (loc > 99)
{
printf("Reached Memory limit, quitting loop.\n", loc);
break;
}
read_success = fgets(buffer, DATA_BUFFER_LEN, datafile);
// Gets next line and continues the loop
}
fclose(datafile);
I am reading values from an sdc file with the following values:
1234
3456
-4567;
2353
3434
654
0345
7655
555
9999
10000
The problem is that 0345 shows up as 345, i want 645 to be 0645, and so on.
I tried formatting %d based on a post I saw related to this, but it is not working. Any professional insight?
Edit: I did use %04d to start, but that did not work.
If you want leading zeros to be displayed, use %04d in your printf format.
The 0 is a flag used with d (among others) that says to pad on the left with zeros.
Here is a binary file that contains:
0xff 0xff 0xff
which is exactly three bytes.
I try to use the dump_file function here
#include "table.h"
#include "debug.h"
typedef unsigned int Code
void dump_file( char* fileName[] )
{
char c;
for (int i = 0; i < 4; ++i)
{
log_info("File: %s",fileName[i]);
FILE* file = fopen(fileName[i],"rb");
fread(&c,sizeof(char),1,file);
while( !feof(file) ){
dump_code( c , 8 );
fread(&c,sizeof(char),1,file);
}
}
}
void dump_code( Code code,int BitsNum )
{
int mask = 1 << (BitsNum-1);
for (int i = 0; i < BitsNum ; ++i)
{
if(i%8==0)putchar('|');
putchar((mask & code) ? '1' : '0');
code <<= 1;
}
puts("");
}
to print the file in binary format, but it prints nothing. ( Somehow it bumps into EOF in an undesirable manner ?? )
I also use the Unix unity xxd.
When I signal xxd to print my file in binary, it prints nothing. But if I choose to print hexademically, it prints as expected. What's wrong with this file?
This file is generated by a parser. The C program uses fseek to jump to various location in a file and print the corresponding binary code. It might go like:
0th byte --> 1st byte --> 3rd byte --> 5th byte --> 2nd byte --> 4th byte --> 6th byte
It is guaranteed that there is no "leak" in the resulting file, i.e, every byte will be traversed.
What is the reason for this strange behavior?
Update 1
While pointed out by samgak that this might be due to the interpretation of 0xff, some of my other experiments indicate that even file containing:
0x01 0x01 0x01
which results in the same phenomenon.
Update 2
Here's the relevent code that write Code into file:
#define CODE_FILE_NUM 3
void writeCode( FILE* out[] , Code code ){
for (int i = 0; i < CODE_FILE_NUM; ++i){
fwrite(&code,sizeof(char),1,out[i]);
code >>= 8;
}
}
Code is an unsigned int, which has 4 bytes. Function writeCode will only consider the lower 3 bytes and write each byte into 3 seperate files.
I have found the reason.
It's because I forgot to close the output files.
I tried to dump unclosed binary files ( That is: open and read data from files that haven't been closed. ) , which resulted in unpredictable behaviors.
I'm trying to create a counter using hex, I know this can easily be done using decimals, but is it possible to do this in hex, or is it the same in dec?
will it go like this?
myhex = 0x00;
myhex++;
or will it be done on an entirely different manner?
If you are asking why hex its because this is for an MCU and for me the best way to control the IO of MCU is using hex.
Yes if you try it you will see it, that it makes no difference if the number is hex, octal or decimal!
As an example:
#include <stdio.h>
int main() {
int myhex = 0x07;
int myOct = 07;
int myDec = 7;
printf("Before increment:\n");
printf("Hex: %x\n", myhex);
printf("Oct: %o\n", myOct);
printf("Dec: %d\n", myDec);
myhex++;
myOct++;
myDec++;
printf("After increment:\n");
printf("Hex: %x\n", myhex);
printf("Oct: %o\n", myOct);
printf("Dec: %d\n", myDec);
return 0;
}
Output:
Before increment:
Hex: 7
Oct: 7
Dec: 7
After increment:
Hex: 8
Oct: 10
Dec: 8
OK so I've got this function which finds the average of all numbers in a file:
float averageOfNumbers(FILE *fp_in)
{
int n=0,S=0;
char red[1024];char *ptr;
int p_a_h;
float sr;
while(!feof(fp_in)){
if(fgets(red,1024,fp_in)!=NULL){
ptr =red;
while(p_a_h = strtol(ptr, &ptr, 10)){
if((p_a_h>0&&S>INT_MAX-p_a_h)||(p_a_h<0&&S<INT_MIN-p_a_h)){
printf("OVERFLOW\n");
break;
}
else{
S=p_a_h+S;
n++;}
}
}
}
sr=S/n;
return sr;
}
It works fine when there are only numbers in the file but if it finds anything other than a digit, the program will crash. How can I make it so that the program ignores other symbols. For example here is a text file:
wdadwa 321 1231 das 421124 1 wdasdad 4 1412515
sad14312 yitiyt453534 3554312 sad -2 -53 -12 -231 ##!
#!312 -2 241 -46343 sada 21312 65454
Average should be: 310422
Add an additional check in the if condition.
p_a_h==0 && (strlen(ptr)>1 || (strlen(ptr)==1 && ptr[0]!='0'))
I am making use of the fact that strtol returns 0L if the conversion is invalid(if the string contains non-digit characters). But checking for this alone, also skips if the actual string contains 0. I leave the rest to understand it yourself.