Accessing array by char in C++ - c++

Usually, I access an array in C++ by the syntax foo[2], where 2 is the index of an array.
In the below code. I didn't understand how this code is giving output and access this array by index 'b', 'c'. I am confused it is array index or something else.
int count[256] = {0};
count['b'] = 2;
cout << count['b'] << endl; //output 2
cout << count['c'] << endl; //output 0
Output
2
0

Remember that in c++ characters are represented as numbers. Take a look at this ascii table. http://www.asciitable.com
According to this the character 'b' is represented 98 and 'c' as 99. Therefore what your program is really saying is...
int count[256] = {0};
count[98] = 2;
cout << count[98] << endl; //output 2
cout << count[99] << endl; //output 0
Also incase you don't know saying an array = {0} means zero initialize every value so that is why count['c'] = 0.
In C/C++ there is not 8 bit / 1 byte integer. We simply use the char type to represent a single (signed or unsigned) byte and you can even put signed and unsigned infront of the char type. Char really is just another int type which we happen to use to express characters. You can also do the following.
char b = 98;
char c = 99;
char diff = c - b; //diff is now 1

Type char is actually an integral type. Every char value represented by a character literal has an underlying integral value it corresponds to in a given code page, which is probably an ASCII table. When you do:
count['b'] = 2;
you actually do:
count[98] = 2;
as character 'b' corresponds to an integral value of 98, character 'c' corresponds to an integral value of 99 and so on. To illustrate, the following statement:
char c = 'b';
is equivalent of:
char c = 98;
Here c has the same underlying value, it's the representation that differs.

Because characters are always represented by integers in the computer, it can be used as array indices.
You can verify by this:
char ch = 'b';
count[ch] = 2;
int i = ch;
cout << i << endl;
cout << count[i] << endl;
Usually the output is 98 2, but the first number may vary depending on the encoding of your environment.

Related

How it became possible for integer and character be added and return a summation of integer type?

#include<iostream>
using namespace std;
int main()
{
char a = 77;
int b = a + 3;
cout << a << endl;
cout << b << endl;
return 0;
}
Look carefully, a is holding the character 'M', according to its ASCII value 77. Variable a is actually returning 'M' here. How can you store M+3=80 in an int type variable?
The type char is an integral type. Full stop. There is nothing magical about a char that says it has to represent a character. So
char a = 77;
does exactly the same thing as
int a = 77;
except that char could be smaller than int, so might have a more limited range of values that it can represent.
Similarly,
int a = 'A';
assigns the value of 'A' to a, just as
char a = 'A';
would.
And, finally,
char a = 77;
a = a + 1;
does exactly the same thing as
int a = 77;
a = a + 1;
does. They're both integer types, and they both store integer values.
The place where char differs is in the functions that do input and output. For example,
char ch = 'A';
std::cout << ch << '\n';
will display the character A, while
int i = 'A';
std::cout << i << '\n';
will display the numeric value of the character A, That value depends on the character encoding that the compiler uses; that's almost always ASCII theses days, but that's not required.

Totally unrelated result when multiplying two integers?

#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

How can I convert 1 element of an int array to a string/char

When I try to write for example arr[0] = 'y'; and I try to print it it will print "121" because 121 is 'y' in the ASCII table. How can I convert it so the array element will replace it with an actual 'y'?
int example [2] = {16,2};
How do I convert for example 16 to the letter 'y' so if I print the whole array it'd print "y2" and not 1212?
Print format:
int r[2] = {12,43};
for(int i=0; i<2;i++){
cout << r[i];
}
Arrays are homogeneous. All elements of the array have the same type. When you have an array of int, then all elements have the type int.
When you insert an int into a character stream, the output will be a number, with equivalent format to num_put::put().
So, if you want to see output like y, then you must insert either a character, or a character string. If you want to output one object like a character, and another like an integer, then those objects must have a different type.
Characters are integers (with special treament), and convertible to and from int (although not all int values are representable as char). Example using such conversion:
int example [2] = {'y',2};
std::cout << char(example[0]) << example[1];
An easy way to associate letters with numbers is to use std::map:
std::map<int, char> conversions;
//...
map[16] = 'y';
//...
std::cout << map[16] << std::endl;
You could also use an array of char:
static const char conversion_array[] =
{'F', ..., 'y', ...};
std::cout << conversion_array[16] << std::endl;
short my_short = 12;
char my_character = static_cast<char>(my_short);
std::cout << my_character << std::endl;
Will print a char
std::ostream has an overloaded operator<< for chars, which allows you to print the char instead of printing an integer

Difference between .at<uchar> and static_cast<uchar> in opencv?

