If I want to compile the following code:
int x = 8;
int y = 17;
char final[2];
final[0] = (char) x;
final[1] = (char) y%10;
cout << final[0] << final[1] << endl;
It shows nothing. I don't know why? So how can I successfully convert it?
(char)8 is not '8', but the ASCII value 8 (the backspace character). To display the character 8 you can add it to '0':
int x = 8;
int y = 17;
char final[2];
final[0] = '0' + x;
final[1] = '0' + (y%10);
cout << final[0] << final[1] << endl;
As per your program you are printing char 8, and char 7.
They are not printable. In fact they are BELL and Backspace characters respectively.
Just run you program and redirect it to a file.
Then do an hexdump, you will see what is printed.
./a.out > /tmp/b
hd /tmp/b
00000000 08 07 0a |...|
00000003
What you need to understand is that in C++, chars are numbers, just like ints, only in a smaller range. When you cast the integer 8 to char, C++ thinks you want a char holding the number 8. If we look at our handy ASCII table, we can see that 8 is BS (backspace) and 7 is BEL (which sometimes rings a bell when you print it to a terminal). Neither of those are printable, which is why you aren't seeing anything.
If you just want to print the 87 to standard output, then this code will do that:
cout << x << (y%10) << endl;
If you really need to convert it chars first, then fear not, it can still be done. I'm not much of a C++ person, but this is the way to do it in C:
char final[2];
snprintf(final, sizeof final, "%d%d", x, y % 10);
(See snprintf(3))
This code treats the 2-char array as a string, and writes the two numbers you specified to it using a printf format string. Strings in C normally end with a NUL byte, and if you extended the array to three chars, the final char would be set to NUL. But because we told snprintf how long the string is, it won't write more chars than it can.
This should also work in C++.
Related
When i wrte this code :
using namespace std;
int main(){
char x[] = "γεια σας";
cout << x;
return 0;
}
I noticed that compiler gave me output which i excepted γεια σας Although the type of array is char, That is, it should just accept ASCII characters.
So why compiler didn't give error?
Here's some code showing what C++ really does:
#include <iostream>
#include <iomanip>
using namespace std;
int main(){
char x[] = "γεια σας";
cout << x << endl;
auto len = strlen(x);
cout << "Length (in bytes): " << len << endl;
for (int i = 0; i < len; i++)
cout << "0x" << setw(2) << hex << static_cast<int>(static_cast<unsigned char>(x[i])) << ' ';
cout << endl;
return 0;
}
The output is:
γεια σας
Length (in bytes): 15
0xce 0xb3 0xce 0xb5 0xce 0xb9 0xce 0xb1 0x20 0xcf 0x83 0xce 0xb1 0xcf 0x82
So the string takes up 15 bytes and is encoded as UTF-8. UTF-8 is a Unicode encoding using between 1 and 4 bytes per character (in the sense of the smallest unit you can select with the text cursor). UTF-8 can be saved in a char array. Even though it's called char, it basically corresponds to a byte and not what we typically think of as a character.
What you have got with 99.99% likelihood is Unicode code points stored in UTF-8 format. Each code point is turned into one to four chars.
Unicode in the ASCII range is turned into one ASCII byte from 0x00 to 0x7f. There are 2048 code points translated to two bytes with the binary pattern 110x xxxx 10yy yyyy, 65536 are translated to three code points 1110 xxxx 10yy yyyy 10zz zzzz, and the rest becomes four chars 1111 0xxx 10yy yyyy 10zz zzzz 10uu uuuu.
Most C and C++ string functions work just fine with UTF-8. An exception is strncpy or strncat which could create an incomplete code point. The old Interview problem “reverse the strings in a character” becomes more complicated because reversing the bytes inside a code point produces nonsense.
Although the type of array is char, That is, it should just accept ASCII characters.
You've assumed wrongly.
Unicode has several transformation formats. One popular such format is UTF-8. The code units of UTF-8 are 8 bits wide, as implied by the name. It is always possible to use char to represent the code units of UTF-8, because char is guaranteed to be at least 8 bits wide.
I am fairly new to C++ and i have some trouble in understanding character subtraction in c++.
I had this code intially
char x='2';
x-='0';
if(x) cout << "More than Zero" << endl;
This returned More than Zero as output so to know the value of x i tried this code.
char x='2';
x-='0';
if(x) cout << x << endl;
And i am getting null character(or new line) as output.
Any help is appreciated.
According to the C++ Standard (2.3 Character sets)
...In both the source and execution basic character sets, the value of
each character after 0 in the above list of decimal digits shall be
one greater than the value of the previous.
So the codes of adjacent digits in any character set differ by 1.
Thus in this code snippet
char x='2';
x-='0';
if(x) cout << x << endl;
the difference between '2' and '0' (the difference between codes that represent these characters; for example in ASCII these codes are 0x32 and 0x30 while in EBCDIC they are 0xF2 and 0xF0 correspondingly) is equal to 2.
You can check this for example the following way
if(x) cout << ( int )x << endl;
or
if(x) cout << static_cast<int>( x ) << endl;
If you just write
if(x) cout << x << endl;
then the operator << tries to output x as a printable character image of the value 2 because x is of type char.
In C/C++ characters are stored as 8-bit integers with ASCII encoding. So when you do x-='0'; you're subtracting the ASCII value of '0' which is 48 from the ASCII value of '2' which is 50. x is then equal to 2 which is a special control character stating STX (start of text), which is not printable.
If you want to perform arithmetic on characters it's better to subtract '0' from every character before any operation and adding '0' to the result. To avoid problems like running over the range of the 8bit value I'd suggest to cast them on ints or longs.
char x = '2';
int tempVal = x - '0';
/*
Some operations are performed here
*/
x = tempValue % 10 + '0';
// % 10 - in case it excedes the range reserved for numbers in ASCII
cout << x << endl;
It's much safer to perform these operations on larger value types, and subtracting the '0' character allows you to perform operations independent on the ASCII encoding like you'd do with casual integers. Then you add '0' to go back to the ASCII encoding, which alows you to print a number.
You are substracting 48 (ascii char '0') to the character 50 (ascii '2')
50 - 48 = 2
if (x) ' true
In C++, characters are all represented by an ASCII code (see http://www.asciitable.com/)
I guess that doing :
'2' - '0'
is like doing
50 - 48 = 2
According to the ASCII table, the ASCII code 2 stands for start of text, which is not displayed by cout.
Hope it helps.
So what your code is doing is the following:
x = '2', which represents 50 as a decimal value in the ASCII table.
then your are basically saying:
x = x - '0', where zero in the ASCII table is represented as 48 in decimal, which equates to x = 50 - 48 = 2.
Note that 2 != '2' . If you look up 2(decimal) in the ASCII table that will give you a STX (start of text). This is what your code is doing. So keep in mind that the subtraction is taking place on the decimal value of the char.
I cannot figure out why this result in undefined behavoiur or whatever its called?
char ch[10];
strcpy(ch, "street1-3");
char ch2 = ch[6];
cout << ch2 << endl;
int n = (int) ch2;
n = n * 12;
cout << n << endl;
that is cout first prints out position 6 of street1-3 that is "1".
Then when I am trying to typecast this char to an int the value becomes not what its expected to be, that is 12, instead 588.
output in the consolewindow
1
588
What I am doing wrong in the typecasting and how is it solved?
The character '1' doesn't have the ascii value of 1. So (int)'1' != (int)1.
If you look at an ASCII table, you'll see that '1' == 49, and coincidentally (or not...) 49*12 == 588.
There is 2 different behaviour for the operator << on stream with char and int. With char, you get the corresponding character, i.e. "1", wich has a ascii value of 49. So when you do int n = (int)ch2, n has a value of 49, then n * 12 is equal to 588 which is outputed as a value because n is a int.
AS ch2 = 1 , which is of type 'char' , when it is type cast into 'int' , it takes ASKII value of 1 which is 49 and assigns it to 'n' . And 49 * 12 is 588 which is output of your program .
(int)ch2 tells the compiler to interpret the char value in ch2 as an int. Since characters are stored by ascii value, ch2 contains 49, which is what the calculation uses.
Instead of (int)ch2 you should instead use int(ch2), which will perform the conversion you expect.
Oh, and you should always avoid c style casts in c++ where possible - c++ provides a number of safer casts that you should use instead (dynamic,static,etc).
My codes are like this:
int main(int argc, char *argv[])
{
char ca[] = {'0'};
cout << *ca << endl;
cout << *(ca+1) << endl;
cout << ca[1] << endl;
cout << (char)(0) << endl;
return 0;
}
The result is like this:
0
\210
\210
^#
From this thread, I knew that ^# is the same as \0 actually. However, the \210 seems not because when I use hexdump to view the result.
bash-3.2$ ./playground | hexdump -C
00000000 30 0a 88 0a 88 0a 00 0a |0.......|
00000008
It can be seen clearly that \210 is 88 instead of 00.
As I understood, ca+1 should point to a null terminator, which is \0. But why cout << *(ca+1) << endl; gives me \210 as the result?
Because you have to manually add the null terminator when declaring a character array. If you make it a string (such as in char myString[] = "hi"), then it will add a null terminator. But if you make it an array, with the braces, it will not.
As for the 0x88 byte, it just happened to be the next byte in RAM for whatever reason.
In any valid C program the string literals are always null terminated. Here you are trying to initialize the individual element of character array but just with list initialization syntax and not to a string literal. As this is static array allocated with in same function, you can even confirm this with help of sizeof operator.
doing ca should give you 1 i.e. one character array. However if you would have done something like char ca[] = "0"; then applying sizeof(ca) should give you 2 i.e. character '0' and null termination character. As aaaaaa123456789 mentioned, this is just an output now you are getting, just another byte in a memory. If you run this at some different time, you will see different output or your program may crash. referring incorrect location may cause any runtime anomaly.
I have a char a[] of hexadecimal characters like this:
"315c4eeaa8b5f8aaf9174145bf43e1784b8fa00dc71d885a804e5ee9fa40b16349c146fb778cdf2d3aff021dfff5b403b510d0d0455468aeb98622b137dae857553ccd8883a7bc37520e06e515d22c954eba5025b8cc57ee59418ce7dc6bc41556bdb36bbca3e8774301fbcaa3b83b220809560987815f65286764703de0f3d524400a19b159610b11ef3e"
I want to convert it to letters corresponding to each hexadecimal number like this:
68656c6c6f = hello
and store it in char b[] and then do the reverse
I don't want a block of code please, I want explanation and what libraries was used and how to use it.
Thanks
Assuming you are talking about ASCII codes. Well, first step is to find the size of b. Assuming you have all characters by 2 hexadecimal digits (for example, a tab would be 09), then size of b is simply strlen(a) / 2 + 1.
That done, you need to go through letters of a, 2 by 2, convert them to their integer value and store it as a string. Written as a formula you have:
b[i] = (to_digit(a[2*i]) << 4) + to_digit(a[2*i+1]))
where to_digit(x) converts '0'-'9' to 0-9 and 'a'-'z' or 'A'-'Z' to 10-15.
Note that if characters below 0x10 are shown with only one character (the only one I can think of is tab, then instead of using 2*i as index to a, you should keep a next_index in your loop which is either added by 2, if a[next_index] < '8' or added by 1 otherwise. In the later case, b[i] = to_digit(a[next_index]).
The reverse of this operation is very similar. Each character b[i] is written as:
a[2*i] = to_char(b[i] >> 4)
a[2*i+1] = to_char(b[i] & 0xf)
where to_char is the opposite of to_digit.
Converting the hexadecimal string to a character string can be done by using std::substr to get the next two characters of the hex string, then using std::stoi to convert the substring to an integer. This can be casted to a character that is added to a std::string. The std::stoi function is C++11 only, and if you don't have it you can use e.g. std::strtol.
To do the opposite you loop over each character in the input string, cast it to an integer and put it in an std::ostringstream preceded by manipulators to have it presented as a two-digit, zero-prefixed hexadecimal number. Append to the output string.
Use std::string::c_str to get an old-style C char pointer if needed.
No external library, only using the C++ standard library.
Forward:
Read two hex chars from input.
Convert to int (0..255). (hint: sscanf is one way)
Append int to output char array
Repeat 1-3 until out of chars.
Null terminate the array
Reverse:
Read single char from array
Convert to 2 hexidecimal chars (hint: sprintf is one way).
Concat buffer from (2) to final output string buffer.
Repeat 1-3 until out of chars.
Almost forgot to mention. stdio.h and the regular C-runtime required only-assuming you're using sscanf and sprintf. You could alternatively create a a pair of conversion tables that would radically speed up the conversions.
Here's a simple piece of code to do the trick:
unsigned int hex_digit_value(char c)
{
if ('0' <= c && c <= '9') { return c - '0'; }
if ('a' <= c && c <= 'f') { return c + 10 - 'a'; }
if ('A' <= c && c <= 'F') { return c + 10 - 'A'; }
return -1;
}
std::string dehexify(std::string const & s)
{
std::string result(s.size() / 2);
for (std::size_t i = 0; i != s.size(); ++i)
{
result[i] = hex_digit_value(s[2 * i]) * 16
+ hex_digit_value(s[2 * i + 1]);
}
return result;
}
Usage:
char const a[] = "12AB";
std::string s = dehexify(a);
Notes:
A proper implementation would add checks that the input string length is even and that each digit is in fact a valid hex numeral.
Dehexifying has nothing to do with ASCII. It just turns any hexified sequence of nibbles into a sequence of bytes. I just use std::string as a convenient "container of bytes", which is exactly what it is.
There are dozens of answers on SO showing you how to go the other way; just search for "hexify".
Each hexadecimal digit corresponds to 4 bits, because 4 bits has 16 possible bit patterns (and there are 16 possible hex digits, each standing for a unique 4-bit pattern).
So, two hexadecimal digits correspond to 8 bits.
And on most computers nowadays (some Texas Instruments digital signal processors are an exception) a C++ char is 8 bits.
This means that each C++ char is represented by 2 hex digits.
So, simply read two hex digits at a time, convert to int using e.g. an istringstream, convert that to char, and append each char value to a std::string.
The other direction is just opposite, but with a twist.
Because char is signed on most systems, you need to convert to unsigned char before converting that value again to hex digits.
Conversion to and from hexadecimal can be done using hex, like e.g.
cout << hex << x;
cin >> hex >> x;
for a suitable definition of x, e.g. int x
This should work for string streams as well.