I have 4 byte arrays containing 4 bytes each, and when I print them they print horizontally, but I need them to print vertically. Is this possible in C? I know when I use printf() and pass it the array, it prints all four bytes automatically. Can I sub-divide the array into four separate bytes like a normal array and print each byte on a separate line? There has to be a way.
To illustrate what I am doing, here is the segment that I am having trouble with:
byte a0 = state[0];
byte a1 = state[1];
byte a2 = state[2];
byte a3 = state[3];
state[0] = lookup_g2[a0] ^ lookup_g3[a1] ^ a2 ^ a3;
state[1] = lookup_g2[a1] ^ lookup_g3[a2] ^ a3 ^ a0;
state[2] = lookup_g2[a2] ^ lookup_g3[a3] ^ a0 ^ a1;
state[3] = lookup_g2[a3] ^ lookup_g3[a0] ^ a1 ^ a2;
for (int i = 0; i < 4; i++)
{
printf("%02x", state[i]);
}
printf("%s", "\n");
This prints each byte array in its entirety on each line until main()ends. Preferably, I would like to print each array in groups of four vertically.
Also, I know there is sprintf() which I was recommended to use but for now I'm using printf() until I can figure out how to print vertically.
Example:
printf("%02x", state[0]);
yields:
b9 e4 47 c5
The output I am looking for is:
b9
e4
47
c5
and then the following iterations will print their values next to the first column as shown above. Is this possible?
Then how do you print the next line of bytes in a column next to the
first up to four columns then move to a new line?
If I follow what you are attempting to do, you have 4 state arrays (or 4 rows and columns of something) and you want to output the first line with the first element of each (one in each column), the next line (one element in each column), and so on. If you want to output each value individually, then you will need nested loops, outputting one value at a time in the inner loop (printing each element in a column), then output the '\n' once the inner loop completes.
Something like the following:
#include <stdio.h>
typedef unsigned char byte;
int main (void) {
byte state[] = { 0xb9, 0xe4, 0x47, 0xc5 },
n = sizeof state / sizeof *state;
for (byte i = 0; i < n; i++) { /* outer loop */
for (byte j = 0; j < n; j++) /* inner loop */
printf (" %02x", state[(j+i)%n]); /* stuff */
putchar ('\n'); /* newline after inner loop completes */
}
return 0;
}
Example Use/Output
$ ./bin/byteperline
b9 e4 47 c5
e4 47 c5 b9
47 c5 b9 e4
c5 b9 e4 47
note: I just used the values from the first array 4-times to construct the four columns. You will adjust your indexing scheme to whatever is called for by your data (e.g. to print rows as columns or columns as rows) Regardless how you do it, you must output the values in a row-wise manner. You can't print a column and then back up 4-lines and offset by 5 chars and print the next column. (I mean you can, but that is well-beyond your question and would require a separate curses library to do in a portable fashion)
Look things over and let me know if this is what you intended.
Related
While working with the following PDF, there is an example in
Section 4: CRC-16 Code and Example
(page 95 or 91) that shows a serial packet with a CRC16 value of 133 (LSB) and 24 (MSB).
However, I have tried different calculators, for example:
Lammert
Elaborate calculator
CRC calc
but I cannot get the CRC16 values that the PDF indicates, regardless of the byte combination I use.
How can I correctly calculate the CRC16 in the example, preferably using one of these calculators? (otherwise, C/C++ code should work).
Thanks.
This particular CRC is CRC-16/ARC. crcany generates the code for this CRC, which includes this simple bit-wise routine:
#include <stddef.h>
#include <stdint.h>
uint16_t crc16arc_bit(uint16_t crc, void const *mem, size_t len) {
unsigned char const *data = mem;
if (data == NULL)
return 0;
for (size_t i = 0; i < len; i++) {
crc ^= data[i];
for (unsigned k = 0; k < 8; k++) {
crc = crc & 1 ? (crc >> 1) ^ 0xa001 : crc >> 1;
}
}
return crc;
}
The standard interface is to do crc = crc16arc_bit(0, NULL, 0); to get the initial value (zero in this case), and then crc = crc16arc_bit(crc, data, len); with successive portions of the message to compute the CRC.
If you do that on the nine-byte message in the appendix, {1, 2, 1, 0, 17, 3, 'M', 'O', 'C'}, the returned CRC is 0x1885, which has the least significant byte 133 in decimal and most significant byte 24 in decimal.
Faster table-driven routines are also generated by crcany.
If you give 01 02 01 00 11 03 4d 4f 43 as hex to Lammert Bies' calculator, the very first one, called "CRC-16" gives 0x1885.
If you give 0102010011034d4f43 to crccalc.com and hit Calc-CRC16, the second line is CRC-16/ARC, with the result 0x1885.
I'm having issues trying to set a char variable to a hexadecimal value.
I'm trying to implement a print function where I print the alignment of a structure. The "aa" is suppose to represent the padding, but I can't seem to set the variable in the default constructor.
Output that it should be
0x00: 00 00 00 00
0x04: 00 aa aa aa
.h file
struct A
{
int a0;
char a1;
char pad0;
char pad1;
char pad2;
A() {
a0 = 0;
a1 = 0;
pad1 = 0xAA;
pad2 = 0xAA;
}
};
.cpp
Alignment::Alignment:Print(void *data)
{
int d {0 };
for (int i = 0; i <2; ++i) {
printf("\n0x%02x:", (d));
d = d + 4;
for (int j = 0; j < sizeof(data); ++j)
{
printf(" %.2x", (*((unsigned char*)data+j )));
}
}
}
Main
A *pa = new A;
Pa is passed into the function
My Output
0x00: 00 00 00 00
0x04: 00 00 00 00
There are a few issues with your Print function. Some are "just" style, but they make fixing the real issue harder. (Also, you jumped to conclusions, possibly blinding you to the real issue.) First off, try to explain why the line
printf(" %.2x", (*((unsigned char*)data+j )));
is supposed to do something different just because i and d changed. Neither of those variables are in this line, so you get the same output with each iteration of the outer loop. The problem is not in the setting of data, but in the reading of it. For each line of output, you print the first four bytes of data when you intended to print the next four bytes.
To get the next four bytes, you need to add d to the pointer, but this is problematic because you increased d earlier in this iteration. Better would be to have d keep the same value throughout each iteration. You could increase it at the end of the iteration instead of the middle, but even slicker might be to use d to control the loop instead of i.
Finally, a bit of robustness: your code uses the magic number 4 when increasing d, which only works if sizeof(data) is 4. Fragile. Better would be to use a symbolic constant for this magic value to ensure consistency. I'll set it explicitly to 4 since I don't see why the size of a pointer should impact how the pointed-to data is displayed.
Alignment::Alignment::Print(void *data)
{
constexpr int BytesPerLine = 4; // could use sizeof(void *) instead of 4
const unsigned char * bytes = static_cast<unsigned char*>(data); // Taking the conversion out of the loop.
for (int d = 0; d < 2*BytesPerLine; d += BytesPerLine) {
printf("\n0x%02x:", (d));
for (int j = 0; j < BytesPerLine; ++j)
{
printf(" %.2x", *(bytes + d + j)); // Add d here!
}
}
}
In C++ I want to encode the bits of 3 unsigned variables into one. More precisely, when the three variables are:
A: a3 a2 a1 a0
B: b3 b2 b1 b0
C: c3 c2 c1 c0
then the output variable shall contain such triples:
D: a3 b3 c3 a2 b2 c2 a1 b1 c1 a0 b0 c0
Let's assume that the output variable is large enough for all used bits. I have come up with
unsigned long long result(0);
unsigned a,b,c; // Some numbers to be encoded
for(int level=0;level<numLevels;++level)
{
int q(1<<level); // SearchBit q: 1<<level
int baseShift((3*level)-level); // 0,2,4,6
result|=( ((a&q)<<(baseShift+2)) | ((b&q)<<(baseShift+1)) | ((c&q)<<(baseShift)) );
}
...and it works sufficiently. But I wonder if there is a solution that does not require a loop that iterates over all bits separately.
Define a table mapping all or part of your bits to where they end up. Shift values appropriately.
unsigned long long encoder(unsigned a, unsigned b, unsigned c) {
static unsigned const encoding[16] = {
0b0000000000,
0b0000000001,
0b0000001000,
0b0000001001,
0b0001000000,
0b0001000001,
0b0001001000,
0b0001001001,
0b1000000000,
0b1000000001,
0b1000001000,
0b1000001001,
0b1001000000,
0b1001000001,
0b1001001000,
0b1001001001,
};
unsigned long long result(0);
int shift = 0;
do {
result += ((encoding[a & 0xF] << 2) | (encoding[b & 0xF] << 1) | encoding[c & 0xF]) << shift;
shift += 12;
a >>= 4;
b >>= 4;
c >>= 4;
} while (a || b || c);
return result;
}
encoding defines a table to map 4 bits into their encoded locations. This used directly for c, and shifted 1 or 2 bits for b and a. If you have more than 4 bits to process, the next 4 bits in the source values are offset 12 bits further to the left. Keep doing this until all nonzero bits have been processed.
This could use a while loop instead of a do/while but checking for zero before starting is useless unless most of the encodings are of all zero values.
If you frequently use more than 4 bits, the encoding table can be expanded and appropriate changes made to the loop to process more than 4 bits at a time.
I have a simple c++ program (and a similar one for c) that just prints out the first argument
#include <iostream>
int main(int argc, char** argv)
{
if(argc > 1)
std::cout << ">>" << argv[1] << "<<\n";
}
I can pass binary data (i have tried on bash) as argument like
$./a.out $(printf "1\x0123")
>>1?23<<
If I try to pass a null there i get
./a.out $(printf "1\x0023")
bash: warning: command substitution: ignored null byte in input
>>123<<
Clearly bash(?) does not allow this
But is it possible to send a null as a command line argument this way?
Do either c or c++ put any restrictions on this?
Edit: I am not using this in day-to-day c++, this question is just out of curiosity
This answer is written in C, but can be compiled as C++ and works the same in both. I quote from the C11 standard; there are equivalent definitions in the C++ standards.
There isn't a good way to pass null bytes to a program's arguments
C11 §5.1.2.2.1 Program startup:
If the value of argc is greater than zero, the array members argv[0] through argv[argc-1] inclusive shall contain pointers to strings, which are given implementation-defined values by the host environment prior to program startup.
C11 §7.1.1 Definitions of terms
A string is a contiguous sequence of characters terminated by and including the first null character.
That means that each argument passed to main() in argv is a null-terminated string. There is no reliable data after the null byte at the end of the string — searching there would be accessing out of bounds of the string.
So, as noted at length in the comments to the question, it is not possible in the ordinary course of events to get null bytes to a program via the argument list because null bytes are interpreted as being the end of each argument.
By special agreement
That doesn't leave much wriggle room. However, if both the calling/invoking program and the called/invoked program agree on the convention, then, even with the limitations imposed by the standards, you can pass arbitrary binary data, including arbitrary sequences of null bytes, to the invoked program — up to the limits on the length of an argument list imposed by the implementation.
The convention has to be along the lines of:
All arguments (except argv[0], which is ignored, and the last argument, argv[argc-1]) consist of a stream of non-null bytes followed by a null.
If you need adjacent nulls, you have to provide empty arguments on the command line.
If you need trailing nulls, you have to provide empty arguments as the last arguments on the command line.
This could lead to a program such as (null19.c):
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
static void hex_dump(const char *tag, size_t size, const char *buffer);
int main(int argc, char **argv)
{
if (argc < 2)
{
fprintf(stderr, "Usage: %s arg1 [arg2 '' arg4 ...]\n", argv[0]);
exit(EXIT_FAILURE);
}
size_t len_args = 0;
for (int i = 1; i < argc; i++)
len_args += strlen(argv[i]) + 1;
char buffer[len_args];
size_t offset = 0;
for (int i = 1; i < argc; i++)
{
size_t arglen = strlen(argv[i]) + 1;
memmove(buffer + offset, argv[i], strlen(argv[i]) + 1);
offset += arglen;
}
assert(offset != 0);
offset--;
hex_dump("Argument list", offset, buffer);
return 0;
}
static inline size_t min_size(size_t x, size_t y) { return (x < y) ? x : y; }
static void hex_dump(const char *tag, size_t size, const char *buffer)
{
printf("%s (%zu):\n", tag, size);
size_t offset = 0;
while (size != 0)
{
printf("0x%.4zX:", offset);
size_t count = min_size(16, size);
for (size_t i = 0; i < count; i++)
printf(" %.2X", buffer[offset + i] & 0xFF);
putchar('\n');
size -= count;
offset += count;
}
}
This could be invoked using:
$ ./null19 '1234' '5678' '' '' '' '' 'def0' ''
Argument list (19):
0x0000: 31 32 33 34 00 35 36 37 38 00 00 00 00 00 64 65
0x0010: 66 30 00
$
The first argument is deemed to consist of 5 bytes — four digits and a null byte. The second is similar. The third through sixth arguments each represent a single null byte (it gets painful if you need large numbers of contiguous null bytes), then there is another string of five bytes (three letters, one digit, one null byte). The last argument is empty but ensures that there is a null byte at the end. If omitted, the output would not include that final terminal null byte.
$ ./null19 '1234' '5678' '' '' '' '' 'def0'
Argument list (18):
0x0000: 31 32 33 34 00 35 36 37 38 00 00 00 00 00 64 65
0x0010: 66 30
$
This is the same as before except there is no trailing null byte in the data. The two examples in the question are easily handled:
$ ./null19 $(printf "1\x0123")
Argument list (4):
0x0000: 31 01 32 33
$ ./null19 1 23
Argument list (4):
0x0000: 31 00 32 33
$
This works strictly within the standard assuming only that empty strings are recognized as valid arguments. In practice, those arguments are already contiguous in memory so it might be possible on many platforms to avoid the copying phase into the buffer. However, the standard does not stipulate that the argument strings are laid out contiguously in memory.
If you need multiple arguments with binary data, you can modify the convention. For example, you could take a control argument of a string which indicates how many subsequent physical arguments make up one logical binary argument.
All this relies on the programs interpreting the argument list as agreed. It is not really a general solution.
I encountered an odd problem when exporting float values to a file. I would expect every float to be of the same length (obviously), but my programme sometimes exports it a 32 bit number and sometimes as a 40 bit number.
A minimal working example of a programme that still shows this behaviour is:
#include <stdio.h>
const char* fileName = "C:/Users/Path/To/TestFile.txt";
float array [5];
int main(int argc, char* argv [])
{
float temp1 = 1.63006e-33f;
float temp2 = 1.55949e-32f;
array[0] = temp1;
array[1] = temp2;
array[2] = temp1;
array[3] = temp2;
array[4] = temp2;
FILE* outputFile;
if (!fopen_s(&outputFile, fileName, "w"))
{
fwrite(array, 5 * sizeof(float), 1, outputFile);
fclose(outputFile);
}
return true;
}
I would expect the output file to contain exactly 20 (5 times 4) bytes, each four of which represent a float. However, I get this:
8b 6b 07 09 // this is indeed 1.63006e-33f
5b f2 a1 0d 0a // I don't know what this is but it's a byte too long
8b 6b 07 09
5b f2 a1 0d 0a
5b f2 a1 0d 0a
So the float temp2 takes 5 bytes instead of four, and the total length of he file is 23. How is this possible?! The number aren't so small that they are subnormal numbers, and I can't think of any other reason why there would be a difference in size.
I am using the MSVC 2010 compiler on a 64-bit Windows 7 system.
Note: I already asked a very similar question here, but when I realised the problem was more general, I decided to repost it in a more concise way.
QDataStream uses sometimes 32 bit and sometimes 40 bit floats
The problem is that on Windows, you have to differentiate between text and binary files. You have the file opened as text, which means 0d (carriage-return) is inserted before every 0a (line-feed) written. Open the file like this:
if (!fopen_s(&outputFile, fileName, "wb"))
The rest as before, and it should work.
You're not writing text; you're writing binary data... However, your file is open for writing text ("w") instead of writing binary ("wb"). Hence, fwrite() is translating '\n' to "\r\n".
Change this:
if (!fopen_s(&outputFile, fileName, "w"))
To this:
if (!fopen_s(&outputFile, fileName, "wb"))
In "wb", the b stands for binary mode.