Reputation: 340
I got the program to work as expected, but can anyone explain how it works?
#include <iostream>
using namespace std;
int main(void) {
int exit;
string name;
cin >> name;
for (int i = 0; i < name.length(); i++) {
// the line below is the one I don't understand
if ('a' <= name[i] && name[i] <= 'z') name[i] = char(((int)name[i]) - 32);
}
cout << name;
cin >> exit;
return 0;
}
EDIT: Let me rephrase:
The thing I don't understand is how does the string-to-array deal work, as in:
'a'<= name[i]
. What exactly does this compare and how?
EDIT2 Thanks for the quick responses guys, love you all. I figured it out.
Upvotes: 0
Views: 2484
Reputation: 88215
if ('a' <= name[i] && name[i] <= 'z')
char
objects are numeric values similar to ints. So 'a' <= name[i]
is simply testing if the numeric value of 'a'
is less than or equal to the character you're examining. Combined with name[i] <= 'z'
and you're testing if the numeric value of name[i]
is between the values of 'a'
and 'z'
. Now, it just so happens that the most common scheme for assigning numeric values to char
s, named "The American Standard Code for Information Interchange" (ASCII), has the alphabet arranged in order; 'a' + 1 = 'b'
, 'b' + 1 = 'c'
, and so on. So figuring out if the character is between 'a'
and 'z'
tells you if it's a lower case letter.
name[i] = char(((int)name[i]) - 32);
Once you know that char
s are just numeric values you might infer from the basic properties of arithmetic which we all learned in grade school that 'a' + ('A' - 'a')
results in the value 'A'
. Further, ASCII has the upper case alphabet arranged similarly to the lower case alphabet so that 'A' + 1
= 'B', etc. So taking any
charin the lower case alphabet and adding
'A' - 'a'will result in the upper case version of that letter. In ASCII
'A' - 'a'` happens to have the value -32. So take the numeric value for a lower case letter, subtract 32, and you have the value for the upper case letter.
For comparison here's a version of the code that doesn't depend on ASCII:
auto l = std::locale();
if (std::islower(name[i], l))
name[i] = std::tolower(name[i], l);
Upvotes: 0
Reputation: 70472
I assume from the edit in your comment that you are wondering how the []
can apply to a string
object. The operator []
is overloaded for string
to return a reference to the character at the specified position offset of the represented string. There need not be any direct conversion of the string
into an array. The code that implements the overload could well be walking a linked list. It depends on how string
was implemented.
Upvotes: 2
Reputation: 96835
'a' <= name[i] && name[i] <= 'z'
This line is comparing the corresponding ASCII values of these two characters. 'a'
in ASCII is 97 and 'z'
is 122. If name[i]
is one of the characters from 'a'
to 'z'
the expression returns true. This is commonly used to check if a variable is alphabetic.
Upvotes: 1
Reputation: 275740
This is the line:
if('a'<=name[i] && name[i]<='z')name[i]=char(((int)name[i])-32);
broken down:
if( 'a'<=name[i] ) {
if( name[i]<='z' ) {
// name_int is a temporary, which the above code implicitly creates,
// but doesn't give a name to:
int name_int = name[i];
name_int = name_int - 32;
name[i] = char(name_int);
}
}
and note that 32
happens to equal 'a'-'A'
in the character encoding you are using.
(Technically name_int
should be an int&&
or somesuch, but no need to be that confusing.)
Upvotes: 3
Reputation: 23266
It assumes ASCII character format where to convert from lowercase to uppercase you subtract 32 from the original ASCII value. This is because the ASCII values for uppercase are smaller than those for lower case and it's a constant difference between A
and a
, B
and b
and so on.
For reference: http://www.asciitable.com/
Upvotes: 1