Connecting Tech Pros Worldwide Forums | Help | Site Map

Stroustrup 4.11 exercise 4

arnuld
Guest
 
Posts: n/a
#1: Mar 26 '07
solution runs fine but i was not able to do the "hexadecimal" part .
any help on that ?

--------- PROGRAMME ---------------
/* TC++PL 3e, 4.11 exercise 4

STATEMENT:
write a programme that prints out the letters 'a'...'z',
digits '0' to '9' and their integer values. do the same for
other printable characters. Do the same again but use hexadecimal
notation.
*/

#include<iostream>

int main()
{
for(int i=0; i <= 127; ++i)
{
std::cout << "'"
<< char(i)
<< "' : \t"
<< i
<< std::endl;
}

return 0;
}

--------- OUTPUT -------------

NOTE: here some characters are not displayed properly but on my GNOME-
Terminal they were displayed without any trouble.

[arch@voodo tc++pl]$ ./a.out
'' : 0
'' : 1
'' : 2
'' : 3
'' : 4
'' : 5
'' : 6
'' : 7
' : 8
' ' : 9
'
' : 10
'
' : 11
'
' : 12
' : 13
'' : 14
'' : 15
'' : 16
'' : 17
'' : 18
'' : 19
'' : 20
'' : 21
'' : 22
'' : 23
'' : 24
'' : 25
'' : 26
'' : 27
'' : 28
'' : 29
'' : 30
'' : 31
' ' : 32
'!' : 33
'"' : 34
'#' : 35
'$' : 36
'%' : 37
'&' : 38
''' : 39
'(' : 40
')' : 41
'*' : 42
'+' : 43
',' : 44
'-' : 45
'.' : 46
'/' : 47
'0' : 48
'1' : 49
'2' : 50
'3' : 51
'4' : 52
'5' : 53
'6' : 54
'7' : 55
'8' : 56
'9' : 57
':' : 58
';' : 59
'<' : 60
'=' : 61
'>' : 62
'?' : 63
'@' : 64
'A' : 65
'B' : 66
'C' : 67
'D' : 68
'E' : 69
'F' : 70
'G' : 71
'H' : 72
'I' : 73
'J' : 74
'K' : 75
'L' : 76
'M' : 77
'N' : 78
'O' : 79
'P' : 80
'Q' : 81
'R' : 82
'S' : 83
'T' : 84
'U' : 85
'V' : 86
'W' : 87
'X' : 88
'Y' : 89
'Z' : 90
'[' : 91
'\' : 92
']' : 93
'^' : 94
'_' : 95
'`' : 96
'a' : 97
'b' : 98
'c' : 99
'd' : 100
'e' : 101
'f' : 102
'g' : 103
'h' : 104
'i' : 105
'j' : 106
'k' : 107
'l' : 108
'm' : 109
'n' : 110
'o' : 111
'p' : 112
'q' : 113
'r' : 114
's' : 115
't' : 116
'u' : 117
'v' : 118
'w' : 119
'x' : 120
'y' : 121
'z' : 122
'{' : 123
'|' : 124
'}' : 125
'~' : 126
'' : 127
[arch@voodo tc++pl]$


Alf P. Steinbach
Guest
 
Posts: n/a
#2: Mar 26 '07

re: Stroustrup 4.11 exercise 4


* arnuld:
Quote:
solution runs fine but i was not able to do the "hexadecimal" part .
any help on that ?
This prints a number in hexadecimal notation:

cout << hex << 12345 << endl;

Not sure which header 'hex' is defined in.

--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
Mike Wahler
Guest
 
Posts: n/a
#3: Mar 26 '07

re: Stroustrup 4.11 exercise 4



"Alf P. Steinbach" <alfps@start.nowrote in message
news:56pmp5F29rrr0U2@mid.individual.net...
Quote:
>* arnuld:
Quote:
>solution runs fine but i was not able to do the "hexadecimal" part .
>any help on that ?
>
This prints a number in hexadecimal notation:
>
cout << hex << 12345 << endl;
>
Not sure which header 'hex' is defined in.
<iosdeclares stream manipulators, except those
taking arguments, which are declared by <iomanip>.

-Mike


Marcus Kwok
Guest
 
Posts: n/a
#4: Mar 26 '07

re: Stroustrup 4.11 exercise 4


arnuld <geek.arnuld@gmail.comwrote:
Quote:
solution runs fine but i was not able to do the "hexadecimal" part .
any help on that ?
Look up the "hex" manipulator in <ios>.
Quote:
--------- PROGRAMME ---------------
/* TC++PL 3e, 4.11 exercise 4
>
STATEMENT:
write a programme that prints out the letters 'a'...'z',
digits '0' to '9' and their integer values. do the same for
other printable characters. Do the same again but use hexadecimal
notation.
*/
[code snipped]
Quote:
--------- OUTPUT -------------
>
NOTE: here some characters are not displayed properly but on my GNOME-
Terminal they were displayed without any trouble.
In <cctypethere is a function called isprint() that will tell you
whether or not a character is supposed to be printable.

--
Marcus Kwok
Replace 'invalid' with 'net' to reply
I V
Guest
 
Posts: n/a
#5: Mar 27 '07

re: Stroustrup 4.11 exercise 4


Your program doesn't quite do what the exercise asks:

On Mon, 26 Mar 2007 03:23:38 -0700, arnuld wrote:
Quote:
STATEMENT:
write a programme that prints out the letters 'a'...'z',
digits '0' to '9' and their integer values. do the same for
other printable characters. Do the same again but use hexadecimal
notation.
*/
The exercise asks you to print the letters a-z and the digits 0-9 but here
Quote:
for(int i=0; i <= 127; ++i)
{
you are printing all the characters with codes between 0 and 127. Some of
these will be characters which are not letters a-z or numbers 0-9; some of
them will not be printable characters at all (this is why you are getting
odd output).

I'm pretty sure that the C++ standard guarantees that the
character codes for a-z are continuous, as are the codes for the digits
0-9, so you can loop over these two character ranges.
arnuld
Guest
 
Posts: n/a
#6: Mar 27 '07

re: Stroustrup 4.11 exercise 4


Your program doesn't quite do what the exercise asks:
Quote:
>
On Mon, 26 Mar 2007 03:23:38 -0700, arnuld wrote:
Quote:
write a programme that prints out the letters 'a'...'z',
digits '0' to '9' and their integer values. do the same for
other printable characters. Do the same again but use hexadecimal
notation.
*/
>
The exercise asks you to print the letters a-z and the digits 0-9 but here
NO, it also asks you to print the ALL printable characters. read
again.
Quote:
Quote:
for(int i=0; i <= 127; ++i)
{
Quote:
you are printing all the characters with codes between 0 and 127. Some of
these will be characters which are not letters a-z or numbers 0-9; some of
them will not be printable characters at all (this is why you are getting
odd output).
ok, how do i know which characters are printable or not ?

Quote:
>
I'm pretty sure that the C++ standard guarantees that the
character codes for a-z are continuous, as are the codes for the digits
0-9, so you can loop over these two character ranges.

Alf P. Steinbach
Guest
 
Posts: n/a
#7: Mar 27 '07

re: Stroustrup 4.11 exercise 4


* arnuld:
Quote:
>
ok, how do i know which characters are printable or not ?
You can use the iscntrl function.

This function, from the old C library, is designed so that it almost
invites you to use it incorrectly.

The argument type is 'int', but it expects a /non-negative/ character code.

Hence if you pass a 'char', and with your compiler or compiler options
'char' is a signed type, you might end up passing in a negative value.

To avoid that the actual argument should be cast to 'unsigned char'
(it's perhaps best to write a function that in turn calls iscntrl).

--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
arnuld
Guest
 
Posts: n/a
#8: Mar 27 '07

re: Stroustrup 4.11 exercise 4


On Mar 27, 12:29 am, ricec...@gehennom.invalid (Marcus Kwok) wrote:

Quote:
In <cctypethere is a function called isprint() that will tell you
whether or not a character is supposed to be printable.

great, i used it and here is the resulting programme and output. as
you can see the output contains only the CHARS between 32-126 because
i applied "isprint()".

thanks Marcus

--------- PROGRAMME ------------

#include<iostream>
#include<cctype>

int main()
{
std::cout << "CHAR \tDECIMAL\tHEX" << std::endl;

for(int i=0; i <= 127; ++i)
{
char ic = char(i);

if(isprint(ic))
{
std::cout << "'"
<< ic
<< "' : \t"
<< i
<< std::endl;
}
}

return 0;
}

---------- OUTPUT ----------
CHAR DECIMAL HEX
' ' : 32
'!' : 33
'"' : 34
'#' : 35
'$' : 36
'%' : 37
'&' : 38
''' : 39
'(' : 40
')' : 41
'*' : 42
'+' : 43
',' : 44
'-' : 45
'.' : 46
'/' : 47
'0' : 48
'1' : 49
'2' : 50
'3' : 51
'4' : 52
'5' : 53
'6' : 54
'7' : 55
'8' : 56
'9' : 57
':' : 58
';' : 59
'<' : 60
'=' : 61
'>' : 62
'?' : 63
'@' : 64
'A' : 65
'B' : 66
'C' : 67
'D' : 68
'E' : 69
'F' : 70
'G' : 71
'H' : 72
'I' : 73
'J' : 74
'K' : 75
'L' : 76
'M' : 77
'N' : 78
'O' : 79
'P' : 80
'Q' : 81
'R' : 82
'S' : 83
'T' : 84
'U' : 85
'V' : 86
'W' : 87
'X' : 88
'Y' : 89
'Z' : 90
'[' : 91
'\' : 92
']' : 93
'^' : 94
'_' : 95
'`' : 96
'a' : 97
'b' : 98
'c' : 99
'd' : 100
'e' : 101
'f' : 102
'g' : 103
'h' : 104
'i' : 105
'j' : 106
'k' : 107
'l' : 108
'm' : 109
'n' : 110
'o' : 111
'p' : 112
'q' : 113
'r' : 114
's' : 115
't' : 116
'u' : 117
'v' : 118
'w' : 119
'x' : 120
'y' : 121
'z' : 122
'{' : 123
'|' : 124
'}' : 125
'~' : 126
[arch@voodo tc++pl]$


