Accounting for missing existing characters as C inputs

Sorry if the title of the question went off a bit, I had no idea what to call it because this is such a strange question. What I am going to do is decode the input string, encoded using a method that I will explain in a bit, into plain English text. Encoding is done by choosing an integer nRows between 2 and half the message length, for example. a message of length 11 will allow nRows values ​​in the range 2 to 5. The message is then written to the grid columns, one character in each grid cell, nRows in each column, until all message characters have been used. This can result in the last column being only partially filled. Then the message is read line by line. For example, if the input message was ALL HAIL CAESAR and the nRows value is 2, the encoding would look like this:

A L H I   A S R
L   A L C E A @

      

Where @ stands for a blank character in the table that doesn't really exist - I just added it to explain the next part :)

The actual question I have is decoding these phrases. The code I've written so far works for a few problems, but as soon as the empty characters (@) get a lot, the code starts to degrade as the code obviously doesn't register them and the algorithm jumps past them. My code:

/*
 * DeConfabulons.c
 * A program to Decode for the Confabulons
 * 
 * August 9th 2015
 */

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

//A simple function confab which given input text encoded using
//the Confabulons encoding scheme, and a number of rows, returns 
//the originally encoded phrase.

void deconfab(const char inText[], int nRows, char outText[])
{
    int count = 0;
    int i = 0;
    int len = strlen(inText);
    float help = ((float)len/(float)nRows);
    int z = 0;
    while (z < round(help))
    {
        while (((int)inText[count] > 0) && (count <= len))
        {
            outText[i] = inText[count]; 
            i ++;
            if (count < (int)help)
            {
                count = count + round((int)help+0.5);
            }
            else
            {
                float helper = count + help;
                count = round(helper);
            }  


        }
        z ++;
        count = z;
    }
    outText[i] = '\0';
}

      

Which still works with the Caesar example I gave earlier. The coded form was ALHI ASRL ALCEA. The main (void) input I provided for this problem was:

char buffer[40] = {'\0'};
deconfab("ALHI ASRL ALCEA", 2, buffer);
printf("%s\n", buffer);

      

Which correctly outputs:

ALL HAIL CAESAR

      

However, when dealing with cases with extra blanks such as:

char buffer[60] = {0};
char* s = "Two hnvde eo frgqo .uxti hcjeku  mlbparszo y";
deconfab(s, 13, buffer);
printf("%s\n", buffer);

      

The output should be:

The quick brown fox jumps over the lazy dog.

      

However, my code will return:

Thdefq.the browneorouickmps ov  g x julazy

      

I've come to the conclusion that this is caused by a blank character at the end of the last column after going through several manual tests, however no matter what I try, the code won't work for every test case. I am allowed to almost completely edit the main function, however any inputs or anything in int main (void) cannot be edited. I'm just looking for a way to have these blank characters recognized as non-actual characters (as such) :)

+3


source to share


3 answers


First of all, as far as I can see, you are not including these "null" characters in your input - if you did (I think) by adding any "dummy" characters, the algorithm will work. The reason why this is done in the first case is that there is no "empty" character at the end of the input - the same place as in the sentence.

You can try to do a workaround by guessing the length of the message with these dummy characters (I'm not sure how to phrase it), for example: ALHI ASRL ALCEA

has 15 characters (15 mod 2 = 1) but ALHI ASRL ALCEA@

has 16 characters. Likewise, it Two hnvde eo frgqo .uxti hcjeku mlbparszo y

has 44 characters (44 mod 13 = 5), so you need quite a lot of dummy characters to do this job (13-5 = 8).



There are several ways at this point: you can, for example, try to insert missing spaces to align columns, copy everything into a two-dimensional char to char array and then read it line by line, or just define characters (len mod rows) from the last column, remove them from input (it takes some fiddling with classic C string strings so I don't give you a complete answer here), read the rest, and then added characters from the last column.

Hope this helps.

+2


source


There is some confusion with the index calculation. At first, this is a purely discrete transformation. Thus, it should be implemented using only integers. The function below does what you need.

void deconfab(const char inText[], int nRows, char outText[])
{
    int len = strlen(inText);
    int cols = len / nRows;
    int rows_with_large_cols = len % nRows;
    int count = 0;
    int col = 0;
    int row = 0;

    while (count < len)
    {
        int idx;
        if (row < rows_with_large_cols)
            idx = row * (cols + 1) + col;
        else
            idx = rows_with_large_cols * (cols + 1) +
                (row - rows_with_large_cols) * cols + col;

        if (idx > len - 1) {
            ++col;
            row = 0;
            idx = col;
        }

        outText[count] = inText[idx];
        ++row;
        ++count;
    }
    outText[count] = '\0';
}

      



It can be rewritten more beautifully. Now it's like pseudocode to explain the algorithm.

+2


source


You cannot use standard functions str*

if you are going to handle zeros. Instead, you should work directly with the data and use a family of functions *read

to get your data.

0


source







All Articles