I'm trying to understand why I keep getting an unexpected binary result. For example, if I were to write
8
I will get a result of
00111000
and not
00001000
I'm not trying to manipulate to get another result, I'm trying to see what the actual data is for my input and understand why it's giving that input.
I'm using C++ in visual studio with a platform of Win32.
This is my code:
#include <stdio.h>
#include <bitset>
#include <iostream>
using namespace std;
int main() {
char cl;
cout << "The minimum value of char is " << CHAR_MIN << endl;
cout << "The maximum value of char is " << CHAR_MAX << endl;
cout << "The storage size in byte(s) of a char is " << sizeof(cl) << endl;
cout << "Input hexadecimal number in the data type of char for example a" << endl;
scanf_s("%c", &cl, sizeof(cl));
bitset < 8 * sizeof(cl)>charBits(cl);
cout << "The converted binary value is " << charBits << endl;
printf("The converted decimal value is% i \n", cl);
}
The value being input is an ASCII character, and you should convert that value to its corresponding number before printing. in ASCII, the letters 'a'-'f' have the range 97-102, 'A'-'F' have the range 65-70, and '0'-'9' have the range 48-57. So after getting your input, test its ASCII value with if's and subtract accordingly like this:
// Subtracting 87 converts 'a' to 10 and 'f' to 15, the numerical representations
// of those hexadecimal values, which are then converted to binary by bitset.
if (cl >= 97 && cl <= 102)
cl -= 87;
// Subtract 10 less again for the same reason above.
else if (cl >= 65 && cl <= 70)
cl -= 55;
// Subtracting 48 from '0' converts it to the number 0 in memory,
// and subtracting 48 from '9' converts it to the number 9.
else if (cl >= 48 && cl <= 57)
cl -= 48;
You'll notice that this breaks the decimal printing, so you should convert the number to decimal for printing like this cout << static_cast<int>(cl) << endl;.
Related
I am trying to create a C++ function with the following behavior:
Input: "A4B5C3" ; Output: "AAAABBBBBCCC"
Input: "R1T3" ; Output: "RTTT"
And so on.
I have written the following function:
#include <iostream>
#include <string>
#include <vector>
using namespace std;
string foo(string s){
int count = 0;
string t = "";
char letter = 'a';
for (string::iterator it=s.begin(); it<s.end(); it++){
if(count%2==0)
{
cout << "count: "<<count << " *it: "<< *it << endl;
letter = *it;
}
else
{
cout <<"count: "<< count << " *it: " << *it << " letter: " << letter << endl;
int j = 0;
while (j<*it)
{
t.push_back(letter);
j++;
}
}
count++;
}
cout << endl<<endl;
return(t);
}
However , on calling foo("A1B4C2D8"), I get this output:
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD
For some reason, my while loop seems to be running 48 more times than I would like it to...
There are no character encodings where the integer 1 is equal to the character '1' (for example).
In the ASCII encoding the character '1' is equal to the integer 49.
That means the condition j<*it is flawed.
The C++ specification requires that all digits are encoded consecutively, so '0' will always come before '1', and '1' will always come before '2', and so on. With that knowledge, together with knowing that char is a simple integer type, you can always subtract '0' from any digit character to get its integer value.
For example '2' - '0' == 2.
To solve your problem the condition should be j < (*it - '0').
Here :
while (j< *it)
you are comparing an integer (int) with a character (char). The character '0' does not equal 0, but as digits have consecutive representations you can subtract '0' from the character to get the corresponding integer:
while (j< *it - '0')
Issue is in the line
int j = 0;
while (j<*it)
...
You are comparing the int value with the chacter.
The character '0' in ASCII encoding has the hexadecimal integer value 0x30 and the decimal integer value 48. The character '1' has the hexadecimal integer value 0x31 and the decimal integer value 49. And so on till '9' that has the hexadecimal integer value 0x39 and the decimal integer value 57.
Even not knowing those ASCII codes the shortest fix is changing int j = 0; to int j = '0'; or char j = '0';. Then the loop while (j < *it) will iterate correctly.
#include <iostream>
using std::cout;
using std::endl;
int main(void) {
std::string fx = "6x^2+6x+4";
int part1 = fx[0] * fx[3];
cout << fx[0] << endl;
cout << fx[3] << endl;
cout << part1;
}
So I have this string and fx[0] and fx[3] are obviously integers: when I print them to the console they print out just fine; however, part1 (their multiplication) equals some totally unrelated number? Can anyone help?
Here is the output:
6
2
2700
Your fx[0] and fx[3] variables are of type char (which is an integer type in C++). However, the actual values in those two elements of your fx string will be representations of the digits, 6 and 2, not the numerical values of those digits.
Very often, those representations will be ASCII codes (but that's not required); however, what is required is that the representations of the digits 0 thru 9 have contiguous, sequential values. Thus, by subtracting the value of the digit, 0, we can convert to their numerical representations.
In your case, the following line will do the conversion:
int part1 = (fx[0]-'0') * (fx[3]-'0');
The reason why you see the correct values when printing fx[0] and fx[3] is because the version of the cout << operator that takes a char argument is designed to print the represented character (not its 'ASCII' code); however, the cout << operator for an int type (like your part1) will print the actual value represented internally. (Try changing one of your lines to cout << (int)fx[0] << endl; to see the difference.)
P.S. Don't forget the #include <string> header – some implementations do that implicity inside the <iostream> header, but don't rely on that!
well, first of all, string::operator[] returns a char... then, a char can be casted to an int, and the cast works checking the ID in the ASCII table (in your case)
In ASCII, the ID of "6" and "2" are respectively 54 and 52 (you can check it here for example)... so your program is taking the two char, casting them to int, and multiplying them (54 * 50 = 2700)
If you need to interpret those as the integer value they represent, you can check this answer:
int val = '6' - '0'; // val == 6
Characters are values representing glyphs from some representation, usually the ASCII table. The numeric value of a character is not the same as the glyph that is printed on the screen. To convert a numeric-looking char to an actual "0-based" numeric value, subtract '0' from your char value.
(fx[3]-'0']) will be the numeric value of character represented at position 3.
You are multiplying character types. so the characters '6' and '2' will converted to its integer values 54 and 50 respectively then multiplication is applied. This works based on C++ type conversion rule. Then you will get 2,700. Try the modified sample code
#include <iostream>
using std::cout;
using std::endl;
int main(void) {
std::string fx = "6x^2+6x+4";
int part1 = fx[0] * fx[3];
cout << fx[0] << endl;
cout << fx[3] << endl;
cout << part1;
cout << std::endl;
cout << (int)fx[0] << " " << (int)fx[3] << std::endl;
}
And the results
6
2
2700
54 50
The code asks for a positive integer, than the first output shows the corresponding ASCII code, the others are made to convert the integer to decimal, octal and hexadecimal equivalents. I understand the logic of the code, but I don't understand the assignment made on line 10 c=code than the assignment made on line 12 code=c. What happens on background when we 'swap' the two variables.
#include <iostream>
#include <iomanip>
using namespace std;
int main(){
unsigned char c = 0;
unsigned int code = 0;
cout << "\nPlease enter a decimal character code: ";
cin >> code;
c = code;
cout << "\nThe corresponding character: " << c << endl;
code = c;
cout << "\nCharacter codes"
<< "\n decimal: " << setw(3) << dec << code
<< "\n octal: " << setw(3) << oct << code
<< "\n hexadecimal: " << setw(3) << hex << code
<< endl;
return 0;
}
I could be wrong here so maybe someone else can weigh in, but I believe I know the answer.
If you assign a character a number, when you print that char it prints the corresponding character. Since c is of type char, the line c = code converts the integer entered into a character. You can test this yourself by assigning any int to a char variable and printing it out.
The second assignment, code = c, seems to be completely unnecessary.
That's not a swap. c is assigned the same value as code and then this value is assigned back to code. The original value of code is lost.
We can see this because unsigned char c is (usually) much smaller than unsigned int code and some information may be lost stuffing the value in code into c.
For example, code = 257. After c = code; code is still 257 and c, assuming an 8 bit char will be 1. After code = c;, both code and c will be 1. 257 has been lost.
Why is this being done? when given a char, operator<< will print out the character encoded, completely ignoring the request to print as hex, dec, or oct. So
<< "\n decimal: " << setw(3) << dec << c
is wasted. Given an int << will respect the modifiers, but if c and code have different values, you're comparing apples and Sasquatches.
I have an array ( char location[2]; ) This needs to receive two values from the user. The first is a letter the other a number, in that order. This is used to select a location in a 9 x 9 grid.
The grid appears
A B C D E F G H I
1
2
3
4
5
6
7
8
9
When I try to store the second value as an int, The method I would think would work is being set to -48.
int row = location[1] - 48;
48 is the ASCII value of '1'. Shouldn't this have created an int with the value of one less than whatever number was input by the user? '2' (aka 49) - 48 = 1? It always comes out as -48 no matter what the input is.
My full function:
#include <iostream>
using namespace std;
void getLocation(int &column, int &row)
{
int row = 0;
int column = 0;
char location[2];
cout << "location: ";
cin.getline(location,2);
cin.ignore();
cin.clear();
switch (location[0])
{
case 'A':
cout << "case A\n";
column = 0;
break;
case 'B':
cout << "case B\n";
column = 1;
break;
case 'C':
cout << "case C\n";
column = 1;
break;
}
row = location[1] - 48;
cout << "column: "
<< column
<< " row: "
<< row
<< "\n";
}
location[1] - 48 will always be -48 if positive-length string is given because terminating null-character will be stored there. Allocate enough length to store the input. You are using C++, so using std::string is better to store strings than using arrays of char.
cin.getline(location,2) does not behave in the way you expect.
It writes a nul-terminated string to location i.e. location[0] is read from cin, and location[1] receives a character with value of 0 (numeric zero, not '0').
0 - 48 always produces a result of -48 as an int.
Note, also, that '1' is not guaranteed to have a value of 48. '0' does in ASCII and compatible character sets. Other character sets will give different values.
You would be better off using std::string - that eliminates the need to worry about arrays of char and nul termination.
The size of the stream for cin.getline needs space for a null terminator. Therefore, increase the size of the stream buffer and terminate input on the carriage return:
cin.getline(location, 3, '\r');
I am trying to work with the modbus protocol and right now i am calculating the LRC of the messages. I made a function which worked with no issue whatever i was putting into and then i noticed that id did not worked with one input and i can't find a logical explanation on why this don't work.
The function is :
void LRCstring(std::string example)
{
std::stringstream ss;
std::string hex =example.substr(1, example.length()-5);
std::vector<unsigned char> hexCh;
unsigned int buffer;
int offset = 0;
while (offset < hex.length()) {
ss.clear();
ss << std::hex << hex.substr(offset, 2);
ss >> buffer;
hexCh.push_back(static_cast<unsigned char>(buffer));
offset += 2;
}
unsigned char LRC=0x00;
int i;
for (i=0;i<hexCh.size();i++)
{
LRC=LRC+hexCh[i];
}
LRC = 0xFF-LRC; // 1 complement
LRC = LRC+1; // 2 complement
//std::string s = std::to_string(LRC);
//int deci = atoi(s.c_str());
int deci = LRC;
int reste=deci % 16;
std::string temp;
int partiehexa=(deci-reste)/16;
std::string temp2;
std::cout << "deci : " << deci << std::endl;
std::cout << "reste : " << reste << std::endl;
std::cout << "partiehexa : " << partiehexa << std::endl;
std::stringstream ss2;
ss2 << reste;
ss2 >> temp;
ss2 << partiehexa;
ss2 >> temp2;
if (partiehexa<10) {LRCascii+=temp2;}
if (partiehexa==10) {LRCascii+='A';}
if (partiehexa==11) {LRCascii+='B';}
if (partiehexa==12) {LRCascii+='C';}
if (partiehexa==13) {LRCascii+='D';}
if (partiehexa==14) {LRCascii+='E';}
if (partiehexa==15) {LRCascii+='F';}
if (reste<10) {LRCascii+=temp;}
if (reste==10) {LRCascii+='A';}
if (reste==11) {LRCascii+='B';}
if (reste==12) {LRCascii+='C';}
if (reste==13) {LRCascii+='D';}
if (reste==14) {LRCascii+='E';}
if (reste==15) {LRCascii+='F';}
std::cout << "LRC : " << LRCascii << std::endl;
return;
}
Examples on what is the input and the result when it is working :
input > ":040100130013??\r\n"
The cout display "LRC : D5"
input > ":0401CD6B05??\r\n"
The cout display "LRC : BE"
D5 and BE are the right results.
I tried with other inputs and had no problem until this :
input > ":0403006B0003??\r\n"
The cout display "LRC : B"
input > ":040306022B00000064??\r\n"
The cout display "LRC : 2"
It should be 8B and not simply B and it should be 62 and not simply 2.
We can see that the last part of the LRC is good but the other part is ignored. What is even stranger is that in this case the cout of "partiehexa" is showing "8" and "6", it is not like this int was empty. I fail to understand why this is happening in this case.
To me it seems to a C code. But I did quickly analyze your code. I Think the problem lies where your are calculating the
(partiehexa < 10)
The LRCascii only gets assigned while looping through the "reste" part of the code. In the "partiehexa" part of the code it do not get assigned to anything.
Suggestion: Change the code to the following and your code will work
if (partiehexa<10)
{
std::stringstream ss3;
ss3 << partiehexa;
ss3 >> temp2;
LRCascii += temp2;
}
Best solution would be to rewrite the code in proper optimized way.
To calculate the LRC
Add up all the data bytes in the message (before converting to ASCII and without the initial colon and final CR/LF).
Throw away any bits that carry over 8 bits.
Make the result negative (by twos compliment) to get the LRC byte.
In your example, checksum can be calculated mathematically as below:
String: 040306022B00000064
Checksum: 62
Byte# 1 Hex Value 04 Decimal Value 4
Byte# 2 Hex Value 03 Decimal Value 3
Byte# 3 Hex Value 06 Decimal Value 6
Byte# 4 Hex Value 02 Decimal Value 2
Byte# 5 Hex Value 2B Decimal Value 43
Byte# 6 Hex Value 00 Decimal Value 0
Byte# 7 Hex Value 00 Decimal Value 0
Byte# 8 Hex Value 00 Decimal Value 0
Byte# 9 Hex Value 64 Decimal Value 100
Total Hex Value 9E Decimal Value 158
LRC: Hex Value FFFFFFFF62 Decimal Value -158
So the single Hex LRC Byte in this example is 62.
Prashant..