Подсчет символов в файле в шестнадцатеричном формате

#c

#c

Вопрос:

Я пытаюсь подсчитать количество символов в файле и отобразить их в шестнадцатеричном формате. Пример:

5 экземпляров ‘a’

‘n’ экземпляров ‘,’

Я не хочу выводить символы, которые не появились в файле и, следовательно, не в моем массиве. Я хотел бы вывести экземпляры, которые находятся в файле.

Я не уверен, как печатать для каждого экземпляра, который произошел, поскольку я не хочу выводить ‘0’ экземпляров ‘something’.

 #include <stdio.h>

int main(int argc, char const *argv[]) {
    int c;
    FILE *f = fopen(argv[1], "r");
    int totalchars[256] = { 0 };
    while ((c = getc(f)) != EOF) {
        if (totalchars[c] == 0)
            totalchars[c] = 1;
        else
            totalchars[c]  ;

    } // while

    for (int i = 0; i < 256; i  )
        printf("%d instances of character %xn", totalchars[i], c);

    return 0;
}
  

Я знаю, что при печати c находится в конце файла, поэтому он будет печатать ffffffff. Я не уверен, как вывести то, что я хочу.

Комментарии:

1. всегда проверяйте (!= NULL) возвращаемое значение из fopen() , чтобы убедиться, что операция прошла успешно

2. никогда не заходите дальше, argv[0] не проверив argc , действительно ли был введен параметр командной строки.

Ответ №1:

Во-первых, вам не нужно

 if (totalchars[c] == 0)
    totalchars[c] = 1;
else
    totalchars[c]  ;
  

Просто скажите

 totalchars[c]  ;
  

Добавление 1 изменит 0 на 1 точно так же, как это изменит (скажем) 5 на 6. Я предполагаю, что вы поместили if (totalchars[c] == 0) тест здесь, потому что вы не хотели печатать количество символов, равное 0, но оно неуместно. (Смотрите ниже.)

Во-вторых, вам нужно

 for(int i = 0; i < 256; i  )
    printf("%d instances of character %xn", totalchars[i], i);
  

чтобы для каждого из (до) 256 слотов в массиве вы печатали символ, который подсчитан для этого слота ( i ), а не повторяли последний символ EOF, который вы прочитали из файла ( c ).

Наконец, когда вы распечатываете массив, пришло время проверить количество символов, равное 0, и подавить их. Итак, это будет выглядеть следующим образом:

 for(int i = 0; i < 256; i  ) {
    if(totalchars[i] != 0) {
        printf("%d instances of character %xn", totalchars[i], i);
    }
}
  

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

         printf("%d instances of character %x: %cn", totalchars[i], i, i);
  

Однако у этого есть небольшой недостаток, заключающийся в том, что он будет пытаться печатать специальные символы, такие как пробел, табуляция и перевод строки, как сами по себе, что не всегда будет выглядеть правильно.

Комментарии:

1. @guy Я думал, ты хочешь это в шестнадцатеричном формате! Но смотрите мой исправленный ответ.

2. Незначительный, лучше использовать UCHAR_MAX 1 , чем 256. Как минимум, он самодокументируется.

3. это для нулевого символа?

4. @guy Нет, это для возможности использования компьютера с чем-то иным, чем 8-битные байты, что означает что-то иное, чем 256 символов.

Ответ №2:

Вы используете неправильную переменную, будьте осторожны при копировании и вставке

 printf("%d instances of character %cn", totalchars[i], i);
/*                                                      ^
 *                                   should be `i' not `c'
 */