所以我做了一个RLE实现来从矩阵中将字符绘制到控制台,但是由于某种原因,print_chars();
函数似乎覆盖了应该显示的字符数量,我只在矩阵中设置了8个大于0的值,但是它打印出来的像是30。我相信这可能是由于分配了太多的内存,但是我不知道。任何帮助都是感激的。
代码:
#include <stdio.h>
#include <time.h>
#include <windows.h>
#define sizeX 150
#define sizeY 40
int grid[sizeY][sizeX];
void colorChar(int r, int g, int b){
printf("\x1b[48;2;%d;%d;%dm",r,g,b);
}
void draw_screen(){
int y, x;
for(y=0;y<sizeY;y++){
for(x=0;x<sizeX;x++){
if(grid[y][x] == 0){
colorChar(0,0,0);
printf(" ");
}
else{
colorChar(255,255,255);
printf(" ");
}
}
printf("\n");
}
}
int main(void) {
int x, y;
float frameTime;
grid[19][19] = 1;
grid[2][8] = 1;
grid[15][12] = 1;
grid[6][3] = 1;
grid[13][16] = 99;
grid[17][3] = 1;
grid[6][6] = 1;
grid[9][3] = 1;
clock_t start = clock();
draw_screen();
clock_t stop = clock();
frameTime = (float)(stop - start) / CLOCKS_PER_SEC;
printf("Frame: %f\n", frameTime);
}
2条答案
按热度按时间myss37ts1#
我将对
print_chars
的调用替换为调试printf
:这将输出:
简而言之,
if
语句中的条件被满足了 * this * 多次,所以函数被调用了 * that * 多次,打印了 * that * 许多字符串。我的建议是重新思考并简化你的逻辑。我真的不能给出任何额外的建议,因为我真的不明白你想要达到什么目的。我不知道你期望
print_chars
被调用多少次。如果你希望它只在grid[y][x] > 0
时被调用,那么为什么不把它用作if
条件呢?变量counter0
,counter1
和counter2
对我来说真的很混乱。补充意见:
SetStdHandle()
修改过标准输出句柄,那么您可以"缓存"GetStdHandle(STD_OUTPUT_HANDLE)
的返回值,而不是反复调用.HANDLE stdout_handle = GetStdHandle(STD_OUTPUT_HANDLE);
或类似函数。"RED"
这样的原始字符串在双等于比较中会"衰减"成一个指向该字符串的指针。正如**@Some Programmer Dude**所说,这个函数起作用的唯一原因是你调用这个函数时使用的字符串是byte-wise与要与之比较的字符串常量相同,并且编译器足够聪明,能够将两个示例解析为相同的(很可能是只读的)内存地址。在我看来,你要处理这个问题的方式,最好是使用enum color { GREEN, RED, BLUE, WHITE, BLACK, YELLOW };
或类似的东西。if(color == "GREEN") { ... } else if(color == "RED") { ...
这样的if-else-if链时,你可能会找到一种方法来使用一个开关大小写的结构来代替,但是不要感到有压力,这主要是为了风格。malloc
你的缓冲区,你应该做malloc(sizeof(char)*(size + 1))
。这不是严格必要的,因为sizeof(char)
将永远是1
,除非在 * 非常奇怪 * 的情况下,但我提到它,因为你指定sizeof(char)
。int y, x;
内联到for
循环中,如for(int y=0; ...
和for(int x=0; ...
。sizeX
和sizeY
是"宏",在编译时被扩展。您应该考虑将grid
声明为int grid[sizeX][sizeY];
,以便更好地使用这些宏。还可以考虑将它们重命名为SIZE_X
和SIZE_Y
-似乎大多数C/C ++程序员都将宏设置为CAPSLOCKED_WITH_UNDERSCORES,以便更好地将它们与标识符区分开来。color /?
,它会显示对应于cmd调色板中颜色的十六进制代码。您可以插入一个两位数的十六进制代码(就像color
命令一样!)转换为SetConsoleTextAttribute
,就像SetConsoleTextAttribute(conout_handle, 0xA0);
一样,可以在黑色背景上获得明亮的绿色前景。还要注意的是,更现代的cmd版本并不 * 真的 * 受16-您也可以使用虚拟终端转义序列来指定颜色,并且\e[38;2;r;g;bm
和\e[48;2;r;g;bm
转义支持任意的r,g,b三元组。qacovj5a2#
我相信我已经解决了这个问题,你可以分层打印屏幕,而不是打印所有的东西,我们使用
goTo()
函数去任何需要打印值的地方,然后在那里运行算法,这样就避免了打印所有的0。代码: