473,326 Members | 2,095 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,326 software developers and data experts.

counting with char

Hello,

I want to print a table of characters and their values for my system like
65: A
66: B
aso.
starting from 0 to 255.

Am I rigth that I should use an unsigned char for this,
incrementing it each time? Using an signed char, or just
plain char (which is signed on my system) would just make
things difficult since I need to count with negative values.

But then the problem is the for loop.
Both this:

unsigned char c;
for (c = 0; c < 256; c++)

and

for (c = 0; c <= 255; c++)

will result in an infinite loop since c can't be larger than 255.

How can I tackle this? Do I have to use an other datatype than
char for the counter? Or can I cast it at the comparision somehow?

Which way is the best to go?
May 2 '06 #1
13 2515
eiaks said:
Hello,

I want to print a table of characters and their values for my system like
65: A
66: B
aso.
starting from 0 to 255.

Am I rigth that I should use an unsigned char for this,
incrementing it each time? Using an signed char, or just
plain char (which is signed on my system) would just make
things difficult since I need to count with negative values.


Just use int. All characters are representable as ints.

A word of advice: before deciding whether to write a character to your
standard output stream, shove it through isprint(), like this:

/* ch is an int */
if(isprint((unsigned char)ch))
{
display the character as a character by all means
}
else
{
display some kind of indication that the character is not printable
}

--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: rjh at above domain (but drop the www, obviously)
May 2 '06 #2

"eiaks" <ja**@hotmail.com> wrote in message
news:xG*******************@newsb.telia.net...
Hello,

I want to print a table of characters and their values for my system like
65: A
66: B
aso.
starting from 0 to 255.

Am I rigth that I should use an unsigned char for this,
incrementing it each time? Using an signed char, or just
plain char (which is signed on my system) would just make
things difficult since I need to count with negative values.

But then the problem is the for loop.
Both this:

unsigned char c;
for (c = 0; c < 256; c++)

and

for (c = 0; c <= 255; c++)

will result in an infinite loop since c can't be larger than 255.
You could count backwards:

#include <ctype.h>
#include <limits.h>
#include <stdio.h>

int main(void)
{
unsigned char c = UCHAR_MAX;
const char unprintable = '#';
unsigned char tmp = 0;

while(c)
{
tmp = UCHAR_MAX - c;
printf("%d: %c\n",
tmp,
isprint(tmp) ? (char)tmp : unprintable);
--c;
}

return 0;
}
How can I tackle this? Do I have to use an other datatype than
char for the counter?
You must if you need to use a value outside its range:

int main(void)
{
unsigned int c = 0;
const char unprintable = '#';

for(c = 0; c < UCHAR_MAX; ++c)
{
printf("%3d: %c\n",
c, isprint(c) ? (char)c : unprintable);
}

return 0;
}

Or can I cast it at the comparision somehow?
Casting cannot change the range of a type.
Always view a desire to cast with suspicion.
Which way is the best to go?


I'd go with my second example; imo it's more
'straightforward'.

-Mike
May 3 '06 #3

"Mike Wahler" <mk******@mkwahler.net> wrote in message
news:do*****************@newsread2.news.pas.earthl ink.net...

int main(void)
{
unsigned int c = 0;
const char unprintable = '#';

for(c = 0; c < UCHAR_MAX; ++c)


for(c = 0; c <= UCHAR_MAX; ++c)

-Mike
May 3 '06 #4
Richard Heathfield wrote:

All characters are representable as ints.


Chapter and verse? ;)

May 3 '06 #5
On Tue, 02 May 2006 23:11:25 GMT, eiaks <ja**@hotmail.com> wrote:
Hello,

I want to print a table of characters and their values for my system like
65: A
66: B
aso.
starting from 0 to 255.

Am I rigth that I should use an unsigned char for this,
incrementing it each time? Using an signed char, or just
plain char (which is signed on my system) would just make
things difficult since I need to count with negative values.

But then the problem is the for loop.
Both this:

unsigned char c;
for (c = 0; c < 256; c++)

and

for (c = 0; c <= 255; c++)