arnuld
Guest
 
Posts: n/a
#9: Mar 27 '07

re: Stroustrup 4.11 exercise 4


On Mar 26, 8:39 pm, "Mike Wahler" <mkwah...@mkwahler.netwrote:

Quote:
<iosdeclares stream manipulators, except those
taking arguments, which are declared by <iomanip>.
i tried this:

------------ PROGRAMME -----------
#include<iostream>
#include<cctype>
#include<ios>


int main()
{
std::cout << "CHAR \tDECIMAL\tHEX" << std::endl;

for(int i=0; i <= 127; ++i)
{
char ic = char(i);

if(isprint(ic))
{
std::cout << "'"
<< ic
<< "' : \t"
<< i
<< '\t'
<< std::ios::hex
<< i
<< std::endl;
}
}

return 0;
}

--------- OUTPUT ----------
[arch@voodo tc++pl]$ g++ -ansi -pedantic -Wall -Wextra 4.11_4.cpp
[arch@voodo tc++pl]$ ./a.out
CHAR DECIMAL HEX
' ' : 32 832
'!' : 33 833
'"' : 34 834
---------------------

i only USED some part of OUTPUT of here to make post shorter. you can
see the 1st line: DECIMAL "32" equals "832" in HEX. but it does not,
see:

HEX 832 = 8*16^2 + 3*16^1 + 2*16^0
= 2048 + 48 + 2
= 2098 IN DECIMAL

