如何修改BMP转ASCII艺术字C代码,将输出保存到字符串变量
实现方案
核心逻辑是将原函数直接输出到终端的逻辑,改为写入动态分配的字符串内存中,步骤如下:
- 首先计算ASCII字符串所需的总内存大小:每行有
img->width个有效ASCII字符 + 1个换行符,共img->height -1行(和原printchar的循环逻辑完全一致),最后额外加1个字节存字符串结束符\0 - 动态分配对应大小的内存
- 把原
printchar里putchar的逻辑替换为往分配的内存中写入字符 - 返回字符串指针,调用者使用完后需手动释放内存避免泄漏
具体代码修改
1. 新增生成ASCII字符串的函数
// 生成ASCII艺术字符串,调用者需自行free返回的指针 char* generateAsciiString(image* img) { if (img == NULL || img->data == NULL) { return NULL; } // 计算所需内存大小:(每行字符数+换行符) * 行数 + 结束符 size_t lineCount = img->height - 1; size_t totalLen = (img->width + 1) * lineCount + 1; char* asciiStr = (char*)malloc(totalLen); if (asciiStr == NULL) { return NULL; } char* writePtr = asciiStr; for (size_t y = img->height - 1; y > 0; --y) { for (size_t x = 0; x < img->width; ++x) { unsigned char c = *(img->data + x + img->width * y); int rescaled = c * numScale / 256; *writePtr = scale[numScale - rescaled]; writePtr++; } *writePtr = '\n'; writePtr++; } *writePtr = '\0'; return asciiStr; }
2. 修改main函数调用逻辑
int main(int argc, char ** argv) { if (argc != 2) { puts("Argument needed: filename."); return 1; } puts(argv[1]); setbuf(stdout, 0); numScale = strlen(scale) - 1; printf("ASCII Brightness Scale: %d\n", numScale); image *img = NULL; if (loadImage(&img, argv[1])) { printf("Image dimensions: %zux%zu\n", img->width, img->height); // 生成ASCII字符串 char* asciiArt = generateAsciiString(img); if (asciiArt != NULL) { // 可直接输出验证效果,也可对字符串做其他处理比如写入文件 puts(asciiArt); // 使用完毕必须释放字符串内存避免泄漏 free(asciiArt); } release(img); } return 0; }
注意事项
- 无需删除原有的
printchar函数,两个功能可共存 - 若不需要每行末尾的换行符,只需调整内存计算逻辑、删除写入换行符的代码即可
内容的提问来源于stack exchange,提问作者EMAROH
相关产品推荐
相关产品推荐

