简体   繁体   English

C 程序显示的字符数超过数组大小

[英]C program displaying more characters than array size

I've written a small program to concatenate a string "20746865" upto 300 characters.我编写了一个小程序来连接最多 300 个字符的字符串“20746865”。 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.但是,当我计算输出中的字符数时,它显示 304 个字符。 Could someone help me understand how can it print 304 characters if the array size is only 300?有人能帮我理解如果数组大小只有 300,它如何打印 304 个字符吗?

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.您的代码中的错误是即使写入的索引超出范围,内部循环也会继续,这会导致它继续直到下一个 8 的倍数生成未定义的行为。

Unlike previous replies, this version compiles and works according to your description using C99, minimizing the number of copies and iterations.与之前的回复不同,此版本使用C99根据您的描述编译和工作,最大限度地减少了副本和迭代次数。

#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.我希望这有帮助。

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' .您将crib定义为char[300]类型,但是当您编写crib[length] = '\\0'时,您将其索引到位置300 So it's not clear that your string is actually being null terminated.所以不清楚你的字符串实际上是空终止的。

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.您没有做任何规定来查看for循环是否会超出阈值的长度,而是每 8 个字符检查一次while循环以查看它是否已经足够长/太长。 After 38 complete outer loops, therefore, it hits exactly 304 characters and terminates, since 304 is not <= 299.因此,在 38 个完整的外部循环之后,它正好命中 304 个字符并终止,因为 304 不是 <= 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);
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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