what is wrong with my programme ?

Michael DOUBEZ
Guest
 
Posts: n/a
#10: Mar 27 '07

re: Stroustrup 4.11 exercise 4


Alf P. Steinbach a écrit :
Quote:
* arnuld:
Quote:
>>
>ok, how do i know which characters are printable or not ?
>
You can use the iscntrl function.
Or simply the isprint function of the same header (cctype).
Quote:
>
This function, from the old C library, is designed so that it almost
invites you to use it incorrectly.
>
The argument type is 'int', but it expects a /non-negative/ character code.
>
Hence if you pass a 'char', and with your compiler or compiler options
'char' is a signed type, you might end up passing in a negative value.
>
To avoid that the actual argument should be cast to 'unsigned char'
(it's perhaps best to write a function that in turn calls iscntrl).
>
Alf P. Steinbach
Guest
 
Posts: n/a
#11: Mar 27 '07

re: Stroustrup 4.11 exercise 4


* arnuld:
Quote:
Quote:
>On Mar 26, 8:39 pm, "Mike Wahler" <mkwah...@mkwahler.netwrote:
>
>
Quote:
><iosdeclares stream manipulators, except those
>taking arguments, which are declared by <iomanip>.
>
i tried this:
>
------------ PROGRAMME -----------
#include<iostream>
#include<cctype>
#include<ios>
>
>
int main()
{
std::cout << "CHAR \tDECIMAL\tHEX" << std::endl;
>
for(int i=0; i <= 127; ++i)
{
char ic = char(i);
>
if(isprint(ic))
{
std::cout << "'"
<< ic
<< "' : \t"
<< i
<< '\t'
<< std::ios::hex
<< i
<< std::endl;
}
}
>
return 0;
}
>
--------- OUTPUT ----------
[arch@voodo tc++pl]$ g++ -ansi -pedantic -Wall -Wextra 4.11_4.cpp
[arch@voodo tc++pl]$ ./a.out
CHAR DECIMAL HEX
' ' : 32 832
'!' : 33 833
'"' : 34 834
---------------------
>
i only USED some part of OUTPUT of here to make post shorter. you can
see the 1st line: DECIMAL "32" equals "832" in HEX. but it does not,
see:
>
HEX 832 = 8*16^2 + 3*16^1 + 2*16^0
= 2048 + 48 + 2
= 2098 IN DECIMAL
>
what is wrong with my programme ?
A number of things.

First, unrelated to the hex, the conversion of 'i' to 'ic', to serve as
argument to 'isprint', does exactly the Wrong Thing. For the range you
have chosen, 0 through 127, it doesn't matter. But if increased that
range to say 0 through 255, then the conversion would introduce a
possible bug whereas all would be OK if you just used 'i' directly.

Second, regarding the hex. It's evident from the output that
std::ios::hex is display as '8', then 'i' is displayed in decimal. And
the reason is that the program is using the wrong 'hex', again because
it does to much: simply write 'std::hex', not 'std::ios::hex'.

Third, still regarding the hex. It sets the stream to a persistent
"display as hex" mode. Thus, when the code has been fixed as explained
above, only the first line of output will show any decimal number, the
rest will all be in hex.

I leave it to you to figure out a solution to that. ;-)


