开发者

New to C: whats wrong with my program?

I know my way around ruby pretty well and am teaching myself C starting with a few toy programs. This one is just to calculate the average of a string of numbers I enter as an argument.

#include <stdio.h>
#include <string.h>

main(int argc, char *argv[])
{
   char *token;
   int sum = 0;
   int count = 0;
   token = strtok(argv[1],",");
   while (token != NULL)
   {
     开发者_Python百科count++;
     sum += (int)*token;
     token = strtok(NULL, ",");
   }

 printf("Avg: %d", sum/count);
 printf("\n");
 return 0;
}

The output is:

mike@sleepycat:~/projects/cee$ ./avg 1,1
Avg: 49

Which clearly needs some adjustment.

Any improvements and an explanation would be appreciated.


Look for sscanf or atoi as functions to convert from a string (array of characters) to an integer.

Unlike higher-level languages, C doesn't automatically convert between string and integral/real data types.


49 is the ASCII value of '1' char.

It should be helpful to you....:D


The problem is the character "1" is 49. You have to convert the character value to an integer and then average.


In C if you cast a char to an int you just get the ASCII value of it. So, you're averaging the ascii value of the character 1 twice, and getting what you'd expect.

You probably want to use atoi().

EDIT: Note that this is generally true of all typecasts in C. C doesn't reinterpret values for you, it trusts you to know what exists at a given location.


strtok(

Please, please do not use this. Even its own documentation says never to use it. I don't know how you, as a Ruby programmer, found out about its existence, but please forget about it.

(int)*token

This is not even close to doing what you want. There are two fundamental problems:

1) A char* does not "contain" text. It points at text. token is of type char*; therefore *token is of type char. That is, a single byte, not a string. Note that I said "byte", not "character", because the name char is actually wrong - an understandable oversight on the part of the language designers, because Unicode did not exist back then. Please understand that char is fundamentally a numeric type. There is no real text type in C! Interpreting a sequence of char values as text is just a convention.

2) Casting in C does not perform any kind of magical conversions.

What your code does is to grab the byte that token points at (after the strtok() call), and cast that numeric value to int. The byte that is rendered with the symbol 1 actually has a value of 49. Again, interpreting a sequence of bytes as text is just a convention, and thus interpreting a byte as a character is just a convention - specifically, here we are using the convention known as ASCII. When you hit the 1 key on your keyboard, and later hit enter to run the program, the chain of events set in motion by the command window actually passed a byte with the value 49 to your program. (In the same way, the comma has a value of 44.)


Both of the above problems are solved by using the proper tools to parse the input. Look up sscanf(). However, you don't even want to pass the input to your program this way, because you can't put any spaces in the input - each "word" on the command line will be passed as a separate entry in the argv[] array.

What you should do, in fact, is take advantage of that, by just expecting each entry in argv[] to represent one number. You can again use sscanf() to parse each entry, and it will be much easier.


Finally:

printf("Avg: %d", sum/count)

The quotient sum/count will not give you a decimal result. Dividing an integer by another integer yields an integer in C, discarding the remainder.


In this line: sum += (int)*token; Casting a char to an int takes the ASCII value of the char. for 1, this value is 49.

Use the atoi function instead:

sum += atoi(token);

Note atoi is found in the stdlib.h file, so you'll need to #include it as well.


You can't convert a string to an integer via

sum += (int)*token;

Instead you have to call a function like atoi():

sum += atoi (token);


when you cast a char (which is what *token is) to int you get its ascii value in C - which is 49... so the average of the chars ascii values is in fact 49. you need to use atoi to get the value of the number represented

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