Как сделать гистограмму в C? - PullRequest
0 голосов
/ 31 марта 2010

Я написал программу, которая печатает целые числа в том же порядке, что и ввод, с 5 числами в строке. То есть первые 5 целых чисел будут напечатаны в первой строке; следующие 5 целых чисел в следующей строке; и так далее. Я также пытался распечатать числа в формате гистограммы, например,

81-105 ( 1) x
56-80 ( 5) xxxxx
6-11(5) xxxxx
-1-5 (3) xxx

Моя программа:

cntr=0;
 while (fscanf(in, "%d", &a[i]) != EOF)
   {i++;

 fprintf(out, "%d-%d (%d) %s\n", A, B, k, x, cntr);
 fprintf(out, "%d\n", k, cntr);

    fprintf(out, "x", a[i]);
    i++;
   }

   fprintf(out, "1864-2336 (%d)%s\n", k, x);
   fprintf(out, "1391-1863 (%d)%s\n", k, x);
   fprintf(out, "918-1390 (%d)%s\n", k, x);
   fprintf(out, "445-917 (%d)%s\n", k, x);
   fprintf(out,"-28-444 (%d)%s\n", k, x);
    fclose(in);
    fclose(out);
return 0;
}

Ответы [ 3 ]

2 голосов
/ 31 марта 2010

Вам не нужно использовать цикл, чтобы распечатать ваши иксы. Вы можете объявить одну строку x, которая соответствует максимальному количеству, которое вам понадобится, а затем использовать спецификацию размера в вызове printf, чтобы контролировать, сколько печатается. Вот простой пример, чтобы проиллюстрировать, что я имею в виду:

#include <stdio.h>
#include <string.h>

int main(void)
{
  char maxBar[] = "xxxxxxxxxx";
  size_t i;

  for (i = 0; i < strlen(maxBar); i++)
  {
    printf("%lu: %-*.*s\n", (unsigned long) i, strlen(maxBar), i, maxBar); 
  }
  return 0;
}

Вывод должен выглядеть следующим образом:

0: __________          
1: x_________
2: xx________
3: xxx_______
4: xxxx______
5: xxxxx_____

и т. Д., Где _ представляет пробел.

A * в спецификаторе преобразования printf указывает, что спецификация ширины поля или точности передается в качестве аргумента printf. Запись

printf("%-*.*s\n", 10, 2, "test");

- это то же самое, что и запись

printf("%-10.2s\n", "test");

, что, читая слева направо, означает

  1. -: выравнивание по левому краю для вывода
  2. 10: минимальная ширина поля составляет 10 символов
  3. .2: Точность (максимальное количество напечатанных символов) составляет 2

Таким образом, вывод выглядит как

te________

, где _ представляет символ пробела.

Итак, если вы знаете, насколько большим должен быть ваш бар заранее, вы можете написать что-то вроде

for (i = 0; i < k; i++)
{
  printf("%d-%d (%d) %*.*s\n", lo[k], hi[k], ct[k], strlen(maxBar), ct[k], maxBar);
}
0 голосов
/ 31 марта 2010

Есть много способов сделать это

Кажется, вы уже где-то объявили массив значений, которые вводит пользователь. а []

Для того, чтобы вычислить гистограмму, которую вы могли бы после того, как пользователь ввел все значения, отсортируйте этот массив (например, с помощью qsort ()), затем просмотрите массив, проверяя количество одинаковых значений в массиве - это будет число из * для распечатки

Я думаю, вы должны сначала позволить пользователю ввести значения, а затем сделать вывод.

Код, который вы показываете, выглядит неправильно, например, Вы увеличиваете 'i' дважды в цикле while. Вы используете a [i] после приращения, поэтому у него не будет прочитанного значения.

Также полезно использовать fgets / atoi вместо того, чтобы читать числа таким образом, чтобы неверные числа не приводили к аварийному завершению вашей программы.

0 голосов
/ 31 марта 2010

просто сделайте цикл, чтобы вывести необходимое вам количество х

   fprintf(out, "1864-2336 (%d)%s\n", k, x);
   for(x=k;x>0;x--)
      fprint(out,"%s","x");
   fprintf(out,"\n");

Ура! * * 1004

/ B2S

...