--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
Alf P. Steinbach
Guest
 
Posts: n/a
#12: Mar 27 '07

re: Stroustrup 4.11 exercise 4


* Michael DOUBEZ:
Quote:
Alf P. Steinbach a écrit :
Quote:
>* arnuld:
Quote:
>>>
>>ok, how do i know which characters are printable or not ?
>>
>You can use the iscntrl function.
>
Or simply the isprint function of the same header (cctype).
Not that it matters much, but you can assume there was a reason why I
didn't select that more "obvious" function in my answer.

--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
arnuld
Guest
 
Posts: n/a
#13: Mar 27 '07

re: Stroustrup 4.11 exercise 4


On Mar 27, 9:35 am, "Alf P. Steinbach" <a...@start.nowrote:
Quote:
A number of things.
>
First, unrelated to the hex, the conversion of 'i' to 'ic', to serve as
argument to 'isprint', does exactly the Wrong Thing. For the range you
have chosen, 0 through 127, it doesn't matter. But if increased that
range to say 0 through 255, then the conversion would introduce a
possible bug whereas all would be OK if you just used 'i' directly.
OK, if I use "i" directly then in "isprint(i)" will always be
printable whereas corresponding "char(i)" will not. i have also
removed some magic numbers. this i what i have done now:

#include<iostream>
#include<cctype>

