2

For 'duration' I used the following which works (at least within a testing file), using atoi on individual parts of the inputted string fraction s:

double n = atoi(&s[0]); double d = atoi(&s[2]); int duration = ((n/d))/(.125); return duration;

I added the & after trial and error, and as a result I have a few questions on how atoi works:

1) In Caesar I used: int key = atoi(argv[1]); which worked well, and converted the whole string in one go. In the case of the fraction, does atoi NOT work because it returns a NULL value when it hits the / character?

2) What exactly is the & doing in the code above? From reading, it looks like & is an "Address of Operator" - meaning the & pointing to the value that is stored in the s[0] location...but isn't that what writing s[0] is already doing?

1 Answer 1

3

First, understand what strings in C are.

Strings in C are pointers to a character, or char* (if you use type string, that's a custom alias for the same thing). The convention then says that the pointer points the first byte of a string (this time in the sense of the actual characters), and the string ends at the first character that's zero, often called "null terminator".

This division between the pointer and the memory where the characters are stored might be confusing, but gives extra flexibility (if you assign to a string variable, you copy the pointer, not the whole string, and that string can be of any length, the pointer doesn't care and always has the same size).

Now &s[0]. s[0] is the character the pointer points to. &s[0] is the address of that character (same as s).

atoi(&s[0]) will now try to convert for example "3/8" to an integer. It reads '3', fine. It reads '/', ouch. That's not part of an integer, so return what we got so far.

atoi(&s[2]) for the same string will read '8', fine. Then it reads '\0', null terminator means string end, done, return what we have so far.

As we here just want to convert single digits to their numeric value, you could just subtract '0' (or its ASCII value 48) like you did subtract 'A' or 'a' (or their counterparts 65 and 97) in caesar and vigenere.

And if you multiplied by 8 first, and only then divided, you wouldn't need any floating point numbers.

4
  • Ok, so in this case I almost get lucky that the pattern of a fraction forces atoi to stop at '/' - which gives me the numerator, then I redo for the denom. Is this an OK way of doing this conversion? I had written the latter format (using the shifted ASCII values then dividing out .125) but it felt more efficient to do it this way since there was less computation involved.
    – Jake
    Jun 20, 2018 at 14:41
  • Ah multiplying by 8 instead of dividing is much easier
    – Jake
    Jun 20, 2018 at 14:59
  • Well, it's specified behaviour that atoi stops at first non-number character, the null terminator is nothing special in that sense. A function call to atoi is definitely more computationally intense than some s[0] - '0'.
    – Blauelf
    Jun 20, 2018 at 15:32
  • Great - thanks for all the help!
    – Jake
    Jun 20, 2018 at 20:31

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .