Joey Yue
Joey Yue

Reputation: 29

How to do read multiple characters from an argument

I am trying to read multiple characters from an argument in c. So when the person rules the file like "./amazing_program qwertyyuiopasdfghjklzxcvbnm" it would read the qwerty characters and store the, into a array as a number (ASCII) like:

array[0] = 'q';
array[1] = 'w';
array[2] = 'e';
array[3] = 'r';
array[4] = 't';
array[5] = 'y';
and so on...

My goal: Is to separate the argument into each individual character and store each individual character into a different place in the array (like shown above).

I tried this way, but it didn't work.

int user_sub = 0;
int argument = 1;
while (argument < argc) {
   user_sub = atoi(argv[argument]);
   argument = argument + 1;
}

Upvotes: 1

Views: 1218

Answers (2)

Micrified
Micrified

Reputation: 3650

From reading your comments, I've come to understand you just want to be able to get to the characters so you can do a shift. Well, that's not so hard to do, so I've tried to show you how you can do it here without having to complete the Caesar logic for you.

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

#define SHIFT   13

int main (int argc, const char *argv[]) {

    // Verify they gave exactly one input string.
    if (argc != 2) {
        fprintf(stderr, "Usage: %s <word>\n", argv[0]);
        exit(EXIT_FAILURE);
    }

    // A string IS already an array of characters. So shift then and output. 
    int n = strlen(argv[1]);
    for (int i = 0; i < n; i++) {
        char c = argv[1][i];

        // Shift logic here: putchar(...);
        printf("%d: %c\n", i, c);
    }

    return EXIT_SUCCESS;
}

The key takeaway is that a string is already an array. You don't need to make a new array and stick all the characters in it. You already have one. What this program does is simply "extract" and print them for you so you can see this. It currently only writes the current argument string to output, and does no shifting. That's for you to do. It also doesn't take into account non-alphabetical characters. You'll have to think about them yourself.

Upvotes: 1

Tom&#39;s
Tom&#39;s

Reputation: 2506

You have serious lack :

1)

A string in C is an ARRAY of type char. We know where the end of the array is thank to a special value : '\0'. Now, you have to deeply understand that each case of the array contain a NUMBER : since the type of the case is char, it will be a number in the range [-128, 127] (yeah, I know that char is special and can be signed or not, but let's keep it simple for the time being).

So if you acces each case of the array and print it, you will have a number between -128 and 127. So how the program know to print a letter instead of a number ? And how do he know which letter for which number ?

Thank to an internal table used for this uniq purpose. The most common is the ASCII table. So if a case of the array is 65, what will be printed is 'A'.

2) How can I go through each case of a string ? (which is an array of char terminated by '\0') ?

Simply with a for loop.

char str[] = "test example";
for (size_t i = 0; str[i] != '\0'; ++i) {
  printf("The %d letter is  '%c'\n", i, str[i]);
}

Again, since it's a number in str[i], how the program know how to print a letter ? Thank to the "%c" in printf, meaning "print the letter using the table (probably ASCII)". If you use "%s", it's the same thing, but you have to give the array itself instead of a case of the array.

So, what if I want to print the number instead of the letter ? Just use "%d" in printf.

char str[] = "test example";
for (size_t i = 0; str[i] != '\0'; ++i) {
  printf("The %d letter is  '%c' and it's real value is %d\n", i, str[i], str[i]);
}

Now, what if we increment all the value in each case of the string ?

char str[] = "test example";
for (size_t i = 0; str[i] != '\0'; ++i) {
  str[i] = str[i] + 1; // Or ++str[i];
}
for (size_t i = 0; str[i] != '\0'; ++i) {
  printf("The %d letter is  '%c' and it's real value is %d\n", i, str[i], str[i]);
}

We have changed the string "test example" into "uftu fybnqmf".

Now, for your problem, you have to take the resolution step by step : First, make a function that alter (cypher) a string given in argument by adding a shift.

void CesarCypherString(char *string);

Beware of "overflow" ! If I want to have a shift of 5, then 'a' will become 'f', but what happen for 'z' ? It should be 'e'. But if you look at the ascii table, 'a' = 97, 'f' = 102 (and it make sense, since 'a' + 5 = 'f', 97 + 5 = 102), but 'z' is 122 and 'e' is 101. So you cannot directly do 'z' + 5 = 'e' since it's wrong.

Hint : use modulo operator (%).

Next, when you have finished to do the function CesarCypherString, do the function CesarDecypherString that will decypher a string.

When you have finished, then you can concentrate on how to read/duplicate a string from argv.

Upvotes: 0

Related Questions