will result in an infinite loop since c can't be larger than 255.
Make it an int. An int will hold all char values, and chars change
into ints whenever you aren't watching them closely anyway <g>.

One other thing - your printer or screen will likely go nuts when you
print the output, because of all the non-printable characters. Use
isprint() to check each character, and substitute something else for
those that aren't printable (a period is often used.)
How can I tackle this? Do I have to use an other datatype than
char for the counter? Or can I cast it at the comparision somehow?

Which way is the best to go?


--
Al Balmer
Sun City, AZ
May 3 '06 #6
Old Wolf said:
Richard Heathfield wrote:

All characters are representable as ints.


Chapter and verse? ;)


Um, well, okay, what I said is certain to be true on the OP's system.

I suppose it is possible to construct a scenario where what I said is not
true, e.g. CHAR_BIT = 16, char is unsigned by default, INT_MAX is 32767,
and the character set is pretty large.
--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: rjh at above domain (but drop the www, obviously)
May 3 '06 #7
In article <xG*******************@newsb.telia.net>
eiaks <ja**@hotmail.com> wrote:
Both this:
unsigned char c;
for (c = 0; c < 256; c++)
and
for (c = 0; c <= 255; c++)
will result in an infinite loop since c can't be larger than 255.


Indeed: if UCHAR_MAX is 255, then when c==255, c++ has the same
effect as "c = 0" (because 255+1 is congruent to zero mod 256, as
the mathematicians say it).

As others noted, this particular case can be solved by counting in
"int" (which goes to at least +32767, and often higher). But there
are some situations in which C's "for" loop simply does not do the
desired job. For instance, suppose that, in C89 (not C99 hence
no "long long" type), you wish to iterate over every possible
"unsigned long" value. An attempt like:

unsigned long ul;

for (ul = 0; ul <= ULONG_MAX; ul++)

is an infinite loop, just as with the example above with unsigned
char. What is needed is a loop construct with a test-at-bottom.
C has one, but it is clumsier than a "for" loop. Just as most
people prefer a "for" loop for iterating through a list:

for (p = head; p != NULL; p = p->next)

or looping zero-or-more times through a case that does not hit
integer boundary problems:

for (i = 0; i < n; i++)

we might "prefer" a "for_until_with_test_at_bottom" loop in which
we could write:

for_until_test_at_bottom (ul = 0; ul != ULONG_MAX; ul++) {
... code ...
}

Instead, in C, we have to write, e.g.:

ul = 0;
do {
... code ...
continue_here: ;
} while (ul++ != ULONG_MAX);

and replace any "continue" statements in the "code" section with
"goto continue_label". (If there are no such statements, we can
omit the label and the empty statement that goes with it.) This
construct *also* depends on the fact that "ul++" is well defined
even if ul was ULONG_MAX (here ul becomes 0). (We could write this
as "do { ... } while (++ul != 0);" as well.) If the termination
condition might overflow -- as is true with signed integers -- we
have at least a technical problem, as the "++" might trap (even
though Real C Compilers never do, even on machines on which they
could -- it is usually more important to produce wrong answers fast
than to catch the error, after all :-) ).

Fortunately there is a third alternative. Although some purists
object to it, it neatly implements *all* forms of loops, including
test-at-top, test-at-bottom, and the occasional test-in-the-middle
"loop-and-a-half" that comes up now and then:

for (ul = 0;; ul++) {
... some code here ...
if (should_terminate_loop)
break;
... more code here ...
}

where either "code" section can be eliminated. (Of course, if the
first section is eliminated, we can just move the termination
condition into the "for" statement, and invert the sense.)
--
In-Real-Life: Chris Torek, Wind River Systems
Salt Lake City, UT, USA (40°39.22'N, 111°50.29'W) +1 801 277 2603
email: forget about it http://web.torek.net/torek/index.html
Reading email is like searching for food in the garbage, thanks to spammers.
May 3 '06 #8
Chris Torek wrote:
.... snip ...
Fortunately there is a third alternative. Although some purists
object to it, it neatly implements *all* forms of loops, including
test-at-top, test-at-bottom, and the occasional test-in-the-middle
"loop-and-a-half" that comes up now and then:

for (ul = 0;; ul++) {
... some code here ...
if (should_terminate_loop)
break;
... more code here ...
}

where either "code" section can be eliminated. (Of course, if the
first section is eliminated, we can just move the termination
condition into the "for" statement, and invert the sense.)


In my view, ugly. What is this urge to cast everything into a for
loop? while and do while are also available, and usually clearer
IMNSHO. for is best suited for iteration.

--
"If you want to post a followup via groups.google.com, don't use
the broken "Reply" link at the bottom of the article. Click on
"show options" at the top of the article, then click on the
"Reply" at the bottom of the article headers." - Keith Thompson
More details at: <http://cfaj.freeshell.org/google/>
Also see <http://www.safalra.com/special/googlegroupsreply/>
May 3 '06 #9
>Chris Torek wrote:
Fortunately there is a third alternative. Although some purists
object to it, it neatly implements *all* forms of loops, including
test-at-top, test-at-bottom, and the occasional test-in-the-middle
"loop-and-a-half" that comes up now and then:

for (ul = 0;; ul++) {
... some code here ...
if (should_terminate_loop)
break;
... more code here ...
}

where either "code" section can be eliminated. (Of course, if the
first section is eliminated, we can just move the termination
condition into the "for" statement, and invert the sense.)

In article <44***************@yahoo.com>
CBFalconer <cb********@maineline.net> wrote:In my view, ugly. What is this urge to cast everything into a for
loop? while and do while are also available, and usually clearer
IMNSHO. for is best suited for iteration.


The example *was* iteration.

Write me a loop that iterates an "int i" from INT_MIN through
INT_MAX, *inclusive*, with no undefined behavior, and only one copy
of the loop body. (Make sure that a "continue" within the loop
"does the right thing" too.) The last constraint rules out these
two forms:

i = INT_MIN;

LOOP_BODY; /* handles INT_MIN case */

do {
i++; /* starts at INT_MIN+1 */
LOOP_BODY; /* handles INT_MIN+1 through INT_MAX */
} while (i != INT_MAX);

and:

i = INT_MIN;
do {
LOOP_BODY; /* handles INT_MIN through INT_MAX - 1 */
} while (++i != INT_MAX);
LOOP_BODY; /* handles INT_MAX case */

The "no undefined behavior" constraint rules out this form:

i = INT_MIN;
do {
LOOP_BODY;
} while (i++ != INT_MAX);

because "i++" is undefined when i == INT_MAX.
--
In-Real-Life: Chris Torek, Wind River Systems
Salt Lake City, UT, USA (40°39.22'N, 111°50.29'W) +1 801 277 2603
email: forget about it http://web.torek.net/torek/index.html
Reading email is like searching for food in the garbage, thanks to spammers.
May 4 '06 #10
Chris Torek wrote:
.... snip ...
Write me a loop that iterates an "int i" from INT_MIN through
INT_MAX, *inclusive*, with no undefined behavior, and only one copy
of the loop body. (Make sure that a "continue" within the loop
"does the right thing" too.) The last constraint rules out these
two forms:


Can't do it in C. However <big grin> my PascalP system could do it
25 years ago:

FOR i := -maxint TO maxint DO something(i);

This was a failing that was discovered, and fixed, by use of the
Pascal validation suite. Unfortunately C has never had a public
equivalent.

--
"If you want to post a followup via groups.google.com, don't use
the broken "Reply" link at the bottom of the article. Click on
"show options" at the top of the article, then click on the
"Reply" at the bottom of the article headers." - Keith Thompson
More details at: <http://cfaj.freeshell.org/google/>
Also see <http://www.safalra.com/special/googlegroupsreply/>
May 5 '06 #11
Chris Torek wrote:
Write me a loop that iterates an "int i" from INT_MIN through
INT_MAX, *inclusive*, with no undefined behavior, and only one copy
of the loop body. (Make sure that a "continue" within the loop
"does the right thing" too.)


int i = INT_MIN;
do {
LOOP_BODY;
} while(i != INT_MAX ? i++, 1 : 0);

Does that count? :)

May 5 '06 #12
On 2006-05-04, Chris Torek <no****@torek.net> wrote:
The "no undefined behavior" constraint rules out this form:

i = INT_MIN;
do {
LOOP_BODY;
} while (i++ != INT_MAX);
because "i++" is undefined when i == INT_MAX.


int i = INT_MIN;
do {
LOOP_BODY;
} while(i != INT_MAX && (i++,1))
May 5 '06 #13
"CBFalconer" <cb********@yahoo.com> wrote i
Chris Torek wrote:

... snip ...

Write me a loop that iterates an "int i" from INT_MIN through
INT_MAX, *inclusive*, with no undefined behavior, and only one copy
of the loop body. (Make sure that a "continue" within the loop
"does the right thing" too.) The last constraint rules out these
two forms:


Can't do it in C. However <big grin> my PascalP system could do it
25 years ago:

FOR i := -maxint TO maxint DO something(i);

This was a failing that was discovered, and fixed, by use of the
Pascal validation suite. Unfortunately C has never had a public
equivalent.

int i;

i = INT_MIN;
loop:
do_something(i);
if(i < INT_MAX)
{
i++;
goto loop;
}
/* loop end */
--
Homepage: www.personal.leeds.ac.uk/bgy1mm
Programming goodies

May 7 '06 #14

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

8
by: pembed2003 | last post by:
Hi all, As an exercise, I am trying to come up with a function to count the length of a char* string using recursion. I came up with this: int count_length(char* s){ if(s == 0) return 0;...
4
by: sun6 | last post by:
this is a program counting words from "text_in.txt" file and writing them in "text_out.txt". it uses binary tree search, but there is an error when i use insert () thanks for any help ...
7
by: sathyashrayan | last post by:
Group, Following function will check weather a bit is set in the given variouble x. int bit_count(long x) { int n = 0; /* ** The loop will execute once for each bit of x set,
7
by: zets | last post by:
I need a macro for counting the bits in the odd positions of a given input (of any type, char, pointer, int, struct, whatever). Is there any clever way I could not think of, to do it efficiently? ...
5
by: andy.lee23 | last post by:
hi im having trouble counting lines in a text file, i have the following code int node1, node2, i; char name; float value; ifstream fin; fin.open(OpenDialog1->FileName.c_str()); i=1;
1
by: gisleyt | last post by:
I'd like to use the index-function to retrieve a certain char in a string, but i need it to start counting from the last char. E.g. in the string. Foo-bar, foo foo-bar I want the latter...
13
by: John | last post by:
Trying to return the number of 'on' bits in a byte: 'a' = 01100001 = 3 on bits, etc... I'm just adding a bit-wise AND ('&' against octal 1) to a counter called 'bits', then shifting my byte 1...
27
by: Simon Biber | last post by:
I was reading http://en.wikipedia.org/wiki/Poker_probability which has a good description of how to count the frequency of different types of poker hands using a mathematical approach. A sample...
3
by: majna | last post by:
I have character counter for textarea wich counting the characters. Special character needs same place as two normal characters because of 16-bit encoding. Counter is counting -2 when special...
0
by: DolphinDB | last post by:
Tired of spending countless mintues downsampling your data? Look no further! In this article, you’ll learn how to efficiently downsample 6.48 billion high-frequency records to 61 million...
0
by: ryjfgjl | last post by:
ExcelToDatabase: batch import excel into database automatically...
0
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, we are pleased to welcome back...
1
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, we are pleased to welcome back...
0
by: jfyes | last post by:
As a hardware engineer, after seeing that CEIWEI recently released a new tool for Modbus RTU Over TCP/UDP filtering and monitoring, I actively went to its official website to take a look. It turned...
1
by: PapaRatzi | last post by:
Hello, I am teaching myself MS Access forms design and Visual Basic. I've created a table to capture a list of Top 30 singles and forms to capture new entries. The final step is a form (unbound)...
1
by: CloudSolutions | last post by:
Introduction: For many beginners and individual users, requiring a credit card and email registration may pose a barrier when starting to use cloud servers. However, some cloud server providers now...
1
by: Defcon1945 | last post by:
I'm trying to learn Python using Pycharm but import shutil doesn't work
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 3 Apr 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome former...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.