int main()
{
std::cout << "CHAR \tDECIMAL\tHEX" << std::endl;

const int lower_range = 0;
const int upper_range = 127;

for(int i = lower_range; i <= upper_range; ++i)
{
if(isprint((char(i))))
// i think it is same as using "char ic = char(i)
{
std::cout << "'"
<< char(i)
<< "' : \t"
<< i
<< "\t0x"
<< std::hex
<< i
<< std::endl;
}
}

return 0;
}

Quote:
Second, regarding the hex. It's evident from the output that
std::ios::hex is display as '8', then 'i' is displayed in decimal. And
the reason is that the program is using the wrong 'hex', again because
it does to much: simply write 'std::hex', not 'std::ios::hex'.
done
Quote:
Third, still regarding the hex. It sets the stream to a persistent
"display as hex" mode. Thus, when the code has been fixed as explained
above, only the first line of output will show any decimal number, the
rest will all be in hex.

YES, you are right:

[arch@voodo tc++pl]$ ./a.out
CHAR DECIMAL HEX
' ' : 32 0x20
'!' : 21 0x21
'"' : 22 0x22
'#' : 23 0x23


:-(

Quote:
I leave it to you to figure out a solution to that. ;-)
all i can guess is "std::hex" works in both directions, left and right
BUT if that is true why do i get CORRECT values in 1st line? "32
0x20". i don't have any answer to this question.

i can create an "if-else" loop, where it will ask the user whether to
print the output in DEC format or in HEX but i don't want to do this.
i want both DEC and HEX on the same line. i am unable to figure any
way out.

Alf P. Steinbach
Guest
 
Posts: n/a
#14: Mar 27 '07

re: Stroustrup 4.11 exercise 4


* arnuld:
Quote:
Quote:
>On Mar 27, 9:35 am, "Alf P. Steinbach" <a...@start.nowrote:
>
Quote:
>A number of things.
>>
>First, unrelated to the hex, the conversion of 'i' to 'ic', to serve as
>argument to 'isprint', does exactly the Wrong Thing. For the range you
>have chosen, 0 through 127, it doesn't matter. But if increased that
>range to say 0 through 255, then the conversion would introduce a
>possible bug whereas all would be OK if you just used 'i' directly.
>
OK, if I use "i" directly then in "isprint(i)" will always be
printable whereas corresponding "char(i)" will not.
No. If you use isprint(i) then the function will work correctly. If
you use isprint(char(i)) then, if char is a signed type and the
character code is negative, isprint has Undefined Behavior, which means
it may crash or give an incorrect result or, for that matter, a correct
one. Don't ever give isprint a negative number as argument. That also
goes for its family functions.

Quote:
i have also
removed some magic numbers. this i what i have done now:
>
#include<iostream>
#include<cctype>
>
int main()
{
std::cout << "CHAR \tDECIMAL\tHEX" << std::endl;
>
const int lower_range = 0;
const int upper_range = 127;
>
for(int i = lower_range; i <= upper_range; ++i)
This is good.

Quote:
{
if(isprint((char(i))))
This is in-principle bad (although with the given range it doesn't do
anything bad): just write 'isprint(i)'.

Quote:
// i think it is same as using "char ic = char(i)
{
std::cout << "'"
<< char(i)
<< "' : \t"
<< i
<< "\t0x"
<< std::hex
<< i
<< std::endl;
}
}
>
return 0;
}
>
[snip]
Quote:
Quote:
>Third, still regarding the hex. It sets the stream to a persistent
>"display as hex" mode. Thus, when the code has been fixed as explained
>above, only the first line of output will show any decimal number, the
>rest will all be in hex.
>
>
YES, you are right:
>
[arch@voodo tc++pl]$ ./a.out
CHAR DECIMAL HEX
' ' : 32 0x20
'!' : 21 0x21
'"' : 22 0x22
'#' : 23 0x23
>
>
:-(
>
>
Quote:
>I leave it to you to figure out a solution to that. ;-)
>
all i can guess is "std::hex" works in both directions, left and right
BUT if that is true why do i get CORRECT values in 1st line? "32
0x20". i don't have any answer to this question.
No, it doesn't work in both directions. It doesn't affect earlier
output. It causes cout to /remember/ that the numbers should be display
in hexadecimal notation.

