Распечатка, сколько у каждого символа из алфавита есть файл.- С - PullRequest
0 голосов
/ 18 ноября 2018

Здравствуйте, коллеги-программисты.У меня огромная проблема с выяснением этой программы, я сидел на ней часами.Вот что мне нужно.Программа, которая вычисляет символы для каждой строки в файле.Насколько мне известно, в настоящее время у меня есть программа для расчета и печати строк, а также печати символов AZ.Кроме того, нет никакой разницы между, например, t & T, поэтому программа считает оба как T. Вот то, что я еще кодировал.

вход: Привет, я

вывод: H - 1, I -2, T - 1, S - 1, M - 1, E - 1

Но он также выведет 0 для символов, которых нет.Например, А - 0 и т. Д.

int main()
{
    FILE *fr;
    char *fname, a='A',b;
    int line = 1, lines=1,i=0,counter=0,z=0;

    //Scans file name & open it

    scanf("%s",fname);
    fr = fopen(fname,"r");

    //print out first line

    printf("  ");
    for (;a<='Z';a++) {
        printf(" %c",a);
    }
    printf("\n");

    //calculate how many lines file has

    while (fscanf(fr,"%c",&b) != EOF) {
        if (b == '\n') {
            lines++;
        }
    }

    //cycle for printing lines

    for (;line<=lines;) {
        printf("%d  ",line);

        //check till end of file

        while ((fscanf(fr,"%c",&b) != EOF)) {
            printf("%c ",a);
            //check a-z
            for (a='A';a<='Z';a++) {
                if (b == a || a+32 == b) {
                    counter++;
                }
                else if (b == '\n') {
                    line++; printf("\n");
                }

            }
            printf("%d ",counter);
            counter=0;
        }
    }
    fclose(fr);
    return 0;
}

1 Ответ

0 голосов
/ 19 ноября 2018

предложить:

для устранения любых «магических» чисел:

#define MAX_FILENAME_LEN 100
#define MAX_LINE_LEN     1024
#define MAX_CHARACTERS   256

заменить:

char *fname, a='A',b;

на:

char fname[ MAX_FILENAME_LEN ];

в противном случае, попытка прочитать имя файла в некоторую случайную память (хороший способ вызвать событие сбоя сегмента и его неопределенное поведение)

заменить:

printf("  ");
for (;a<='Z';a++) {
    printf(" %c",a);
}
printf("\n");

на:

char line[ MAX_LINE_LEN ];
fgets( line, sizeof line, fr );
printf( "%s", line );

заменить это:

scanf("%s",fname);
fr = fopen(fname,"r");

на:

if( scanf("%99s",fname) != 1 )
{
    fprintf( stderr, "scanf failed to input file name"
    exit( EXIT_FAILURE );
}
// implied else, scanf successful

fr = fopen(fname,"r");
if( !fr )
{
    perror( "fopen failed" );
    exit( EXIT_FAILURE );
}
// implied else, fopen successful

заменить

    while (fscanf(fr,"%c",&b) != EOF) {
    if (b == '\n') {
        lines++;
    }
}

на:

int lines = 1;
while( fgets( line, sizeof line, fr ) )
{
    lines++;
}
rewind( fr );

замените:

        while ((fscanf(fr,"%c",&b) != EOF)) {
        printf("%c ",a);
        //check a-z
        for (a='A';a<='Z';a++) {
            if (b == a || a+32 == b) {
                counter++;
            }
            else if (b == '\n') {
                line++; printf("\n");
            }

        }
        printf("%d ",counter);
        counter=0;
    }

на:

int counts[ MAX_CHARACTERS ];
...
// use `While()` loop with `fgets()` to read data into `line[]`
...
memset( counts, '\0', sizeof( counts ) ); 

for( int i=0; line[i]; i++ )
{
    counts[ line[i] ]++; 
}

for( int i=0; i<MAX_CHARACTERS; i++) 
{ 
    if( counts[i] ) 
    {
        printf( "%c - %i\n" , (char)i, counts[ i ] ); 
    } 
}

Возможно, вы захотите «настроить» вышеприведенное, чтобы не выводить знаки препинания, переводы строк и т. д.

Возможно, вы захотите'настройте' вышеприведенное, чтобы подсчитать как верхние, так и строчные буквы как одинаковые.Простой способ сделать это -

#include <ctype.h>

, а затем для каждого символа, выбранного из массива 'line []:

line[i] = tolower( line[i] ); 

Примечание: exit() и EXIT_FAILUREнаходятся в заголовочном файле: stdlib.h

...