Add up ascii values of a char array

I have a C program that is sent a checksum.  I need to  need to modify the program so it calculates the checksum and compare.  It's just adding the ascii values on a file name.  Here's what I tried but I'm new at C and feeling stupid tonight.

long calc_checksum (char *fileName)
{
   int i;
   long checksum;

  for (i=0; i < strlen(fileName); i++)
     {
         checksum += atoi(&fileName[ i ]);
     }
     return checksum;
}
StarDusterIIAsked:
Who is Participating?

[Product update] Infrastructure Analysis Tool is now available with Business Accounts.Learn More

x
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

phoffricCommented:
atoi will convert a c-string like, "123", to an integer, 123. But if your filename is, say, "testChecksum.c", then atoi will return a 0 - probably not what you want.

fileName[ i ] is a char; and a char is an integer type, so you can just add the numbers together to get a checksum:
    checksum += fileName[ i ];

What you were doing, by using the &, was to convert the sequential addresses of the char array to a number; and that is not want you want, since that ignores the values in the filename.

Usually, checksums are done on the file contents, and not on the filename.
0
StarDusterIIAuthor Commented:
Doesn't really matter what checksums are usually done on does it... this is what's handed to me.  Using the "&" because if I don't I get a "passing argument 1 of ‘atoi’ makes pointer from integer without a cast" error.
0
phoffricCommented:
You can remove the atoi altogether and just add up the integer chars.
0
Become a Microsoft Certified Solutions Expert

This course teaches how to install and configure Windows Server 2012 R2.  It is the first step on your path to becoming a Microsoft Certified Solutions Expert (MCSE).

Dave BaldwinFixer of ProblemsCommented:
Here's both methods in one program.  You can see you don't need the atoi in the second example.  I had to add it up by hand to check it.  It just seemed odd that 'see2.c' would add up to 512 but it did.
#include <stdio.h>
#include <string.h>

/*   checksum characters in filename; 1st version */

main()
{
long calc_checksum (char *fileName)
  {
  int i;
  long checksum;
  checksum = 0;
  for (i=0; i < strlen(fileName); i++)
    {
    checksum += atoi(&fileName[ i ]);
    }
  return checksum;
  }

long calc_checksum2 (char *fileName)
  {
  int i;
  long checksum;
  checksum = 0;
  for (i=0; i < strlen(fileName); i++)
    {
    checksum += fileName[i];
    }
  return checksum;
  }

printf("Size = %ld\r\n",calc_checksum ("see2.c"));
printf("Size = %ld\r\n",calc_checksum2 ("see2.c"));
}

Open in new window

0
TommySzalapskiCommented:
I believe what phoffric is saying and Dave has made look complicated is to just replace your atoi line with this
checksum += fileName[ i ];

It will automatically cast the char to an integer. If you give C++ something it doesn't understand (like int = char) it looks to see if one can be promoted to something it does understand (like int = int). This works for all operators and functions (which is why you can to int + float, the int promotes to a float and then they are added).
0
Dave BaldwinFixer of ProblemsCommented:
Oh Tommy, I was just putting in the format that he was using so he could see how simple the change was.  With that and the explanations, I think we have answered his question fairly completely.
0
TommySzalapskiCommented:
I see. Well, perhaps my explanation of why it works has added some value to the thread anyway.
0
Dave BaldwinFixer of ProblemsCommented:
I think so, it wasn't mentioned before your comment.
0
phoffricCommented:
Here is a detailed explanation of what you did in your OP.

>> checksum += atoi(&fileName[ i ]);

When i is 0, then &fileName[0] is just the address of the first char in fileName. Suppose that name just happens to be "see2.c"
So what exactly is     atoi("see2.c")  ?

You have to look at the steps taken by atoi, which are described here:
     http://www.cplusplus.com/reference/clibrary/cstdlib/atoi/

In this specific example, the following two excerpts applies:
"If the first sequence of non-whitespace characters in str is not a valid integral number, or if no such sequence exists because either str is empty or it contains only whitespace characters, no conversion is performed."
"If no valid conversion could be performed, a zero value is returned."
So, atoi("see2.c") returns a 0 because the first char 's' is not a valid digit nor is it a plus or minus sign. So, as mentioned earlier, the atoi() function when using your construct is ignoring the c-style string pointed to by &fileName[0].

What about &fileName[1]. Well, this is just pointing to the 2nd char in the string. From the link, you see that atoi() is expecting a c-style string, so what the string being passed to atoi() is just "ee2.c" (and so again, a 0 is returned since 'e' is invalid).

For i = 2, "e2.c" is passed to atoi(), and again a 0 is returned.

For i = 3, "2.c" is passed to atoi(). Another excerpt from the atoi link:
"...followed by as many numerical digits as possible, and interprets them as a numerical value"
Since atoi is dealing with conversion of a string to an integer, the period (which would be a valid char for a float or double) is not going to be converted. So, atoi() takes the '2', converts it to an integer 2, and then stops when it sees the period. Since there are no more valid chars that atoi() can convert, then for i=4, and i=5, atoi() returns a 0.

So, for this string "see2.c", your checksum in your original post should come out to 2. As you can see, most of the chars in your filename were ignored in computing this checksum.

=======

Now, I suggested removing the atoi function as one way to get a checksum while still honoring the approach you were taking:
         checksum += fileName[ i ];
This is equivalent as I'm sure you know to:
         checksum = checksum  + fileName[ i ];
The very first time you hit this line, you are using checksum on the right hand side of the = sign. So, naturally, you have to initialize it to some value. (Whatever value you use, you will always use for consistency.) If you don't initialize it, then since checksum is on the stack, it has whatever garbage happens to be there, leading potentially to inconsistent results.

Using this revised code, for i=0, fileName[0] is 's', which I said was just an integer. From the following table, you can see that the value is 115 decimal or equivalently 73 hex.
In decimal, you see that: 'e' is 101; '2' is 50; '.' is 46; and 'c' is 99.
http://www.ascii-code.com/

So, what does "see2.c" add up to using the approach I suggested? It is just
=  's'  +  'e'  +   'e'  +  '2' +  '.' +  'c'
= 115   +  101  +   101  +  50  +  46  +  99 = 512

Open in new window


0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
Dave BaldwinFixer of ProblemsCommented:
@phoffric, that's very good.  And you were the first to point that out.
0
StarDusterIIAuthor Commented:
Wow... now that's what I call a complete answer!  Very helpful guys, very helpful.
0
StarDusterIIAuthor Commented:
More than complete... extraordinary description of the problem and possible solutions.
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
C

From novice to tech pro — start learning today.