2016-11-16 2 views
0

У меня проблема. Мне нужны функции в tool.c файл для цикла всего лишь несколько раз. Например, он останавливается после цикла через весь ввод. Мой учитель сказал, что я должен передать второй аргумент, но класс закончился, и я не знаю, как это должно выглядеть.Установка числа циклов

main.c

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

int main(int argc, char *argv[]) { 
    int count[256] = { 0 }; 
    int c; 
    while ((c=getchar())!=EOF){ 
     count[c]++; 
    } 
    switch (argc > 1 && argv[1][1]) { 
    case 'm': case 'M': 
     mostOften(count); 
     break; 
    case 'l': case 'L': 
     leastOften(count); 
     break; 
    default: 
     mostOften(count); 
     break; 
    } 
    return 0; 
} 

tools.c

#include <stdio.h> 
#include <stdlib.h> 
#include <limits.h> 
#include "tools.h" 

void mostOften(int *s) { 
    int j, a = 0; 
    int max=0, cha; 
    for(j=32; j<126; j++){ 
     if(s[j]>max) { 
       max=s[j]; 
       cha=j; 
     } 
    a++; 
    } 
    printf("char %c: %d times\n", cha, max); 
} 

void leastOften(int *s) { 
    int j, a = 0; 
    int min=INT_MAX, cha; 
    for(j=32; j<126; j++){ 
     if(s[j] && s[j]<=min) { 
       min=s[j]; 
       cha=j; 
     } 
    a++; 
    } 
    printf("char %c: %d times\n", cha, min); 
} 

Например, если я вход

пункт

Я хочу, чтобы петля только 9 раз, в основном мне нужно установить некоторые, если Постулаты остановить зацикливание

+3

Сохраните 'case 'm': case 'M':' в отдельных строках. –

+2

'switch (argc> 1 && argv [1] [1]) {' должен быть 'if (argc> 1) switch (argv [1] [1]) {' – BLUEPIXY

+0

Измените свой вопрос и покажите нам пример вход и ожидаемый выход. –

ответ

0

Вашей главной программа первые строит гистограмму персонажей, которые появляются на входе, а затем ищет его либо наиболее частый или наименее часто печатаемый характер.

Если вы хотите избежать этого второго цикла (фазы поиска), вам необходимо постепенно обновлять индекс самого или наименее частого символа каждый раз, когда символ читается.

Вот пример:

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

int main() 
{ 
    int count[256] = { 0 }; 
    int c; 
    int index_min = -1; 
    int min = INT_MAX; 
    int index_max = -1; 
    int max = INT_MIN; 

    while ((c = getchar()) != EOF) { 
     if (isprint (c)) { 
      count[c]++; 

      // update min 
      if (count[c] < min) { 
       min = count[c]; 
       index_min = c; 
      } 

      // update max 
      if (count[c] > max) { 
       max = count[c]; 
       index_max = c; 
      } 
     } 
    } 

    printf ("least common printable char: "); 
    if (index_min != -1) { 
     printf ("`%c` (%d times)\n", index_min, min); 
    } 
    else { 
     printf ("N/A\n"); 
    } 

    printf ("most common printable char: "); 
    if (index_max != -1) { 
     printf ("`%c` (%d times)\n", index_max, max); 
    } 
    else { 
     printf ("N/A\n"); 
    } 

    return 0; 
} 
+0

Нет ничего плохого в инициализации массива 'int count [256] = {0};' Замена этого на цикл 'for' не дает никакой пользы (хотя он также не дает никакого ущерба) –

0

Глядя на то, как у вас есть настройки проблемы, это выглядит, как вы путаете Перебор символов, которые являются частью входных данных, а массив, который содержит частоту прочитанных символов.

Во-первых, чтобы сделать ваш код доступным для чтения, не используйте магические числа в своем коде, например. 32 и 126. Вместо этого используйте символы, которые вы пытаетесь представить, например. (space) и ~ (tilde). Например, вместо использования:

for(j=32; j<126; j++){ 

вы можете использовать:

for(j = ' '; j < '~'; j++){ 

Это тоже имеет это подводные камни. Зачем? Вы не хотите перебирать символы, вы на самом деле хотите перебрать элементы в вашем массиве count, которые содержат частоту, которую каждый символ встречает на входе. Другими словами, вам нужен массив, содержащий как минимум 95 целые числа, которые будут содержать частоту, которую каждый символ встречается на вашем входе. Поскольку вы знаете, как могут быть символы, которые будут, не затушевывайте его за 32 до 126, просто объявите константу для вашего размера массива (может быть, называется ARSZ) в tools.h, например.

#define ARSZ 95 

Затем после прочтения ввода и заполнения count массива, это просто вопрос итерации над count массивом один раз, чтобы получить либо mostoften или leastoften номер.Кроме того, поскольку у вас есть константа для числа элементов в count, вам не нужно передавать размер count в mostoften и leastoften - вы уже знаете, сколько элементов присутствует, 95. (См ниже примечание на перебор только над символами, присутствующих на входе)

(если размер массива не является постоянным (и вы не передавая массив с дозорными, как NUL завершающих строки ) или номером элементов, которые нужно перебрать, неизвестно во время компиляции, тогда вам нужно передать размер массива в функции.

(и еще один отскок в сторону, C обычно использует все строчные буквы для имен переменных, сохраняя все верхние регистры для констант и макросов. Обычно вы не увидите MixedCase или camelCase имена переменных в C, оставьте это для C++)

Далее, в то время как вы должны использовать getopt для обработки аргументов командной строки, вы можете воспользоваться быстрым взломом проверки второго символа аргументов, но вам нужно проверить, что у вас есть хотя бы один аргумент, чтобы проверить, и что Аргумент не является пустой строкой. В принципе, вы хотите проверить:

if (argc > 1 && *argv[1]) /* check argc & not empty-string */ 
    switch (argv[1][1]) { 
     case 'm': 
      mostoften (count); 
      break; 
     case 'M': 
      mostoften (count); 
      break; 
     case 'l': 
      leastoften (count); 
      break; 
     case 'L': 
      leastoften (count); 
      break; 
     default: 
      fprintf (stderr, "warning: unrecognized option, using 'mostoften'.\n"); 
      mostoften (count); 
    } 
else { 
    fprintf (stderr, "warning: no option given using 'mostoften'.\n"); 
    mostoften (count); 
} 

примечание: вы не можете поставить две постоянные условия вместе ни для одного случая вашего switch (некоторые компиляторы предоставляют нестандартные расширения). Также обратите внимание: вам не нужен break в корпусе default, нет возможности проскока.

Собираем в целом, вы можете написать свой tools.h похожие на:

#include <stdio.h> 
#include <limits.h> 

#define ARSZ 95 

int mostoften (int *a); 
int leastoften (int *a); 

Ваш tools.c как:

#include "tools.h" 

int mostoften (int *a) { 

    int i, max = INT_MIN, cha = '0'; 

    for (i = 0; i < ARSZ; i++) 
     if (a[i] > max) { 
      max = a[i]; 
      cha = i + ' '; 
     } 

    printf ("char '%c' : %d times\n", cha, max); 

    return max; 
} 

int leastoften (int *a) { 

    int i, min = INT_MAX, cha = '0'; 

    for (i = 0; i < ARSZ; i++) 
     if (a[i] < min) { 
      min = a[i]; 
      cha = i + ' '; 
     } 

    printf ("char '%c' : %d times\n", cha, min); 

    return min; 
} 

Вы знаете, что если max или min то же самое для 2-х различных персонажей , вы выберете первый, а в случае leastoften вы всегда будете выбирать первый символ с частотой 0. Чтобы исправить эту проблему, вам нужно будет сохранить второй массив (или 2D-массив или структуру), который отслеживает, какие символы присутствуют на входе, и учитывать частоту этих символов.

Наконец, ваш main.c может быть написано что-то вроде:

#include "tools.h" 

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

    int c = 0, count[ARSZ] = {0}; 

    while ((c = getchar()) != EOF) 
     if (' ' <= c && c <= '~') 
      count[c - ' ']++; 

    if (argc > 1 && *argv[1]) /* check argc & not empty-string */ 
     switch (argv[1][1]) { 
      case 'm': 
       mostoften (count); 
       break; 
      case 'M': 
       mostoften (count); 
       break; 
      case 'l': 
       leastoften (count); 
       break; 
      case 'L': 
       leastoften (count); 
       break; 
      default: 
       fprintf (stderr, "warning: unrecognized option, using " 
           "'mostoften'.\n"); 
       mostoften (count); 
     } 
    else { 
     fprintf (stderr, "warning: no option given using 'mostoften'.\n"); 
     mostoften (count); 
    } 

    return 0; 
} 

Есть много различных способов выполнения этой задачи, но учитывая свой исходный код, это держит с, казалось бы, ваши намерения. Посмотрите, и дайте мне знать, если у вас возникнут вопросы. Если вам нужен самый простой способ отслеживания символов, присутствующих на вашем входе, без использования структуры, просто сделайте объявление count как count[ARSZ][2] и используя дополнительный элемент, чтобы указать, какие символы присутствовали. (вы можете передать массив своим функциям как int a[][2] или int (*a)[2]) Удачи.

Смежные вопросы