简体   繁体   中英

How do I use padding if my string has odd number of characters in C?

I am using C as my programming language (not C++) and I am required to encrypt whatever the user types in using a 2-rail fence cipher method of coding in C, AND then pad whatever empty space there is left in the encrypted name with an 'x'. Because it's 2-rail fence the empty space happens if the output string has ODD number of characters!

Here is an example.

Let's say someone write this name: andredimera (all lowercase, no space). The name is 11 characters long. If padding with the x is done correctly, the encrypted name should give me this output WITH the padding -->

adeiea
nrdmrx

adeieanrdmrx

But I keep getting this output without the padding-->

adeiea
nrdmr

adeieanrdmr

This is FRUSTRATING! This has been a class quiz for almost a week now, I have not done well, and nobody has been able to help me out no thanks to my short-term memory. I would really appreciate this if someone can help me solve this, with an explanation on how you came up with the solution, so I can get it right in future endeavors. I don't want just the hint or explanation for me to go fish it out myself. I've had my share of it already this week. Thank you. I appreciate your help. :)

Oh, and here is my code:

UPDATED: Code was reposted because I was stupidly compiling it in a completely different solution. That code should work now. Which now brings me to my latest question based on my updated code: how can I make my char pad = 'x' be added into my char str if the user input has odd number of characters?

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

int main()
{
        char row, col;
        char str[100][100];
        char pad = 'x';

    printf("****Welcome to The Caesar's Palace for Encrypted Names****");

    printf("\n Please enter your name: ");
    scanf("%s", str);

    printf("You entered: %s\n", str);

    printf("2-RAIL CIPHER ENCRYPTION:\n");
    for (row = 0; row < 1; ++row)
    {
        for (col = 0; col < 12; col += 2) 
        {
            printf("%c", str[row][col]);
        }

    printf("\n");
    for (col = 0; col < 12; col += 2) 
        {

            printf("%c", str[row][col + 1]);
        }
    }

    printf("%c", pad);
    printf("\n");

    for (row = 0; row < 1; ++row) 
    {
        for (col = 0; col < 12; col += 2) 
        {
            printf("%c", str[row][col]);
        }
        for (col = 0; col < 12; col += 2) 
        {
            printf("%c", str[row][col + 1]);
        }
    }

    printf("\n");
    printf("\n");

    return 0;
}

There are a number of fundamental issues that are giving you problems. The biggest being the understanding of what a character , character array and string is in C, and how to declare/initialize each. Your pad is a single char , there are no additional dimensions required during the declaration and initialization. It is simply:

char pad = 'x';

A character array is just that multiple characters. In C, if the contents of a character array is nul-terminated , then it can be used as a string . Without the nul-termination it is simply an array of characters.

In your case, you are attempting a 2-Rail cipher with a key (number of rows of text) of 2 . Meaning you will simply stagger the characters from the name read from the user between the top-rail and bottom-rail across two lines. eg

word: ALLIGATOR
len : 12 characters max (11 char + nul-terminator)
key : 2 (number of lines of text)

0 1 2 3 4 5 6 7 8 9 10
------------------------- rail 1
A x L x G x T x R x x
x L x I x A x O x x x
------------------------- rail 2

The string you take as input need only be a single-dimension array of characters ( nul-terminated ). As such, your declaration of str , with the number of columns ( NCOL = 12 ), need only be:

char str[NCOL] = "";  /* a 12 character array initialized to 0 (empty string) */

Since your row and col variables are used as array indexes, they should properly be type int instead of type char . (that is another compiler warning)

The remainder of your code, isn't far off. There is no need for the outer row loop in your 2-Rail cipher code, iterating from 0 < 1 with only execute once.

Your padding issue is simply due to the way the rail-cipher works. For each line in key you add, you need to add that number of padding characters. (eg after the original line, for the 1st line, you add one x before the text, 2 before the second, etc..) In your case, you are simply missing one x before the line following the original. You can correct the issue here with a simple:

printf ("\nx");

between the column loops.

