Davigor
Davigor

Reputation: 403

C- Performing mathematical operations on string characters

I'm confused about mathematical operations being performed on characters in C. This is for implementing a basic cypher. I'm working with a string stored in a command line argument, argv.

for (int i = 0, n = strlen(p), m = strlen(argv[1]); i < n; i++)
{
    if ((p[i] >= 'A' && p[i] <= 'Z') || (p[i] >= 'a' && p[i] <= 'z'))
    {
        if (argv[1][i % m] >= 'A' && argv[1][i % m] <= 'Z')
        {
            printf("%c", ((p[i] - 'A') + ((argv[1][i % m]) - 'A')) % 26);
        }

        else if (argv[1][i % m] >= 'a' && argv[1][i % m] <= 'z')
        {
            printf("%c", ((p[i] - 'a') + ((argv[1][i % m]) - 'a')) % 26);
        }
    }

    else 
    {
        printf("%c", p[i]);
    }

My confusion comes in the "printf" lines. They aren't printing as written, and I don't know why. I did a few tests and found that my code will print fine if I remove the - 'a' and the % 26, to where it just looks like:

printf("%c", p[i] + argv[1][i % m]);

I don't know why this is, however. In my eyes, what I'm trying to do should be no different than an example given by the prof.:

string s = get_string();
if (s != NULL)
{
    for (int i = 0, n = strlen(s); i < n; i++)
    {
        if (s[i] >= 'a' && s[i] <= 'z')
    {
        printf("%c", s[i] - ('a' - 'A'));
    }
    else
    {
        printf("%c", s[i]);
    }
}

In particular, the line:

printf("%c", s[i] - ('a' - 'A'));

Any guidance is much appreciated!

Upvotes: 1

Views: 1496

Answers (2)

Aconcagua
Aconcagua

Reputation: 25516

printf("%c", ((p[i] - 'a') + ((argv[1][i % m]) - 'a')) % 26);

Stolen from Bathsheba:

So yes, your expressions of the form (a - b) - (c - b) simplify to a - c.

Well, (a - b) + (c - b) then gets a + c - 2*b, too...

So you get first:

printf("%c", (p[i] + argv[1][i % m] - 2*'a') % 26);
//                                           ^  yet left...

Next point is % 26 - it will calculate values from 0 to 26 - which all are control characters you presumably do not want to see...

Be aware that 'a' has a numerical value of 97 and 'A' of 65 (in ASCII, at least...). So you'll be interested in re-adding this value to your result:

printf("%c", (p[i] + argv[1][i % m] - 2*'a') % 26 + 'a');
//                                                ^ (or 'A' in the upper case case)

Upvotes: 3

Bathsheba
Bathsheba

Reputation: 234665

You are correct, you can simplify your code.

In C, things like 'a' are int types. (Contrary to popular belief, they are not char types, it's just that the C standard guarantees that they can be assigned to a char type without any danger of overflow.) The single quotation notation is used to obviate the fact that C does not mandate a specific character encoding. That is, you ought not care what number 'a' etc. represents. If you do care then strictly speaking your code is not portable C.

So yes, your expressions of the form (a - b) - (c - b) simplify to a - c.

Upvotes: 3

Related Questions