gpt4 book ai didi

c - 在C中基于stdin绘制#的垂直图

转载 作者:行者123 更新时间:2023-11-30 14:59:21 24 4
gpt4 key购买 nike

我编写了一个程序,它从 stdin 读取整数值,用一个或多个空格或换行符分隔,直到到达 EOF。输入将包含不超过 80 个值。

在标准输出上,我想根据输入值创建一个简单的垂直柱形图,按从左到右的顺序,使用哈希 # 字符。每列打印的哈希数等于相应的输入值。

已完成的列上方的区域填充有空格字符。

到目前为止,我已经做到了这一点,并且对于 4 个或更多数字的输入它可以正常工作,但是当我输入 2 或 3 个数字时,我会遇到段错误。谁能明白为什么吗?

#include <stdio.h>
#include <stdlib.h>

int main(int argc, const char*argv) {

int arr[80];
int count=0;
int i,j;

while(1) {
if((scanf("%d", &arr[count++]))==EOF) {
break;
}
}
int max=arr[0];
for(i=0; i<count; i++) {
if(max<arr[i]) {
max=arr[i];
}
}

char **matrix;
matrix=(char**)malloc(max*sizeof(char*));

for(i=0;i<count;i++) {
matrix[i]=(char*)malloc(sizeof(char)*max);
}

for(i=0;i<count-1;i++) {
for(j=max-1;j>=0;j--) {
if(max-j<=arr[i]) {
matrix[j][i]='#';
}
else {
matrix[j][i]=' ';
}
}
}

for(i=0;i<max;i++) {
for(j=0;j<count;j++) {
printf("%c", matrix[i][j]);
}
printf("\n");
}

return 0;
}

最佳答案

问题在于 OP 分配了足够的内存来存储 max * max 个字符(其中 max 是输入的最大值),而他们需要的是 如果只允许正数,则 max * count(其中 count 是输入的值的数量)。

此外,程序还会泄漏内存,因为缺少正确的 free 调用。

处理内存管理的一种更简单的方法(如果 OP 可以使用符合 C99 的编译器进行编译)是使用可变长度数组:

char matrix[rows][cols];        // where rows and cols aren't known at compile time

如果 VLA 不是一个选项,内存仍然可以连续分配:

#include <stdlib.h>

char **matrix = malloc(rows * sizeof(*matrix));
if ( !matrix )
exit(EXIT_FAILURE);
matrix[0] = malloc(rows * cols * sizeof(**matrix));
if ( !matrix[0] ) {
free(matrix);
exit(EXIT_FAILURE);
}
for ( int i = 1; i < rows; ++i )
matrix[i] = matrix[i - 1] + cols;

// do something with 'matrix'...

free(matrix[0]);
free(matrix);

另一个潜在的问题是,负责输入的循环不会将输入的值的数量限制为缓冲区的大小 (80),也不检查这些值是否确实是数字。

以下是完整的工作实现(带有一些辅助函数):

#include "stdio.h"
#include "limits.h"

#define MAX_ARR_SIZE 80

int min (int a, int b) {
return a < b ? a : b;
}

int max (int a, int b) {
return a > b ? a : b;
}

void draw_bar_chart (FILE *out_stream, char fill_char,
int *arr, int size,
int bottom, int top);

int read_ints (FILE *in_stream,
int *arr, int size,
int *min, int *max);

int main(void) {
int min_value, max_value;
int values[MAX_ARR_SIZE];
int n_values = read_ints(stdin, values, MAX_ARR_SIZE,
&min_value, &max_value);
// Avoid clipping the chart
int top_view = max(max_value, 0);
int bottom_view = min(min_value, 0);

draw_bar_chart(stdout, '#', values, n_values, bottom_view, top_view);
}

int read_ints (FILE *in_stream,
int *arr, int size,
int *min, int *max) {
int count = 0;
*min = INT_MAX;
*max = INT_MIN;
// Reads up to 'size' values to avoid buffer overflow.
while ( count < size && fscanf(in_stream, "%d", &arr[count]) == 1 )
{ // note that it stops when the read fails (EOF or not an int) ^^^^
if ( arr[count] > *max )
*max = arr[count];
if ( arr[count] < *min )
*min = arr[count];
++count;
}
return count;
}

void tidy_up (int a, int b, int *min, int *max) {
if ( a > b ) {
*min = b;
*max = a;
} else {
*min = a;
*max = b;
}
}

void draw_bar_chart (FILE *out_stream, char fill_char,
int *arr, int size,
int bottom, int top) {
int draw_height = top - bottom;
int i, j, start, end;

// VLA, requires a C99 compliant compiler
char canvas[draw_height][size + 1];
// null-terminates every row to make output easier
for ( i = 0; i < draw_height; ++i )
canvas[i][size] = '\0';
// The "drawing" can be done in many ways...
for ( j = 0; j < size; ++j ) {
tidy_up(top, top - arr[j], &start, &end);
for ( i = 0; i < start; ++i )
canvas[i][j] = ' ';
for ( ; i < end; ++i )
canvas[i][j] = fill_char;
for ( ; i < draw_height; ++i )
canvas[i][j] = ' ';
}

for ( i = 0; i < draw_height; ++i ) {
fprintf(out_stream, "%s\n", canvas[i]);
}
}

例如,给出这些输入

1 5 6 9 8 7 3 2 0 -3 -8 -5 -4 1 1 2 0 1 q

输出:

   #
##
###
####
#####
#####
######
####### #
######## ### #
####
####
####
###
##
#
#
#
<小时/>

值得注意的是,对于这个特定的任务,我们根本不需要使用临时的二维数组。负责打印图表的函数可以这样实现:

void draw_bar_chart (FILE *out_stream, char fill_char,
int *arr, int size,
int bottom, int top) {
int start, end;
// "draws" the chart by determining if the current position is inside a bar
for ( int i = top - 1; i >= bottom; --i ) {
for ( int j = 0; j < size; ++j ) {
tidy_up(0, arr[j], &start, &end);
putc((i >= start && i < end ? fill_char : ' '), out_stream);
}
puts("");
}
}

关于c - 在C中基于stdin绘制#的垂直图,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42821484/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com