我写了一个小程序来连接一个字符串“20746865”,最多300个字符。该计划如下:
#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);
}
以下是输出:
2074686520746865207468652074686520746865207468652074686520746865207468652074686520746865207468652074686520746865207468652074686520746865207468652074686520746865207468652074686520746865207468652074686520746865207468652074686520746865207468652074686520746865207468652074686520746865207468652074686520746865
但是,当我计算输出中的字符数时,它会显示304个字符。有人可以帮我理解如果数组大小只有300,它怎么能打印304个字符?
答案 0 :(得分:1)
代码中的错误是即使写入的索引超出界限,内部循环仍会继续,这会导致它继续直到下一个8的倍数生成未定义的行为。
与以前的回复不同,此版本使用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;
}
我希望这会有所帮助。
答案 1 :(得分:0)
这里有未定义的行为。您将crib
定义为char[300]
类型,但在撰写300
时,您正在将其编入索引crib[length] = '\0'
。所以不清楚你的字符串实际上是否为空终止。
答案 2 :(得分:0)
您没有做出任何规定来查看for
循环是否会超出阈值,而是只检查while
循环每8个字符以查看它是否&# 39; s已经足够长/太久了。因此,在38个完整的外部循环之后,它会精确地命中304个字符并终止,因为304不是&lt; = 299。
你应该做的是避免两个循环。相反,保持循环索引和基于此的计算滚动索引。未测试的:
#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);
}