0

I'm helping a friend write a piece of code in C for an intro class that will take in a string and shift all of the characters of the string over by a certain amount of characters. So if he runs the program with the number 2, then it will shift all the characters over 2 places (hello -> jgnnq).

We're just trying to test for lowercase numbers now and no negative cases or anything like that. For some reason, this piece of code isn't working. We've just been testing with the letter o (ascii #111) and the number 18 for k. In the comments are our issues. I'm sure this is just some weird c behavior but we can't figure out what the problem is.

#include <string.h>
.
.
.
int k = atoi(argv[1]);
printf("Thanks for the %s. What sentence do you want to encrypt?\n", argv[1]);
string s = GetString();

for (int i = 0, n = strlen(s); i < n; i++) { 
    if (s[i] >= 'a' && s[i] <= 'z') {
        // printing s[i] gives 111 for 'o'
        // printing k gives 18
        // printing s[i]+k gives 129 which is expected.
        s[i] = s[i] +k;
        // printing s[i] here should give 129 but it gives -127
        while (s[i] > 'z') {
            s[i] = s[i] -26;
        } 
    }
}

Thanks!

Nate
  • 131
  • 2
  • 7
  • 1
    What is `string`? That's not a standard type. (Though seems to be `char *` and `char` is signed on your platform from the output you get.) – Mat Feb 09 '14 at 19:27
  • The "negative" value is to be expected if you're using signed characters. You need to reorganize your math a bit to avoid that. – keshlam Feb 09 '14 at 19:30
  • Sorry forgot to include the imports. We're including string.h in the file. I'll edit it to include this. We tried it earlier with char* and got the same behavior. – Nate Feb 09 '14 at 19:30
  • Well `string`is not defined in `` but rather in `cs50.h>` as in the other Caesar cipher question (http://stackoverflow.com/questions/21663698/caesar-cipher-in-c-working-for-lower-not-upper). That would be my guess, anyway. – M Oehm Feb 09 '14 at 19:31
  • It all depends what `string` is (you really need to show the definition). If it's an array of `char`, a `char` only has the range `-128` to `127`. Printing `s[i]+k` shows it as an `int`, so you get `129`. But `s[i]=s[i]+k` will yield `-127` (wrap around). – lurker Feb 09 '14 at 19:36

2 Answers2

3

Alternative "after accepted" answer that negates the need to change the type of s.

Do the math as int.

if (s[i] >= 'a' && s[i] <= 'z') {
    int sum = s[i] + k;
    if (sum > 'z') {
        sum = sum - 26;
    } 
    s[i] = sum
}

Changing sto type unsigned char fails should 'z' + key > 255.

This answer fails should 'z' + key > INT_MAX

chux - Reinstate Monica
  • 143,097
  • 13
  • 135
  • 256
0

Presumably string is of type char *.

char values have a range from -128 to +127.

Change the type of string to unsigned char *.

suspectus
  • 16,548
  • 8
  • 49
  • 57
  • 1
    `char` values may be signed or unsigned, depending on the compiler, and they must be large enough to represent the execution character set. It's true that the problem is likely that Nate is using a compiler where `char` is signed. A common range for a signed `char` is -128 to +127, but the details may vary. In any case, it's incorrect to say that the range of a `char *` (that is, a _pointer to_ a char) is -128 to +127. – Adrian McCarthy Feb 09 '14 at 20:13