Create Function: Every 8 increments = one paragraph - c

I want to create a function in c, which creates every 8 increments (to be exact, when an integer holds the value 8) a paragraph/new line (and also prints an offset).
In this case, i've got an array
for (int i = 0; i < sizeof(myarray); i++){
printf(" %02hhX", myarray[i]);
}
Now i want to implement my function like this
int row = 0;
for (int i = 0; i < sizeof(myarray); i++){
printf(" %02hhX", myarray[i]);
check_newline(row);
}
The function 'check_newline' has this structure:
void check_newline(int row){
row++;
if(row==8){
offset = offset + 8;
row= 0;
printf("\n%06X", offset);
}
}
Everytime, the integer 'row' reaches the value 8 a new offset will be printed and the value of 'row' will be reset to 0.
Now, i don't know how to implement the return; and with this code, my output looks like this
000008 E0 60 66 64 38 7D E0 60 66 64 38 7D 80000008 80 00 FF FF FF FF FF FF 000010 E0 60 66 64 38 7D E0 60 66 64 38 7D 80000010 80 00 FF FF FF FF FF FF
(totaly wrong)
When i 'put the function inside my code' (so basicaly don't use a function), everything is nice, because of the missing return statement.
for (int i = 0; i < sizeof(myarray); i++){
printf(" %02hhX", myarray[i]);
row++;
if(row==8){
offset = offset + 8;
row= 0;
printf("\n%06X", offset);
}
000000 80 00 FF FF FF FF FF FF
000008 E0 60 66 64 38 7D E0 60
I have to use this kind of calculation often in my code, so a function will be more sleek.

You are over complicating things. You don't need the extra variables as you can make use of i and the % (modulo operator) to work out when you're at the beginning or end of a row like this.
for (int i = 0; i < sizeof(myarray); i++) {
if (i % 8==0) {
printf("%06X",i);
}
printf(" %02hhX", myarray[i]);
if (i % 8==7) {
printf("\n");
}
}

Related

How to delete bytes from a byte array in between in C?

Given a byte array buff of length n:
unsigned char buff[n] = "....." // len n
I want to delete m characters at position pos,
0 < pos, m, pos + m < n
I tried using memmove:
memmove(buff + pos, buff + pos + m, n - (pos + m) + 1);
But this doesn't work for byte array as we don't have '\0' terminator for this buff (but we know its length)
How do I delete bytes in between? Anyone please help
Edit: Sample input,
Pos    Data
0000  03 00 02 ef 02 f0 80 64 00 08 03 eb 70 82 e0 40
0010  00 ff 30 00 00 00 00 b3 47 43 00 00 00 00 00 00
0020  00 1e 00 c4 00 00 00 00 00 00 00 44 00 65 00 66
0030  00 61 00 75 00 6c 00 74 00 41 00 6c 00 74 00 53
Say I want to delete the highlighted bytes from packet.
New paket,
Pos    Data
0000  03 00 02 ef 02 f0 80 64 00 08 03 00 00 00 00 00
0010  00 00 44 00 65 00 66 00 61 00 75 00 6c 00 74 00
0020  41 00 6c 00 74 00 53
This would erase m chars in an array without terminating null character.
int main()
{
int pos = 1, m = 3;
unsigned char arr[8] = {1,2,3,4,5,6,7,8};
memmove(arr + pos, arr + pos + m, sizeof(arr)/sizeof(arr[0]) - pos - m);
// if required to zero-out the remaining elements
memset(arr + sizeof(arr)/sizeof(arr[0]) - m, 0, m);
for (int i = 0; i < sizeof(arr)/sizeof(arr[0]); i++)
printf("%hhu ", arr[i]);
return 0;
}
Output: 1 5 6 7 8 0 0 0
You probably want something like this:
#include <stdio.h>
#include <string.h>
void Display(const char buff[], int nb)
{
for (int i = 0; i < nb; i++)
printf("%d ", buff[i]);
printf("\n");
}
int main()
{
unsigned char buff[20] = { 0,1,2,3,4,5 };
// buff has room for 20 elements
int nbelements = 6; // but there are only 6 meaningful elements
Display(buff, nbelements);
int pos = 1; // delete from element 1
int nbtodelete = 2; // delete 2 elements
memmove(buff + pos, buff + pos + nbtodelete, nbelements - pos - 1);
nbelements -= nbtodelete;
Display(buff, nbelements);
}
Output:
0 1 2 3 4 5
0 3 4 5
It's pretty self explanatory.

Reading Hex from an file

So my knowledge of pointers is a bit rusty and I think thats where I'm getting messed up, I am trying to write a function that will grab hex values (an amount n) at a specified offset in the file. And write those values to an array.
File I'm reading from, Example
0 1 2 3 4 5 6 7 8 9 A B C D E F
0 F6 EA 9D DE D8 40 1C 44 19 24 59 D2 6A 2C 48 1D
1 FC 96 DE 94 AF 95 FC 42 9B 6D DA 15 D4 CE 88 BB
2 B8 24 99 8F 65 B5 D3 7E D9 5D 51 44 89 97 61 85
3 2D 40 1A DC D5 16 1F 70 84 F9 85 58 C8 0E 13 80
4 32 AC 10 97 61 B3 16 3B 40 67 7A CA FE E1 4F 2B
5 21 A9 07 F6 80 26 66 04 20 EC 5C E8 FA 70 68 2C
6 1C 78 C4 7E 5C DA B9 9C 41 38 66 3F 19 B6 6A 3A
Here's the function I've written thus far.
aDest point's to an array of size nBytes + 1
bAddr point's to firstbyte of the memory region
OffsetAmt is a location which is relative bAddr
nBytes is just the number of bytes that I want to copy
Heres the function
void getHexBytesAt(uint8_t* const aDest, const uint8_t* const bAddr,
uint16_t OffsetAmt, uint8_t nBytes)
{
const uint8_t *point1 = bAddr; //set he address of point1 to base address value
//front point1 shift until we get to the specified offset value
for (int i = 0; i < Offset; i++)
{
point1 = (point1 + 1);
}
//set the values of *aDest to the value of point1;
//increment point1
for (int k = 0; k < nBytes; k++)
{
*aDest = point1;
point1 = (point1 + 1);
}
The problem I'm having is im not even getting the first byte copied into the array correctly,
My output looks like this Getting 9 bytes,
starting at the offset 2C
MY OUTPUT: 84 CA CA CA CA CA CA CA CA
FILE: 89 97 61 85 2D 40 1A DC D5
If you want to read the data from the Memory bAddr then you must
dereference the pointer for reading
increment the Destination pointer
This would be implemented like this:
void getHexBytesAt(uint8_t* const aDest, const uint8_t* const bAddr,
uint16_t OffsetAmt, uint8_t nBytes)
{
const uint8_t *point1 = bAddr; //set he address of point1 to base address value
//front point1 shift until we get to the specified offset value
for (int i = 0; i < OffsetAmt; i++) // fixed typo
{
point1 = (point1 + 1);
}
//set the values of *aDest to the value of point1;
//increment point1
for (int k = 0; k < nBytes; k++)
{
*aDest = *point1; // copy data from address the point1 points to
aDest = aDest + 1; // increment destination pointer
point1 = (point1 + 1);
}
}
But this can be done much simpler:
void getHexBytesAt(uint8_t* const aDest, const uint8_t* const bAddr,
uint16_t OffsetAmt, uint8_t nBytes)
{
memcpy(aDest, bAddr + OffsetAmt, nBytes);
}
You should consider replacing the function with the one-liner that implements it in your code.
BTW: There is no file used in the code. You should review your question.

Why does my C code not work everytime?

I wrote this code to merge two sorted arrays. The desired output is:
Merged array:0 1 2 3 4 5 6 7 8 9 10 11 12
I am using gcc (Ubuntu 5.4.0-6ubuntu1~16.04.4) 5.4.0 20160609 to compile my code.
The problem is that sometimes I get the desired output when I execute the a.out file but on other occasions, the cursor keeps blinking and no result is shown. Why is this happening? Is there something wrong with my code?
#include<stdio.h>
#include<stdlib.h>
int main(void){
//change arrays as per your need but it should be sorted
int a[] = {1,2,3,7,8};
int b[] = {0,3,5,6,9,10,11,12};
int m =sizeof(a) / sizeof(int);
int n =sizeof(b) / sizeof(int);
int index=0, j=0, k=0;
int size = m + n;
int array[size];
while(index < size) {
while(a[j] < b[k] && j<m ){
array[index] = a[j];
++index;
++j;
}
while(a[j] > b[k] && k<n){
array[index] = b[k];
++index;
++k;
}
while(a[j] == b[k]){
array[index] = a[j];
j++; index++;
}
}
printf("Merged array: ");
for(int i=0; i<size; i++)
printf("%d ", array[i]);
printf("\n");
}
You have undefined behaviour (accessing the array out of bounds). Use gcc -fsanitize=undefined to create an executable that can detect all sorts of bad behaviour.
% gcc -g fffff.c -Wall -Wextra -fsanitize=undefined
% ./a.out
fffff.c:20:12: runtime error: index 5 out of bounds for type 'int [5]'
fffff.c:20:12: runtime error: load of address 0x7ffd0c0c9804 with insufficient space for an object of type 'int'
0x7ffd0c0c9804: note: pointer points here
08 00 00 00 04 00 00 00 04 00 00 00 04 00 00 00 00 00 00 00 03 00 00 00 05 00 00 00 06 00 00 00
^
fffff.c:25:12: runtime error: index 5 out of bounds for type 'int [5]'
fffff.c:25:12: runtime error: load of address 0x7ffd0c0c9804 with insufficient space for an object of type 'int'
0x7ffd0c0c9804: note: pointer points here
08 00 00 00 04 00 00 00 04 00 00 00 04 00 00 00 00 00 00 00 03 00 00 00 05 00 00 00 06 00 00 00
^
fffff.c:30:12: runtime T: index 5 out of bounds for type 'int [5]'
fffff.c:30:12: runtime error: load of address 0x7ffd0c0c9804 with insufficient space for an object of type 'int'
0x7ffd0c0c9804: note: pointer points here
08 00 00 00 04 00 00 00
The lines 20, 25 and 30 are
20 while(a[j] < b[k] && j<m ){
25 while(a[j] > b[k] && k<n){
30 while(a[j] == b[k]){
Is there something wrong with my code?
Yes!
It gets out of bounds when accessing a, here for example:
while(a[j] < b[k] && j<m ){
array[index] = a[j];
++index;
++j;
}
j will eventually get the value 4, enter the body of the if statement, and when it tries to resolve the condition of the while loop, it will access a[5], which is out of bounds, thus causing Undefined Behavior (which explains why your code runs sometimes, and others hang).
You could let short circuiting help you by changing your while loop's condition to this:
while(j < m && a[j] < b[k]) {
which when j reaches mm, resulting in j<m evaluated to false, will not go through a[j] < b[k], because a logical and operation will be false, if at least one of its operands are false.
Same happens in your next while loop. So change it to this:
while(k < n && a[j] > b[k]) {
Last, but not least, the condition of the last while loop:
while(a[j] == b[k]){
will also invoke Undefined Behavior, since j will be equal to 5, and k equal to 8.
Changing it to:
while(j < m && k < n && a[j] == b[k]) {
will prevent Undefined Behavior from being invoked.

How to parse hex dump

I have a flash memory dump file that spits out addresses and data.
I want to parse the data so that it will tell me the valid tags
The '002F0900' column are the starting addresses.
An example of a valid tag is "DC 08 00 06 00 00 07 26 01 25 05 09" where "DC 08" = tag number, "00 06" = tag data length, "00 00" = tag version. Tag data starts after the version and in this case would be "07 26 01 25 05 09" and the next tag would start "DC 33".
I'm able to print out the first tag up to the data length but I'm not sure how to print the data because I have to consider if the data will go onto the next line so I'd have to skip the address somehow. Each line contains 58 columns. Each address is 8 characters long plus a colon and 2 spaces until the next hex value starts.
I also will eventually have to consider when "DC" shows up in the address column.
If anyone could give some advice because I know how I'm doing this isn't the best way to do this. I'm just trying to get it to work first.
The text file is thousands of lines that look like this:
002F0900: 09 FF DC 08 00 06 00 00 07 26 01 25 05 09 DC 33
002F0910: 00 07 00 00 1F A0 26 01 25 05 09 FF 9C 3E 00 08
002F0920: 00 01 07 DD 0A 0D 00 29 35 AD 9C 41 00 0A 00 01
002F0930: 07 DD 0A 0D 00 29 36 1C 1D 01 9C 40 00 02 00 01
002F0940: 01 00 9C 42 00 0A 00 01 07 DD 0A 0D 00 29 36 21
002F0950: 1D AD 9C 15 00 20 00 00 01 00 00 00 00 04 AD AE
002F0960: C8 0B C0 8A 5B 52 01 00 00 00 00 00 FF 84 36 BA
002F0970: 4E 92 E4 16 28 86 75 C0 DC 10 00 05 00 00 00 00
002F0980: 00 00 01 FF DC 30 00 04 00 01 00 00 00 01 9C 41
Example output would be:
Tag Number: DC 08
Address: 002E0000
Data Length: 06
Tag Data: 07 26 01 25 05 09
Source Code:
#include<stdio.h>
FILE *fp;
main()
{
int i=0;
char ch;
char address[1024];
char tag_number[5];
char tag_length[4];
int number_of_addresses = 0;
long int length;
fp = fopen(FILE_NAME,"rb");
if(fp == NULL) {
printf("error opening file");
}
else {
printf("File opened\n");
while(1){
if((address[i]=fgetc(fp)) ==':')
break;
number_of_addresses++;
i++;
}
printf("\nAddress:");
for (i = 0; i < number_of_addresses;i++)
printf("%c",address[i]);
while((ch = fgetc(fp)) != 'D'){ //Search for valid tag
}
tag_number[0] = ch;
if((ch = fgetc(fp)) == 'C') //We have a valid TAG
{
tag_number[1] = ch;
tag_number[2] = fgetc(fp);
tag_number[3] = fgetc(fp);
tag_number[4] = fgetc(fp);
}
printf("\nNumber:");
for(i=0;i<5;i++)
printf("%c",tag_number[i]);
fgetc(fp); //For space
tag_length[0] = fgetc(fp);
tag_length[1] = fgetc(fp);
fgetc(fp); //For space
tag_length[2] = fgetc(fp);
tag_length[3] = fgetc(fp);
printf("\nLength:");
for(i=0;i<4;i++)
printf("%c",tag_length[i]);
length = strtol(tag_length,&tag_length[4], 16);
printf("\nThe decimal equilvant is: %ld",length);
for (i = 0;i<165;i++)
printf("\n%d:%c",i,fgetc(fp));
}
fclose(fp);
}
Update #ooga:The tags are written arbitrarily. If we also consider invalid tag in the logic then I should be able to figure out the rest if I spend some time. Thanks
This is just an idea to get you started since I'm not entirely sure what you need. The basic idea is that read_byte returns the next two-digit hex value as a byte and also returns its address.
#include <stdio.h>
#include <stdlib.h>
#define FILE_NAME "UA201_dump.txt"
void err(char *msg) {
fprintf(stderr, "Error: %s\n", msg);
exit(EXIT_FAILURE);
}
// read_byte
// Reads a single two-digit "byte" from the hex dump, also
// reads the address (if necessary).
// Returns the byte and current address through pointers.
// Returns 1 if it was able to read a byte, 0 otherwise.
int read_byte(FILE *fp, unsigned *byte, unsigned *addr_ret) {
// Save current column and address between calls.
static int column = 0;
static unsigned addr;
// If it's the beginning of a line...
if (column == 0)
// ... read the address.
if (fscanf(fp, "%x:", &addr) != 1)
// Return 0 if no address could be read.
return 0;
// Read the next two-digit hex value into *byte.
if (fscanf(fp, "%x", byte) != 1)
// Return 0 if no byte could be read.
return 0;
// Set return address to current address.
*addr_ret = addr;
// Increment current address for next time.
++addr;
// Increment column, wrapping back to 0 when it reaches 16.
column = (column + 1) % 16;
// Return 1 on success.
return 1;
}
int main() {
unsigned byte, addr, afterdc, length, version, i;
FILE *fp = fopen(FILE_NAME,"r");
if (!fp) {
fprintf(stderr, "Can't open %s\n", FILE_NAME);
exit(EXIT_FAILURE);
}
while (read_byte(fp, &byte, &addr)) {
if (byte == 0xDC) {
// Read additional bytes like this:
if (!read_byte(fp, &afterdc, &addr)) err("EOF 1");
if (!read_byte(fp, &length, &addr)) err("EOF 2");
if (!read_byte(fp, &byte, &addr)) err("EOF 3");
length = (length << 8) | byte;
if (!read_byte(fp, &version, &addr)) err("EOF 4");
if (!read_byte(fp, &byte, &addr)) err("EOF 5");
version = (version << 8) | byte;
printf("DC: %02X, %u, %u\n ", afterdc, length, version);
for (i = 0; i < length; ++i) {
if (!read_byte(fp, &byte, &addr)) err("EOF 6");
printf("%02X ", byte);
}
putchar('\n');
}
}
fclose(fp);
return 0;
}
Some explanation:
Every time read_byte is called, it reads the next printed byte (the two-digit hex values) from the hex dump. It returns that byte and also the address of that byte.
There are 16 two-digit hex values on each line. The column number (0 to 15) is retained in a static variable between calls. The column is incremented after reading each byte and reset to 0 every time the column reaches 16.
Any time the column number is 0, it reads the printed address, retaining it between calls in a static variable. It also increments the static addr variable so it can tell you the address of a byte anywhere in the line (when the column number is not zero).
As an example, you could use read_bye like this, which prints each byte value and it's address on a separate line:
// after opening file as fp
while (read_byte(fp, &byte, &addr))
printf("%08X- %02X\n", addr, byte);
(Not that it would be useful to do that, but to test it you could run it with the snippet you provided in your question.)

Serialization issues while sending struct over socket

I am developing a Client/Server based on UDP I want to send different messages to the client from the server. There are different C structures defined for each message.
I would like to understand what is wrong in the way I am serializing the data.
struct Task
{
int mType;
int tType;
int cCnt;
int* cId;
char data[128];
};
Serialization/Deserialization functions
unsigned char * serialize_int(unsigned char *buffer, int value)
{
buffer[0] = value >> 24;
buffer[1] = value >> 16;
buffer[2] = value >> 8;
buffer[3] = value;
return buffer + 4;
}
unsigned char * serialize_char(unsigned char *buffer, char value)
{
buffer[0] = value;
return buffer + 1;
}
int deserialize_int(unsigned char *buffer)
{
int value = 0;
value |= buffer[0] << 24;
value |= buffer[1] << 16;
value |= buffer[2] << 8;
value |= buffer[3];
return value;
}
char deserialize_char(unsigned char *buffer)
{
return buffer[0];
}
Sender side code to serialize the structure
unsigned char* serializeTask(unsigned char* msg, const Task* t)
{
msg = serialize_int(msg,t->mType);
msg = serialize_int(msg,t->tkType);
msg = serialize_int(msg,t->cCnt);
for(int i=0; i<t->cCnt; i++)
msg = serialize_int(msg,t->cId[i*4]);
for(int i=0; i<strlen(data); i++)
msg = serialize_char(msg,t->data[i]);
return msg;
}
Receiver side code to de-serialize data
printf("Msg type:%d\n", deserialize_int(message) );
printf("Task Type:%d\n", deserialize_int(message+4) );
printf("Task Count:%d\n", deserialize_int(message+8));
Output
Msg type:50364598 //Expected value is 3
Task Type:-2013036362 //Expected value is 1
Task Count:1745191094 //Expected value is 3
Question 1:
Why is the de-serialized value not same as expected?
Question 2:
How is serialization/de-serialization method different from memcpy?
Task t;
memcpy(&t, msg, sizeof(t)); //msg is unsigned char* holding the struct data
EDIT
Code which invokes serializeTask
void addToDatabase(unsigned char* message, int msgSize, Task* task)
{
message = new unsigned char[2*msgSize+1];
unsigned char* msg = message; //To preserve start address of message
message = serializeTask(message, task); //Now message points to end of the array
//Insert serialized data to DB
//msg is inserted to DB
}
Serialized data stored in DB
Message:
00
03 70 B6 88 03 70 B6 68 05 70 B6 68 05 70 B6 00
00 00 00 00 00 00 00 A8 05 70 B6 AC 05 70 B6 B4
05 70 B6 C9 05 70 B6 DE 05 70 B6 E6 05 70 B6 EE
05 70 B6 FB 05 70 B6 64 65 66 00 63 6F 68 6F 72
74 73 00 70 65 6E 64 69 6E 67 5F 61 73 73 69 67
6E 5F 74 61 73 6B 73 00 70 65 6E 64 69 6E 67 5F
61 73 73 69 67 6E 5F 74 61 73 6B 73 00 6D 65 73
73 61 67 65 00 6D 65 73 73 61 67 65 00 3F 00 FF
FF 00 00 FC 90 00 00 00 00 00 00 00 C9 2D B7 00
00 00 00 10 06 70 B6 00 00 00 00 00 00 00 00 30
06 70 B6 34 06 70 B6 3C 06 70 B6
OP has 2 problems in serializeTask()
for(int i=0; i<t->cCnt; i++)
msg = serialize_int(msg,t->cId[i*4]); [i*4]
...
for(int i=0; i<strlen(data); i++)
msg = serialize_char(msg,t->data[i]); strlen(data)
Should be (assuming i<strlen(data) should have been i<strlen(t->data)
for(int i=0; i<t->cCnt; i++)
msg = serialize_int(msg,t->cId[i]); // [i]
...
for(int i=0; i<strlen(t->data); i++) // strlen(data) + 1
msg = serialize_char(msg,t->data[i]);
The first for loop serialize every 4th cId[]. OP certainly wanted to serialize consecutive cId[].
Only the length of the data string was serialized. OP certainly wanted to serialize all that and a NUL terminating byte.
The data in the posted buffer is more likely the below, which does not match the serialization code. This implies the higher level code populating Task* t is wrong. I am confident that the values seen in fields mType and tkType are either pointers or float, again Task* t is likely amiss before the serialization.
0xb6700300 or -3.576453e-06
0xb6700388 or -3.576484e-06
0xb6700568 or -3.576593e-06
0xb6700568 or -3.576593e-06
0x000000 or 0.000000e+00
0x000000 or 0.000000e+00
0xb67005a8 or -3.576608e-06
0xb67005ac or -3.576609e-06
0xb67005b4 or -3.576611e-06
0xb67005c9 or -3.576615e-06
0xb67005de or -3.576620e-06
0xb67005e6 or -3.576622e-06
0xb67005ee or -3.576624e-06
0xb67005fb or -3.576627e-06
def\0cohorts\0pending_assign_tasks\0pending_assign_tasks\0message\0message\0?\0
...

Resources