I have a float matrix a and I want to access the element at the point (x,y), but I want to convert the data type to unsigned char. The float number in point(x,y) is 652.759
The code I want to use (which is based on Opencv)is
a.at<uchar>(Point(x,y))
The result of above code is 68.
But when I checked the result with simple c++ code
static_cast<unsigned char>(a.at<float>(Point(x,y)))
the result is 140.
Anyone knows why? How can I get the same results by using both the code above?
Thx!
The at() function is agnostic as to the number of bits per point, and bases its judgement on the supplied template type.
So, at<float>(2) will return a float composed of a 32 bits range starting from the 4th byte of the array, while at<uchar>(2) will simply return the second byte in the array.
For example, the following
Mat m(10, 1, CV_8U);
m.at<uchar>(0) = 44;
m.at<uchar>(1) = 1;
m.at<uchar>(2) = 0;
m.at<uchar>(3) = 0;
cout << "char 0 : " << (int)m.at<uchar>(0) << endl;
cout << "char 1 : " << (int)m.at<uchar>(1) << endl;
cout << "short 0 : " << (int)m.at<unsigned short>(0) << endl;
produces
char 0 : 44
char 1 : 1
short 0 : 300
short 0 = char 1 * 256 + char 0
It's basically the same difference than in this code:
float f = 140.f;
unsigned char c = static_cast<unsigned char>(f); // c is 140, this is ok
unsigned char wrong = *((unsigned char*)&f); // this is wrong
The last line is the same as the a.at<uchar>(Point(x,y)) you have in your code. This is wrong because it access a float and reinterprets it (its bytes) as an unsigned char. There is no actual conversion of the binary values.

Character Array, \0

I know, the \0 on the end of the character array is a must if you use the character array with functions who expect \0, like cout, otherwise unexpected random characters appear.
My question is, if i use the character array only in my functions, reading it char by char, do i need to store the \0 at the end?
Also, is it a good idea to fill only characters and leave holes on the array?
Consider the following:
char chars[5];
chars[1] = 15;
chars[2] = 17;
chars[3] = 'c';
//code using the chars[1] and chars[3], but never using the chars
int y = chars[1]+chars[3];
cout << chars[3] << " is " << y;
Does the code above risk unexpected errors?
EDIT: edited the example.
The convention of storing a trailing char(0) at the end of an array of chars has a name, it's called a 'C string'. It has nothing to do, specifically, with char - if you are using wide character, a wide C string would be terminated with a wchar_t(0).
So it's absolutely fine to use char arrays without trailing zeroes if what you are using is just an array of chars and not a C string.
char dirs[4] = { 'n', 's', 'e', 'w' };
for (size_t i = 0; i < 4; ++i) {
fprintf(stderr, "dir %d = %c\n", i, dirs[i]);
std::cout << "dir " << i << " = " << dirs[i] << '\n';
}
Note that '\0' is char(0), that is it has a numeric, integer value of 0.
char x[] = { 'a', 'b', 'c', '\0' };
produces the same array as
char x[] = { 'a', 'b', 'c', 0 };
Your second question is unclear, though
//code using the chars[1] and chars[3], but never using the chars
int y = chars[1]+chars[3];
cout << chars[3] << " is " << y;
Leaving gaps is fine, as long as you're sure your code is aware that they are uninitialized. If it is not, then consider the following:
char chars[4]; // I don't initialize this.
chars[1] = '1';
chars[3] = '5';
int y = chars[1] + chars[3];
std::cout << "y = " << y << '\n';
// prints 100, because y is an int and '1' is 49 and '5' is 51
// later
for (size_t i = 0; i < sizeof(chars); ++i) {
std::cout << "chars[" << i << "] = " << chars[i] << '\n';
}
Remember:
char one = 1;
char asciiCharOne = '1';
are not the same. one has an integer value of 1, while asciiCharOne has an integer value of 49.
Lastly: If you are really looking to store integer numeric values rather than their character representations, you may want to look at the C++11 fixed-width integer types in . For an 8-bit, unsigned value uint8_t, for an 8-bit signed value, int8_t
Running off the end of a character array because it has no terminating \0 means accessing memory that does not belong to the array. That produces undefined behavior. Often that looks like random characters, but that's a rather benign symptom; some are worse.
As for not including it because you don't need it, sure. There's nothing magic that says that an array of char has to have a terminating \0.
To me it looks like you use the array not for strings, but as an array of numbers, so yes it is ok not to use '\0' in the array.
Since you are using it to store numbers, consider using uint8_t or int8_t types from stdint.h, which are typedefs for unsigned char and signed char, but is more clear this way that the array is used as an array of numbers, and not as a string.
cout << chars[3] << " is " << y; is not undefined behaviour because you access the element at position 3 from the array, that element is inside the array and is a char, so everything is fine.
EDIT:
Also, I know is not in your question, but since we are here, using char instead of int for numbers, can be deceiving. On most architectures, it does not increase performance, but actually slows it down. This is mainly because of the way the memory is addressable and because the processor works with 4 bytes / 8 bytes operands anyways. The only gain would be the storage size, but use this for storing on the disk, and unless you are working with really huge arrays, or with limited ram, use int for ram as well.