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?
 
phoffricConnect With a Mentor Commented:
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
 
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
Free Tool: Port Scanner

Check which ports are open to the outside world. Helps make sure that your firewall rules are working as intended.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

 
phoffricCommented:
You can remove the atoi altogether and just add up the integer chars.
0
 
Dave BaldwinConnect With a Mentor Fixer 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
 
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
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.