5

I'm still new to the forum so I apologize in advance for forum - etiquette issues.

I'm having trouble understanding the differences between int arrays and char arrays.

I recently wrote a program for a Project Euler problem that originally used a char array to store a string of numbers, and later called specific characters and tried to use int operations on them to find a product. When I used a char string I got a ridiculously large product, clearly incorrect. Even if I converted what I thought would be compiled as a character (str[n]) to an integer in-line ((int)str[n]) it did the exact same thing. Only when I actually used an integer array did it work.

Code is as follows

for the char string

char str[21] = "73167176531330624919";

This did not work. I got an answer of about 1.5 trillion for an answer that should have been about 40k.

for the int array

int str[] = {7,3,1,6,7,1,7,6,5,3,1,3,3,0,6,2,4,9,1,9};

This is what did work. I took off the in-line type casting too.

Any explanation as to why these things worked/did not work and anything that can lead to a better understanding of these ideas will be appreciated. Links to helpful stuff are as well. I have researched strings and arrays and pointers plenty on my own (I'm self taught as I'm in high school) but the concepts are still confusing.

Side question, are strings in C automatically stored as arrays or is it just possible to do so?

Yu Hao
  • 119,891
  • 44
  • 235
  • 294
Charles
  • 99
  • 2
  • 11
  • 3
    Perhaps [this table](http://www.asciitable.com) may shed some light on your treatment of ascii chars as `int` values. And yes, if by 'array` you mean contiguous memory containing the underlying character data, they are stored as such (with an implicit 0-terminator tacked on). – WhozCraig Aug 13 '13 at 04:56
  • does that table say that char '0' corresponds to an int value of 48? – Charles Aug 13 '13 at 05:01
  • Yes, though the value is unsigned, which may not seem important but will be so if you need to handle extended ascii characters (see the table immediately below that one). You're on the right track. Several answers below describe this better. Note also that this ('0' == 48) is only true for ASCII. There are other system-dependent character sets (such as [EBCDIC](http://en.wikipedia.org/wiki/EBCDIC)). – WhozCraig Aug 13 '13 at 05:05

3 Answers3

4

To elaborate on WhozCraig's answer, the trouble you are having does not have to do with strings, but with the individual characters.

Strings in C are stored by and large as arrays of characters (with the caveat that there exists a null terminator at the end).

The characters themselves are encoded in a system called ascii which assigns codes between 0 - 127 for characters used in the english language (only). Thus "7" is not stored as 7 but as the ascii encoding of 7 which is 55.

I think now you can see why your product got so large.

One elegant way to fix would be to convert

int num = (int) str[n];

to

int num = str[n] - '0';  
//thanks for fixing, ' '  is used for characters, " " is used for strings

This solution subtracts the ascii code for 0 from the ascii code for your character, say "7". Since the numbers are encoded linearly, this will work (for single digit numbers). For larger numbers, you should use atoi or strtol from stdlib.h

Karthik T
  • 31,456
  • 5
  • 68
  • 87
  • I like your idea of converting the code back to my digits I'd like. It is, as you say, elegant :) – Charles Aug 13 '13 at 05:06
  • 1
    I would suggest [`strtol()`](http://en.cppreference.com/w/c/string/byte/strtol) for conversions, but the idea is there. – WhozCraig Aug 13 '13 at 05:08
  • @WhozCraig I keep seeing that.. Is that because `atoi` relies on the null terminator to stop parsing? – Karthik T Aug 13 '13 at 06:33
  • @KarthikT See [this discussion](http://stackoverflow.com/questions/3792663/atol-v-s-strtol). Its not often it is applicable, but the term "more better" is fairly accurate in describing the differences. – WhozCraig Aug 13 '13 at 15:07
3

Strings are just character arrays with a null terminating byte. There is no separate string data type in c.

When using a char as an integer, the numeric ascii value is used. For example, saying something like printf("%d\n", (int)'a'); will result in 97 (the ascii value of 'a') being printed.

You cannot use a string of numbers to do numeric calculations unless you convert it to an integer array. To convert a digit as a character into its integer form, you can do something like this:

 char a = '2';
 int a_num = a - '0';
 //a_num now stores integer 2

This causes the ascii value of '0' (48) to be subtracted from ascii value '2' (50), finally leaving 2.

Harry
  • 394
  • 2
  • 10
2
char str[21] = "73167176531330624919"

this code is equivalent to

char str[21] = {'7','3','1','6','7','1','7','6','5',/
                '3','1','3','3','0','6','2','4','9','1','9'}

so whatever stored in str[21] is not numbers, but the char(their ASCII equivalent representation is different).

side question answer - yes/no, the strings are automatically stored as char arrays, but the string does has a extra character('\0') as the last element(where a char array need not have such a one).

Opener
  • 145
  • 1
  • 8