Search code examples
ccs50

Why is argv[1] printing uppercase characters?


I converted the second argument, argv[1] to uppercase so I can check for any repeated characters. I did this by putting everything from argv[1] into a string called "key", then convert everything to uppercase inside "key". Now everything inside "key" is the same as argv[1] but it's all uppercase. However, when I print argv[1], that was converted to uppercase too. I need everything in argv[1] to stay the same. Does anyone know what I did wrong? Also just as a note, I'm using "string" from the cs50 library. Thank you.

#include <stdio.h>
#include <cs50.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>

const int key_length = 26;
int string_length = 0;

int main(int argc, string argv[])
{
    if (argc != 2)
    {
        printf("Usage: ./substitution key\n");
        return 1;
    }

    for (int i = 0, n = strlen(argv[1]); i < n; i++)
    {
        if (!isalpha(argv[1][i]))
        {
            printf("Key must contain only alphabetic characters.\n");
            return 2;
        }
        else
        {
            string_length += 1;
        }

    }
    if (string_length != key_length)
    {
        printf("Key must contain 26 characters.\n");
        return 3;
    }

    string key = argv[1];                       // converting key letters here
    for (int a = 0; a < strlen(key); a++)
    {
        if (!isupper(key[a]))
        {
            key[a] = toupper(key[a]);
        }
    }

    for (int l = 0; l < strlen(key); l++)
    {
        for (int h = l + 1; h < strlen(key); h++)
        {
            if (key[l] == key[h])
            {
                printf("No duplicates in key: %c\n", key[l]);
                return 4;
            }
        }
    }

}

Solution

  • string key = argv[1]; does not copy the characters pointed to by argv[1] to key.

    The type string is defined to be char *, a pointer to a char. argv[1] is also a pointer to a char. string key = argv[1]; creates a new pointer named key and sets it to point to the same place that argv[1] points.

    Then, when you change the characters pointed to by key to uppercase, you are also changing the characters pointed to by argv[1], since they are the same characters.

    To work with a copy of the characters, you must make a copy yourself:

    string key = malloc(strlen(argv[1] + 1); // Allocate space for characters in argument plus null terminator.
    if (!key) // Test whether allocation succeeded.
    {
        fprintf(stderr, "Error, unable to allocate memory.\n");
        exit(EXIT_FAILURE);
    }
    strcpy(key, argv[1]); // Copy characters.