3

I am currently working on a project that when given a main function which calls another function confab(), outputs a serious of characters. The question refers to some made up race. They choose an integer nRows between 2 and half the length of the message, e.g. a message of length 11 would allow values of nRows in the range 2 to 5. The message is then written down the columns of a grid, one character in each grid cell, nRows in each column, until all message characters have been used. This may result in the last column being only partially filled. The message is then read out row-wise.

For example the message "Don't wait until the last day before starting" with a nRows of 3 would return:

D'wtnlhltabo ai.ota t ea yersrnn iuit sd fettg

I have written code that does this fairly efficiently, however I have been provided with a test case that i cannot seem to work out.

 char buffer[8] = {'*','*','*','*','*','*','*','*',};
confab("ABCDEF.", 3, buffer);
printf("%s\n", buffer);

Is this example, and the output it should give is:

AD.BECF

However my code returns:

AD.BECF*

Due to the extra * in the outText buffer not being replaced with a character. I have tried many things such as removing this extra *, or re initializing the outText to be the same length as the inText (within the code as the main case provided is not allowed to be edited), however nothing thus far has made a difference.

I was wondering if there would be a quick edit I could apply to my code that would perform this change, as I cannot seem to find a way apart from editing the main input which is not allowed.

My code is as follows:

/*
 * Confabulons.c
 * A program to encode for the Confabulons
 *
 * August 8th 2015
 */

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

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

void confab(const char inText[], int nRows, char outText[])
{
    int count = 0;
    int i = 0;
    int z = 0;
    int len = strlen(inText);

    while (z < nRows)
    {
        while (((int)inText[count] > 0) && (count < len))
        {
            outText[i] = inText[count]; 
            i ++;
            count = count + nRows;
        }
        z ++;
        count = z;
    }
}
2
  • 2
    I suppose you are using 0-terminated strings. In that case, do actually 0-terminate it. Commented Aug 8, 2015 at 8:43
  • 1
    OT: Please note that strlen() returns size_t not int. Commented Aug 8, 2015 at 9:03

2 Answers 2

4

At the end of the function add line:

outText[i] = '\0';
Sign up to request clarification or add additional context in comments.

Comments

1

You need to validate the length of the outText string, try:

void confab(const char inText[], int nRows, char outText[])
{
    int count = 0;
    int i = 0;
    int z = 0;
    int len = strlen(inText);
    int lenOut = strlen(outText);

    while (z < nRows)
    {
        while (((int)inText[count] > 0) && (count < len))
        {
            outText[i] = inText[count]; 
            i ++;
            count = count + nRows;
        }
        z ++;
        count = z;
    }
    if (i < lenOut) {
        outText[i] = '\0';
    }
}

6 Comments

Given outText refers to char buffer[8] = {'*','*','*','*','*','*','*','*',}; then this int lenOut = strlen(outText); will fail miserably.
If you suggest this condition, that it should be at the beginning of the function! if (lenIn <= lenOut) {fprintf(stderr,"not sufficient length of output"); exit(-1);}
Yes Andrew, you are right, the validations of both lengths must be applied at the beginning
Because buffer is not 0-terminated, as strlen() expects the memory being referenced by its argument to be. If the terminating '\0' is not found, strlen() will search for it out of buffer's bounds and with this invokes the infamous Undefined Behaviour, anything could happen then, including your assumed bahaviour.
You're right, I haven't touched c code for many years and it's good remember this kind of things, thanks alk.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.