Putting those pieces of the puzzle together with a few more corrections (such as preventing overrun of str by a field-width limitation in scanf , etc.), you could do something like:

#include <stdio.h>

enum { KEY = 2, NCOL = 12 };  /* simple decalration of 2 constants */

int main (void) {

    char str[NCOL] = "";
    char pad = 'x';
    int row, col;

    printf ("\n****Welcome to The Caesar's Palace for Encrypted Names****\n");

    printf ("\n Please enter your name: ");
    scanf ("%11[^\n]%*c", str);

    printf (" You entered: %s\n\n", str);

    printf ("2-RAIL CIPHER ENCRYPTION:\n\n");

    for (col = 0; col < NCOL; col += KEY) {
        printf ("%c%c", str[col], pad);
    }
    printf ("\nx");
    for (col = 0; col < NCOL; col += KEY) {
        printf ("%c%c", str[col + 1], pad);
    }

    printf ("\n\n Your new name is now \n\n");

    for (col = 0; col < NCOL; col += KEY) {
        printf ("%c%c", str[col], pad);
    }
    for (col = 0; col < NCOL; col += KEY) {
        printf ("%c%c", str[col + 1], pad);
    }

    printf ("\n\nCAESAR CIPHER ENCRYPTION:\n\n");
    printf (" Your new name is now\n\n");

    for (row = 0; row < NCOL; ++row) {
        char c = str[row];
        c = (char) (c + KEY + 1);
        printf ("%c%c", c, pad);
    }

    printf ("\n");
    printf ("\n");
    printf ("The End\n");

    return 0;
}

Example Use/Output

$ ./bin/railcipher

****Welcome to The Caesar's Palace for Encrypted Names****

 Please enter your name: ALLIGATOR
 You entered: ALLIGATOR

2-RAIL CIPHER ENCRYPTION:

AxLxGxTxRxx
xLxIxAxOxxx

 Your new name is now

AxLxGxTxRxxLxIxAxOxxx

CAESAR CIPHER ENCRYPTION:

 Your new name is now

DxOxOxLxJxDxWxRxUxxxx

The End

note: I make no representations about the correctness of your CAESAR cipher and I'm no expert on rail-ciphers, but the syntax and code corrections must be dealt with before you tweak the ciphers. Look over the changes and let me know if you have any questions.

Here are what you need to do to fix your codes:

Step 1 Add a define hashtag and the include string library to the top of your code...

#include <string.h>
#define BUFFER_SIZE 100

Step 2 Replace these following members that you have...

char row, col;
char str[100][100];
char pad = 'x';

...to these ones

int col, size;
char str[BUFFER_SIZE];

Step 3: Right below your scanf, define your size with a strlen. Strlen calculates and returns to you the length of a string. Any string that you input. This is my strlen for your problem. Use it. ;)

size = strlen(str);

Step 4: From 2-Rail cipher encryption till the last printf function, replace your code to the ones below.

for (col = 0; col < size; col += 2)
    {
        printf("%c", user[col]);
    }

    printf("\n");
    for (col = 0; col < size; col += 2)
    {
        //printf("%c", user[col + 1]);

        if (col + 1 != size)
            printf("%c", user[col + 1]);
        else
            printf("x");

    }

    printf("\n");

    for (col = 0; col < size; col += 2)
    {
        printf("%c", user[col]);
    }
    for (col = 0; col < size; col += 2)
    {
        if (col + 1 != size)
            printf("%c", user[col + 1]);
        else
            printf("x");
    }

In case you need explanation, your issue was simple, you had an extra row in your C-string that the program was not using. Additionally, you needed the strlen and an if function that basically says "if you've reached the end of the character string in an array of more than 100 characters, then print an x. If you did not have that code in the program would either print nothing (as stated in your issue) or print a zero.

But, keep in mind that if you type in a super long C-string name that is more than 100+ characters and you have the x padding at the end, it will cause some memory issue. Just food for thoughts.

But from now, do these steps and your codes should work with the output you wanted. (hopefully it should). This was my ouput.

adeiea
nrdmrx

adeieanrdmrx

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM