Different behaviour of static_cast - c++

I am trying to convert a uint64_t to a uint8_t. I know this makes no sense normaly but since the JSON Library converts all numeric values to a uint64_t or int64_t I have to convert it back. I am always sure I do not receive values which will not fit into the uint8_t.
Now when I compile and run the following code on OSx everything works as expected. But as soon as I move to a Raspberry Pi 2 the code no longer works. The value is 0.
Can anybody explain why this is happening? And does somebody has a better solution?
#include <iostream>
#include "json.h"
using JSON = nlohmann::json;
typedef struct {
uint8_t boardId;
uint8_t commandGroupId;
uint8_t commandId;
} ExternalMessageType;
int main(int argc, const char * argv[])
{
JSON x;
ExternalMessageType y;
x["board-id"] = 1;
x["command-group-id"] = 1;
x["command-id"] = 11;
y.boardId = static_cast<uint8_t>(x["board-id"]);
y.commandGroupId = static_cast<uint8_t>(x["command-group-id"]);
y.commandId = static_cast<uint8_t>(x["command-id"]);
std::cout << "Board: " << (int)y.boardId << std::endl;
std::cout << "Group: " << (int)y.commandGroupId << std::endl;
std::cout << "Command: " << (int)y.commandId << std::endl;
if (y.commandGroupId == 1) {
std::cout << "Command Group is ok." << std::endl;
switch (y.commandId) {
case 11: {
std::cout << "Speed Message" << std::endl;
} break;
}
} else {
std::cout << "Command Group is not ok." << std::endl;
}
return 0;
}

Related

Integer overflow and std::stoi