Initially cout remembers that numbers should be displayed in decimal
notation, and you changed that by using hex.

Now, after a little hex, cout remembers that numbers should be displayed
in hexadecimal notation, and you change that by ...?

--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
arnuld
Guest
 
Posts: n/a
#15: Mar 27 '07

re: Stroustrup 4.11 exercise 4


On Mar 27, 10:46 am, "Alf P. Steinbach" <a...@start.nowrote:
Quote:
No. If you use isprint(i) then the function will work correctly. If
you use isprint(char(i)) then, if char is a signed type and the
i dont understand the behaviour of "isprint()". does it understand its
input as merely an "int" or an "int for ASCII". to be exact:

isprint(68) == int 68
isprint(68) == ASCII representation of 'A'

Quote:
character code is negative, isprint has Undefined Behavior, which means
it may crash or give an incorrect result or, for that matter, a correct
one. Don't ever give isprint a negative number as argument. That also
goes for its family functions.
ok... i will take it as my 1st "good coding practice" advice from
Alf ;-)


Quote:
No, it doesn't work in both directions. It doesn't affect earlier
output. It causes cout to /remember/ that the numbers should be display
in hexadecimal notation.
>
Initially cout remembers that numbers should be displayed in decimal
notation, and you changed that by using hex.
>
Now, after a little hex, cout remembers that numbers should be displayed
in hexadecimal notation, and you change that by ...?
ok.. what "function" i can use that converts only the given DEC int to
a HEX int. IOW, is it possible to make it NOT to REMEMBER ?


Michael DOUBEZ
Guest
 
Posts: n/a
#16: Mar 27 '07

re: Stroustrup 4.11 exercise 4


Alf P. Steinbach a écrit :
Quote:
* Michael DOUBEZ:
Quote:
>Alf P. Steinbach a écrit :
Quote:
>>* arnuld:
>>>>
>>>ok, how do i know which characters are printable or not ?
>>>
>>You can use the iscntrl function.
>>
>Or simply the isprint function of the same header (cctype).
>
Not that it matters much, but you can assume there was a reason why I
didn't select that more "obvious" function in my answer.
Which without explaination only confuse the matter since the OP question
was to know wether a charater is printable or not.

Michael
Default User
Guest
 
Posts: n/a
#17: Mar 27 '07

re: Stroustrup 4.11 exercise 4


Alf P. Steinbach wrote:

Quote:
No. If you use isprint(i) then the function will work correctly. If
you use isprint(char(i)) then, if char is a signed type and the
character code is negative, isprint has Undefined Behavior, which
means it may crash or give an incorrect result or, for that matter, a
correct one. Don't ever give isprint a negative number as argument.
That also goes for its family functions.
A slight nitpick. It's ok to pass EOF to isprint() and the other
"character handling" functions. Presumably that's for the case of using
them in conjunction with getchar() or the like, that return an int
that's either an unsigned char converted to int or EOF.




Brian
Marcus Kwok
Guest
 
Posts: n/a
#18: Mar 27 '07

re: Stroustrup 4.11 exercise 4


I V <ivlenin@gmail.comwrote:
Quote:
I'm pretty sure that the C++ standard guarantees that the
character codes for a-z are continuous, as are the codes for the digits
0-9, so you can loop over these two character ranges.
IIRC, only the digits are guaranteed to be contiguous. The letters, not
necessarily so (see EBCDIC).

--
Marcus Kwok
Replace 'invalid' with 'net' to reply
Closed Thread


Similar C / C++ bytes