-2

I've written a small program to concatenate a string "20746865" upto 300 characters. The program is as follows:

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

void main()
{
char test[] = {'2','0','7','4','6','8','6','5'};
char crib[300];
int i, length = 0;
 while(length <= 299)
  {
     for(i=0; i<8;i++)
      {
        crib[length] = test[i];
        i=i%8;
        length++;
      }

  }
crib[length]='\0';
printf("%s", crib);
}

The following is the output:

2074686520746865207468652074686520746865207468652074686520746865207468652074686520746865207468652074686520746865207468652074686520746865207468652074686520746865207468652074686520746865207468652074686520746865207468652074686520746865207468652074686520746865207468652074686520746865207468652074686520746865

However, when i count the number of characters in the output, it shows 304 characters. Could someone help me understand how can it print 304 characters if the array size is only 300?

seriousgeek
  • 992
  • 3
  • 13
  • 29

3 Answers3

1

The bug in your code is that the inner loop continues even when the written index is out of bounds, which causes it to continue until the next multiple of 8 generating undefined behavior.

Unlike previous replies, this version compiles and works according to your description using C99, minimizing the number of copies and iterations.

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

static const size_t OUTPUT_SIZE = 300U;
static const char   INPUT[]     = {'2','0','7','4','6','8','6','5'};
static const size_t INPUT_SIZE  = sizeof(INPUT);

int main()
{
    char output[OUTPUT_SIZE + 1];
    const size_t numIter = OUTPUT_SIZE / INPUT_SIZE;
    size_t idx = 0;

    // copy full chunks
    for (; idx < numIter; idx++)
    {
        memcpy(output + idx * INPUT_SIZE, INPUT, INPUT_SIZE);
    }

    // write the remainder
    memcpy(output + numIter * INPUT_SIZE, INPUT, OUTPUT_SIZE % INPUT_SIZE);

    // add null terminator
    output[OUTPUT_SIZE] = '\0';

    printf("result: %s\nlength: %d\n", output, strlen(output));

    return 0;
}

I hope this helps.

Artoo
  • 116
  • 7
0

You have undefined behavior here. You defined crib as type char[300], but you are indexing it at position 300 when you write crib[length] = '\0'. So it's not clear that your string is actually being null terminated.

Chris Beck
  • 15,614
  • 4
  • 51
  • 87
0

You don't make any provision to see if the for loop will kick the length beyond the threshold, but instead only check in the while loop every 8 characters to see if it's already long enough/too long. After 38 complete outer loops, therefore, it hits exactly 304 characters and terminates, since 304 is not <= 299.

What you should probably do is avoid having two loops at all. Instead, keep a loop index and a calculated rolling index based on that. Untested:

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

void main() {
    char test[] = {'2','0','7','4','6','8','6','5'};
    char crib[301];
    for (int i = 0, j = 0; i < 300; i++, j = i % 8) {
        crib[i] = test[j];
    }
    crib[length]='\0';
    printf("%s", crib);
}
Nathan Tuggy
  • 2,237
  • 27
  • 30
  • 38