I am writing a C++ function which has a print flag. I want to print different messages using this flag. I thought of this flag to take three different binary values and to print different messages depending on its value.
flag == 000
printf "flag is 0"
flag == 010
printf "flag is 1"
flag == 100
printf "flag is 2"
How can I compare the value of this flag such that I can have the following output:
flag ==011
printf "flag is 0"
printf "flag is 1"
flag ==101
printf "flag is 0"
printf "flag is 2"
flag ==111
printf "flag is 0"
printf "flag is 1"
printf "flag is 2"
I know that I can add more if-blocks to do this task, which does not look professional. Could someone help me find the proper way and avoid writing unnecessary if-blocks?
Maybe something like:
char flags[] = { 0x01, 0x02, 0x04, 0x08 };
int i;
for(i = 0 ; i < sizeof(flags) ; i++ )
if(flag & flags[i])
printf("flag is %i\n",i + 1);
You could loop through and do a bitwise and (&) with each bit in flags. This means you don't have to add more if/else blocks if you want to check more bits. e.g.:
#include <stdio.h>
int main() {
int flags = 7;
int n = 3; // change this to however many bits you want to check
for (int i=0; i<n; ++i) {
if (flags & 1<<i) {
printf("flag is %d\n", i);
}
}
}
Essentially you want to print out which bits are set in the flag. To do that you can use a loop and a right shift.
for(int bit = 0; flag > 0; ++bit, flag >>= 1) {
if(flag & 1)
printf("flag is %d\n", bit);
}
Note that this will destroy the value of flag so make a copy of it if you want to use it again later.
Related
I want to know why the value of i is not updating to i=0 when i == n-1, as I have written in the code. The bool flag is just there to check if the if statement was rendering at all or not (It is).
#include <bits/stdc++.h>
using namespace std;
int main()
{
int t;
scanf("%d", &t);
while (t--)
{
int n, ans = 0;
scanf("%d", &n);
int s[n];
bool flag = false;
for (int i = 0; i < n; i++)
{
scanf("%d", &s[i]);
}
for (int i = 0; i < n; i++)
{
s[i] -= 1;
if (s[i] < 0)
break;
ans++;
if (i == (n - 1))
{
i=0;
flag = true;
}
}
printf("\n%d\n", ans);
printf("%d", flag);
}
return 0;
}
How do you know it's not doing what you want. I ran it and got this:
$ ./foo
1
2 3 4
5
1
$
The final value (1) is true. So it looks like it's doing it to me.
However, this is pretty terrible code. It's a really bad practice to muck with your iterator variable inside your loop like that. That's GOING to bite you. Furthermore, you're not going to go back to 0 -- you're going to go back to 1, because the next thing it does is increment the variable with your i++. So your if-statement sets i to 0 and your for-loop turns it into 1.
But this is just weird. If you need to run the loop multiple times, then wrap it in a larger loop.
Others have commented on printf. Personally, I disagree with them. There are times printf is completely valid. HOWEVER -- the way you're using it for such simple, unformatted stuff, isn't really one of them.
I changed the last printf to this:
cout << "Flag (raw): " << flag << ". Which means: " << (flag ? "True" : "False") << endl;
Output is this:
Flag (raw): 1. Which means: True
As you can see -- it's 1, which is not 0, so it's true.
I'm having a bit of a trouble figuring out the correct calculation of WORD, DWORD etc.
I'm having kind of a knot in my brain, probably sitting on this problem for too long.
I'm reading a PE-section header. So far everything is ok.
Here is a sample output from a random .exe file:
File is 286 Kbytes large
PE-Signature [# 0x108]
0x00000100: ........ ........ 504500
Collect Information (PE file header):
[WORD] Mashinae Type :014C
[WORD] Number of Sections :0006
[DWORD] TimeStamp :5C6ECB00
[DWORD] Pointer to symbol table:00000000
[DWORD] Number of Symbols :00000000
[WORD] Size of optional header:00E0
Now, as you see the size of the "optional" header is 0x00E0, so I was trying to buffer that for later.
(Bc. it would make things faster to just read the complete header).
Where I'm having problems is the point where I am to convert the little-endian values to an actual integer.
I need to read the value from behind (so the second WORD [ 00 ] is actually the first value to be read).
The second value, however, needs to be shifted in some way (bc. significance of bytes), and this is where I am struggeling. I guess the solution is not that hard, I just ran out of wisdom lol.
Here is my draft for a function that should return an integer value with the value:
//get a specific value and safe it for later usage
int getValue(char* memory, int start, int end)
{
if (end <= start)
return 0;
unsigned int retVal = 0;
//now just add up array fields
for (int i = end; i >= start; i--)
{
fprintf(stdout, "\n%02hhx", memory[i]);
retVal &= (memory[i] << 8 * (i- start));
}
fprintf(stdout, "\n\n\n%d",retVal);
return retVal;
}
In other words, I need to parse an array of hex values (or chars) to an actual integer, but in respect of the significance of the bytes.
Also:
[Pointer to symbol table] and [Number of Symbols] seem to always be 0. I'm guessing this is due to the fact the binary is stripped of symbols, but I'm not sure since I am more an expert on Linux Binary Analysis. Is my asumption correct?
I really hope that this helps you. From what I understood so far this will grab the bytes that are within the start to end range and will place them in an integer:
// here I am converting the chars from hex to int
int getBitPattern(char ch)
{
if (ch >= 48 && ch <= 57)
{
return ch - '0';
}
else if (ch >= 65 && ch <= 70)
{
return ch - 55;
}
else
{
// this is in case of invalid input
return -1;
}
}
int getValue(const char* memory, int start, int end)
{
if (end <= start)
return 0;
unsigned int retVal = 0;
//now just add up array fields
for (int i = end, j = 0; i >= start; i--, ++j)
{
fprintf(stdout, "\n%02hhx", memory[i]);
// bitshift in order to insert the next set of 4 bits into their correct spot
retVal |= (getBitPattern(memory[i]) << (4*j));
}
fprintf(stdout, "\n\n\n%d", retVal);
return retVal;
}
boyanhristov96 helped a lot by pointing out the usage of the OR operator instead of AND and it was his / her effort that lead to this solution
A cast to (unsigned char) also had to be made before shifting.
If not, the variable will simply be shifted over it's maximum positive range,resulting in the value
0xFFFFE000 (4294959104)
instead of the desired 0x0000E000 (57344)
We have to left-shift by 8, because we want to shift 2 16bit values at once, like in
0x00FF00 << 8 ; // after operation is 0xFF0000
The final function also uses an OR, here is it:
//now with or operation and cast
int getValue(const char* memory, int start, int end)
{
if (end <= start)
return 0;
unsigned int retVal = 0;
//now just add up array fields
for (int i = end, j = end-start; i >= start; i--, --j)
{
fprintf(stdout, "\n%02hhx", memory[i]);
retVal |= ((unsigned char)(memory[i]) << (8 * j));
}
fprintf(stdout, "\n\n\n%u", retVal);
return retVal;
}
Many thanks for helping
EDIT 16.12.2019:
Returning back here for updated version of function;
It was necassary to rewrite it for 2 reasons:
1) The offset to PE-Header depends on the target binary, so we have to get this value first (at location 0x3c). Then, use a pointer to move from value to value from there.
2) The calculations where shambled, I corrected them, now it should work as intended. The second parameter is the byte-length, f.e. DWORD - 4 byte
Here you go:
//because file shambles
int getValuePNTR(const char* memory, int &start, int size)
{
DWORD retVal = 0;
//now just add up array fields
for (int i = start + size-1,j = size-1; j >= 0; --j ,i--)
{
fprintf(stdout, "\ncycle: %d, memory: [%x]", j, memory[i]);
if ((unsigned char)memory[i] == 00 && j > 0)
retVal <<= 8;
else
retVal |= ((unsigned char)(memory[i]) << (8 * j));
//else
//retVal |= ((unsigned char)(memory[i]));
}
//get the next field after this one
start += size;
return retVal;
}
The code that I did was for solving the following problem. However, the logic of the code is wrong and I as a good newbie cannot figure what is wrong.
After I compile the result of 'sum' is always 0, if I change the initialization of 'sum' for a whatever number, that whatever number is what appear as answer of 'sum'.
If we list all the natural numbers below 10 that are multiples of 3 or 5, we get 3, 5, 6 and 9. The sum of these multiples is 23.
Find the sum of all the multiples of 3 or 5 below 1000.
#include <iostream>
using std::cout;
using std::endl;
int main()
{
long sum = 0;
for( long i; i < 1000; ++i )
{
if (( i % 3 == 0 ) || ( i % 5 == 0 ))
{
sum = sum + i;
}
}
cout << "The sum is: " << sum << endl;
return 0;
}
You need to initialize i in your loop:
for (long i = 0; i < 1000; ++i )
As it is, i is probably some random number greater than 0 at the top of the loop, and the result is that the loop is never executed.
You need to initialize i to zero otherwise i's value will be whatever happens to be in memory. In this case it's > 1000.
for (long i = 0; i < 1000; ++i)
Also, a nice trick I learned. Use ii as your index variable. It's much easier to find ii than just i in your code.
You forgot to set i=O in your loop so the loop won't iterate.
All answers above are correct - you need to set your i to 0. What you might be interested in is that accessing uninitialized variable is an "undefined behaviour" (UB) and modern compilers are actually pretty good in finding the UBs and using them to optimize the code. For example, GCC 5.2 with -O2 (optimizations enabled) will generate same assembly for your code and for one without the loop at all regardless of what might happen to be in the memory at the address of i.
Try putting this code to (which is your code with additional #if for convenience) this online disassembler
#include <iostream>
using std::cout;
using std::endl;
int main()
{
long sum = 0;
#if 1
for (long i; i < 1000; ++i)
{
if ((i % 3 == 0) || (i % 5 == 0))
{
sum = sum + i;
}
}
#endif
cout << "The sum is: " << sum << endl;
return 0;
}
add the -O2 flag to compiler options on top right and try changing #if 1 to #if 0 and observe that the disassembly is the same meaning that the compiler cut out the loop completely.
There are two loops below. The first one works well while the second one is an infinite loop. Why?
for (unsigned int i=0; i<3; ++i)
{
std::cout << "i= " << i << std::endl; // this gives proper result
}
for (unsigned int i=3; i>=0; --i)
{
std::cout << "i= " << i << std::endl; // infinite loop
}
An unsigned int can never be less than 0. That's what makes it unsigned. If you turn on some warning flags, your compiler should tell you about your problem: i >= 0 is always true for an unsigned value.
Clang, for example, required no special flags at all to warn:
example.cpp:5:29: warning: comparison of unsigned expression >= 0 is always true
[-Wtautological-compare]
for (unsigned int i=3; i>=0; --i)
~^ ~
1 warning generated.
GCC required -Wextra:
example.cpp: In function ‘int main()’:
example.cpp:5: warning: comparison of unsigned expression >= 0 is always true
unsigned int cannot be less than zero (which is what loop's condition is checking). When i in your second loop is decremented from 0, it wraps around to UINT_MAX and the loop goes on.
The other answers (so far) are all correct; since i is unsigned, i >= 0 is always true, and so you have an infinite loop.
But that doesn't tell you how to fix it. If you want to iterate over an unsigned range from, say, 3 down to 0, there doesn't seem to be a straightforward way to do it. Other than changing the type of i or the direction of the range (and there may be reasons you can't do that), you could do this:
for (unsigned int i=3; ; --i)
{
std::cout << "i= " << i << std::endl;
if (i == 0) break;
}
It's not as clean as a simple for loop with no break but it does the job.
In addition to Keith Thompson's answer, there is another way to write it that doesn't require a break inside the loop:
for (unsigned int i = 3; i--; ) {
std::cout << "i= " << i << std::endl;
}
Notice how i-- acts both as the termination condition and as the afterthough, all in one. The use of the postfix decrement operator is important because it guarantees you're actually executing the loop 3 times, starting at 2 on the first iteration and ending at 0, included.
The minimum value for unsigned int i is 0; anything else would be negative and require a sign bit which is specifically what an unsigned int won't have.
So i >= 0 will always evaluate to true.
In your second loop ,the condition to stop the loop is that i must be less than 0. The range of unsigned int is 0 to 65535. so, here unsigned int i can't be less than zero. So, your condition is always true as a result the loop become infinite. Using a signed int can solve the problem.
I am making a program that adds two binary numbers (up to 31 digits) together and outputs the sum in binary.
I have every thing working great but I need to remove the leading zeros off the solution.
This is what my output is:
char c[32];
int carry = 0;
if(carry == '1')
{
cout << carry;
}
for(i = 0; i < 32; i++)
{
cout << c[i];
}
I tried this but it didn't work:
char c[32];
int carry = 0;
bool flag = false;
if(carry == '1')
{
cout << carry;
}
for(i=0; i<32; i++)
{
if(c[i] != 0)
{
flag = true;
if(flag)
{
for(i = 0; i < 32; i++)
{
cout << c[i];
}
}
}
}
Any ideas or suggestions would be appreciated.
EDIT: Thank you everyone for your input, I got it to work!
You should not have that inner loop (inside if(flag)). It interferes with the i processing of the outer loop.
All you want to do at that point is to output the character if the flag is set.
And on top of that, the printing of the bits should be outside the detection of the first bit.
The following pseudo-code shows how I'd approach this:
set printing to false
if carry is 1:
output '1:'
for each bit position i:
if c[i] is 1:
set printing to true
if printing:
output c[i]
if not printing:
output 0
The first block of code may need to be changed to accurately output the number with carry. For example, if you ended up with the value 2 and a carry, you would want either of:
1:10 (or some other separator)
100000000000000000000000000000010 (33 digits)
Simply outputting 110 with no indication that the leftmost bit was a carry could either be:
2 with carry; or
6 without carry
The last block ensures you have some output for the value 0 which would otherwise print nothing since there were no 1 bits.
I'll leave it up to you whether you should output a separator between carry and value (and leave that line commented out) or use carry to force printing to true initially. The two options would be respectively:
if carry is 1:
output '1 '
and:
if carry is 1:
output 1
set printing to true
And, since you've done the conversion to C++ in a comment, that should be okay. You state that it doesn't work, but I typed in your code and it worked fine, outputting 10:
#include <iostream>
int main(void)
{
int i;
int carry = 0;
int c[] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0};
bool print = false;
// This is the code you gave in the comment, slightly modified.
// vvvvvv
if(carry == 1) {
std::cout << carry << ":";
}
for (i = 0; i < 32; i++) {
if (c[i] == 1) {
print = true;
}
if (print) {
std::cout << c[i];
}
}
// ^^^^^^
std::cout << std::endl;
return 0;
}
const char * begin = std::find(c, c+32, '1');
size_t len = c - begin + 32;
std::cout.write(begin, len);
Use two fors over the same index. The first for iterates while == 0, the second one prints starting from where the first one left off.