if x > INT_MAX or if x > INT_MIN the function will return 0... or that's what i'm trying to do :)
in my test case i pass in a value that is INT_MAX + 1... 2147483648 ... to introduce integer overflow to see how the program handles it.
i step through... my IDE debugger says that the value immediately goes to -2147483648 upon overflow and for some reason the program executes beyond both of these statements:
if (x > INT_MAX)
if (x < INT_MIN)
and keeps crashes at int revInt = std::stoi(strNum);
saying out of range
Must be something simple, but it's got me stumped. Why isn't the program returning before it ever gets to that std::stoi() given x > INT_MAX? Any help appreciated. Thanks! Full listing of function and test bed below: (sorry having trouble with the code insertion formatting..)
#include <iostream>
#include <algorithm>
#include <string> //using namespace std;
class Solution {
public: int reverse(int x)
{
// check special cases for int and set flags:
// is x > max int, need to return 0 now
if(x > INT_MAX)
return 0;
// is x < min int, need to return 0 now
if(x < INT_MIN)
return 0;
// is x < 0, need negative sign handled at end
// does x end with 0, need to not start new int with 0 if it's ploy numeric and the functions used handle that for us
// do conversion, reversal, output:
// convert int to string
std::string strNum = std::to_string(x);
// reverse string
std::reverse(strNum.begin(), strNum.end());
// convert reversed string to int
int revInt = std::stoi(strNum);
// multiply by -1 if x was negative
if (x < 0)
revInt = revInt * -1;
// output reversed integer
return revInt;
}
};
Main:
#include <iostream>
int main(int argc, const char * argv[]) {
// test cases
// instance Solution and call it's method
Solution sol;
int answer = sol.reverse(0); // 0
std::cout << "in " << 0 << ", out " << answer << "\n";
answer = sol.reverse(-1); // -1
std::cout << "in " << -1 << ", out " << answer << "\n";
answer = sol.reverse(10); // 1
std::cout << "in " << 10 << ", out " << answer << "\n";
answer = sol.reverse(12); // 21
std::cout << "in " << 12 << ", out " << answer << "\n";
answer = sol.reverse(100); // 1
std::cout << "in " << 100 << ", out " << answer << "\n";
answer = sol.reverse(123); // 321
std::cout << "in " << 123 << ", out " << answer << "\n";
answer = sol.reverse(-123); // -321
std::cout << "in " << -123 << ", out " << answer << "\n";
answer = sol.reverse(1024); // 4201
std::cout << "in " << 1024 << ", out " << answer << "\n";
answer = sol.reverse(-1024); // -4201
std::cout << "in " << -1024 << ", out " << answer << "\n";
answer = sol.reverse(2147483648); // 0
std::cout << "in " << 2147483648 << ", out " << answer << "\n";
answer = sol.reverse(-2147483648); // 0
std::cout << "in " << -2147483648 << ", out " << answer << "\n";
return 0;
}
Any test like (x > INT_MAX) with x being of type int will never evaluate to true, since the value of x cannot exceed INT_MAX.
Anyway, even if 2147483647 would be a valid range, its reverse 7463847412 is not.
So I think its better to let stoi "try" to convert the values and "catch" any out_of_range-exception`. The following code illustrates this approach:
int convert() {
const char* num = "12345678890123424542";
try {
int x = std::stoi(num);
return x;
} catch (std::out_of_range &e) {
cout << "invalid." << endl;
return 0;
}
}

Converting 4bytes to signed and unsigned ints

I want to convert a four-byte string to either int32 or uint32 in c++.
This answer helped me to write the following code:
#include <string>
#include <iostream>
#include <stdint.h>
int main()
{
std::string a("\xaa\x00\x00\xaa", 4);
int u = *(int *) a.c_str();
int v = *(unsigned int *) a.c_str();
int x = *(int32_t *) a.c_str();
int y = *(uint32_t *) a.c_str();
std::cout << a << std::endl;
std::cout << "int: " << u << std::endl;
std::cout << "uint: " << v << std::endl;
std::cout << "int32_t: " << x << std::endl;
std::cout << "uint32_t: " << y << std::endl;
return 0;
}
However the outputs are all the same, where the int (or int32_t) values are correct, but the unsigned ones are wrong. Why does not the unsigned conversions work?
// output
int: -1442840406
uint: -1442840406
int32_t: -1442840406
uint32_t: -1442840406
Pythons struct.unpack, gives the right conversion
In [1]: import struct
In [2]: struct.unpack("<i", b"\xaa\x00\x00\xaa")
Out[2]: (-1442840406,)
In [3]: struct.unpack("<I", b"\xaa\x00\x00\xaa")
Out[3]: (2852126890,)
I would also like a similar solution to work for int16 and uint16, but first things first, since I guess an extension would be trivial if I manage to solve this problem.
You need to store the unsigned values in an unsigned variables and it will work:
#include <string>
#include <iostream>
#include <stdint.h>
int main()
{
std::string a("\xaa\x00\x00\xaa", 4);
int u = *(int *) a.c_str();
unsigned int v = *(unsigned int *) a.c_str();
int32_t x = *(int32_t *) a.c_str();
uint32_t y = *(uint32_t *) a.c_str();
std::cout << a << std::endl;
std::cout << "int: " << u << std::endl;
std::cout << "uint: " << v << std::endl;
std::cout << "int32_t: " << x << std::endl;
std::cout << "uint32_t: " << y << std::endl;
return 0;
}
When you cast the value to unsigned and then store it in a signed variable, the compiler plays along. Later, when you print the signed variable, the compiler generates code to print a signed variable output.

Test an integer value to determine if it is odd or even in C++

I have to write a program to test an integer value to determine if it is odd or even, and make sure my output is clear and complete. In other words, I have to write the output like "the value 4 is an even integer". I was also hinted that I have to check the value using the remainder modulo.
The issue I have is with the scanf() function. I get a syntax error:
'%=' expected a ')'
How do I fix this?
#include "stdafx.h"
#include "iostream"
#include "string"
using namespace std;
int main()
{
int number = 0;
cout << "enter an integer ";
int scanf(%=2 , &number);
if (number == 0)
cout << "the value" << number << "is even";
else
cout << "the value" << number << "is odd";
return 0;
}
You are using scanf() incorrectly (read the scanf() documentation on cppreference.com). The first parameter expects a null-terminated string containing the format to scan, but you are not passing in anything that even resembles a string. What you are passing in is not valid string syntax, per the C++ language standard. That is why you are getting a syntax error.
You need to change this line:
int scanf(%=2 , &number);
To this instead:
scanf("%d", &number);
Though, in C++ you really should be using std::cin instead for input (you are already using std::cout for output):
std::cin >> number;
Try this:
#include "stdafx.h"
#include <iostream>
#include <string>
using namespace std;
int main()
{
int number = 0;
cout << "enter an integer ";
if (cin >> number)
{
if ((number % 2) == 0)
cout << "the value " << number << " is even";
else
cout << "the value " << number << " is odd";
}
else
cout << "the value is invalid";
return 0;
}
I know this question is a little dated, however, if you are able to use modern C++ features. You can write a constexpr helper function such as this:
#include <cstdint>
constexpr bool isEven(uint32_t value) {
return ((value%2) == 0);
}
Then in your main function, you can traverse through a loop of N integers and output your display such as:
#include <iostream>
#include <iomanip>
int main() {
for ( int i = 0; i < 100; i++ ) {
std::cout << std::setw(3) << std::setfill('0') << i << " is "
<< (isEven(i) ? "even" : "odd") << '\n';
}
return 0;
}
It's literally that simple. Here's another nice feature of using the constexpr helper function... You can also format your output as such:
int main() {
for ( int i = 0; i < 100; i++ ) {
std::cout << std::setw(3) << std::setfill('0') << i << ": "
<< std::boolalpha << isEven(i) << '\n';
}
return true;
}
If you are looking for something that is more efficient than using the modulo operator you can bitwise & with the least significant digit... The code above would then become:
#include <cstdint>
constexpr bool isOdd(uint32_t value) {
return (value&1);
}
And using it would be very similar as above, just make sure you reverse the wording in your output to match that from the function being used...
#include <iostream>
#include <iomanip>
int main() {
for ( int i = 0; i < 100; i++ ) {
std::cout << std::setw(3) << std::setfill('0') << i << " is "
<< (isOdd(i) ? "odd" : "even") << '\n';
}
return 0;
}
Again you can use the std::boolalpha manipulator to get this kind of output:
int main() {
for ( int i = 0; i < 100; i++ ) {
std::cout << std::setw(3) << std::setfill('0') << i << ": "
<< std::boolalpha << isOdd(i) << '\n';
}
return true;
}

INTtoCHAR function couts wrong value

here is what my function looks like:
signed char INTtoCHAR(int INT)
{
signed char CHAR = (signed char)INT;
return CHAR;
}
int CHARtoINT(signed char CHAR)
{
int INT = (int)CHAR;
return INT;
}
It works properly that it assigns the int value to the char, but when I want to cout that char then it gives me some weired signs. It compiles without errors.
My testing code is:
int main()
{
int x = 5;
signed char after;
char compare = '5';
after = INTtoCHAR(5);
if(after == 5)
{
std::cout << "after:" << after << "/ compare: " << compare << std::endl;
}
return 0;
}
After is indeed 5 but it doesn't print 5. Any ideas?
Adding to the above answer using the unary operator +, there is another way as well: typecasting.
std::cout << "after:" << (int)after << "/ compare: " << compare << std::endl;
Correct output
Use +after while printing, instead of after. This will promote after to a type printable as a number, regardless of type.
So change this:
std::cout << "after:" << after << ", compare: " << compare << std::endl;
to this:
std::cout << "after:" << +after << ", compare: " << compare << std::endl;
For more, see this answer.

make some crc check code, loop for multiple file (c++)

so i have this code for checking crc file named map.spak and compare the result with my specified crc result which stored in variable "compare"
int main(int iArg, char *sArg[])
{
char sSourceFile[MAX_PATH];
memset(sSourceFile, 0, sizeof(sSourceFile));
CCRC32 crc32;
crc32.Initialize(); //Only have to do this once.
unsigned int iCRC = 0;
strcpy(sSourceFile, "map.spak");
int compare = 399857339;
ifstream checkfile(sSourceFile);
if (checkfile){
cout << "Checking file " << sSourceFile << "..." << endl;
crc32.FileCRC(sSourceFile, &iCRC);
if(iCRC == compare){
cout << "File " << sSourceFile << " complete!\nCRC Result: " << iCRC << endl;
}else{
cout << "File " << sSourceFile << " incomplete!\nCRC Result: " << iCRC << endl;
}
}else{
cout << "File not found!" << endl;
}
system("pause");
return 0;
}
and now i want to make this code for multiple file
let's say the file name list stored in filelist.txt
the filelist.txt structure:
id|filename|specified crc
1|map.spak|399857339
2|monster.spak|274394072
how to make the crc check, loop for each file name
i'm not really good at c++ i only know some algorithm because i know PHP
c++ is too complicated
this is the full source included CRC source Source Code
or pastebin
TestApp.cpp link
I made several changes to your code. I removed guard headers since we use it only in header files. Old-fasioned memset has been replaced by operation on strings. I suspect that you need to pass char* to CCRC32 object hence sSourceFile is still const char*. I compiled code except parts with CCRC32.
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include "../CCRC32.H"
int main(int iArg, char *sArg[])
{
std::vector<std::string> filenames;
// TODO - populate filesnames (paths?)
CCRC32 crc32;
crc32.Initialize(); //Only have to do this once.
for (unsigned int i = 0; i < filenames.size(); i++) {
const char* sSourceFile = filenames[i].c_str();
unsigned int iCRC = 0;
int compare = 399857339; // TODO - you need to change this since you are checking several files
std::ifstream checkfile(sSourceFile);
if (checkfile) {
std::cout << "Checking file " << sSourceFile << "..." << std::endl;
crc32.FileCRC(sSourceFile, &iCRC);
if(iCRC == compare){
std::cout << "File " << sSourceFile << " complete!\nCRC Result: " << iCRC << std::endl;
} else {
std::cout << "File " << sSourceFile << " incomplete!\nCRC Result: " << iCRC << std::endl;
}
} else {
std::cout << "File tidak ditemukan!" << std::endl;
}
}
return 0;
}