Как подсчитать символы строки и назначить их разным группам (нижний и верхний регистр) в C

Я написал программу на C, которая получает строку от пользователя (50 символов — это предел) и присваивает символы верхнего регистра строке с именем upper, а символы нижнего регистра — lower, в конце концов она должна печатать эти строки (сначала upper). Моя проблема в том, что когда я ввожу строку, она печатает только одну строку (т.е. если строка начинается с верхнего символа, то будет напечатано upper) вместо двух из них.

Вот мой код:

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <time.h>
#include <math.h>

#define MAX_LEN 50

int main()
{
    char str[MAX_LEN] = { 0 };
    char upper[MAX_LEN] = { 0 };
    char lower[MAX_LEN] = { 0 };
    int i = 0;
    int j = 0;

    printf("Enter a string: ");
    fgets(str, MAX_LEN, stdin);
    str[strcspn(str, "\n")] = 0;

    for (i = 0; i < strlen(str); i++)
    {
        if (str[i] > 'A' && str[i] < 'Z')
        {
            upper[j] = str[i];
        }
        else if (str[i] > 'a' && str[i] < 'z')
        {
            lower[j] = str[i];
        }
        j++;
    }

    printf("%s", upper);
    printf("%s", lower);

    getch();
    return 0;
}

person Ma250    schedule 10.03.2017    source источник
comment
Вы используете одну и ту же индексную переменную j для нижней и верхней переменных. Используйте разные переменные для обоих.   -  person Ayush    schedule 10.03.2017
comment
Также > 'A' --› >= 'A'   -  person BLUEPIXY    schedule 10.03.2017
comment
ctype.h предоставляет значения isupper и islower, учитывающие текущую локаль.   -  person Schwern    schedule 10.03.2017
comment
@BLUEPIXY Да, ограничения также неверны для if else.   -  person Ayush    schedule 10.03.2017
comment
Вам также не нужен str[strcspn(str, "\n")] = 0;, потому что fgets() вставит NULL, а ваше объявление str[] полностью заполнит его NULL.   -  person Chimera    schedule 10.03.2017
comment
И при отладке проблем со строками это помогает заключать строку в квадратные скобки при печати, чтобы вы могли видеть, пуст ли массив символов. Что-то вроде этого: printf("\nUPPER:[%s] LOWER[%s]\n", upper,lower);   -  person Chimera    schedule 10.03.2017


Ответы (3)


Вы используете один счетчик для двух массивов. Вы увеличиваете счетчик, независимо от того, какой массив вы заполняете. В результате первая обрабатываемая буква будет определять, какой массив не будет иметь свой первый символ в качестве NULL-ограничителя строки C.

Так? Таким образом, когда вы используете printf(), он перестанет печатать при использовании %s, как только он встретит ограничитель NULL, как это делают все функции <stdio.h>. Кстати, вы забыли включить эту библиотеку.

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

Более того, используйте >= вместо >, чтобы учесть и «а». То же самое для «z» и их заглавных букв.

Собрав их все вместе, вы получите что-то вроде этого:

#include <string.h>
#include <time.h>
#include <math.h>
#include <stdio.h> // you hadn't include that!

#define MAX_LEN 50

int main()
{
    char str[MAX_LEN] = { 0 };
    char upper[MAX_LEN] = { 0 };
    char lower[MAX_LEN] = { 0 };
    int i = 0;
    int j = 0; // counter for 'upper'
    int k = 0; // counter for 'lower'

    printf("Enter a string: ");
    fgets(str, MAX_LEN, stdin);
    str[strcspn(str, "\n")] = 0;

    for (i = 0; i < strlen(str); i++)
    {
        if (str[i] >= 'A' && str[i] <= 'Z') // use the equal operator as well for reading 'A' and 'Z' as well
        {
            upper[j++] = str[i]; // increment the counter 'j'
        }
        else if (str[i] >= 'a' && str[i] <= 'z') // use the equal operator as well for reading 'a' and 'z' as well
        {
            lower[k++] = str[i]; // increment the counter 'k'
        }
    }

    // print your strings, but use a newline for aesthetics
    printf("%s\n", upper);
    printf("%s\n", lower);

    return 0;
}

Выход:

Georgioss-MacBook-Pro:~ gsamaras$ gcc -Wall main.c
Georgioss-MacBook-Pro:~ gsamaras$ ./a.out 
Enter a string: Samaras
S
amaras
person gsamaras    schedule 10.03.2017

Используйте разные индексные переменные для upper и lower, а в if-statements измените оператор > на >= и аналогично < на <=.

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <time.h>
#include <math.h>

#define MAX_LEN 50

int main()
{
    char str[MAX_LEN] = { 0 };
    char upper[MAX_LEN] = { 0 };
    char lower[MAX_LEN] = { 0 };
    int i = 0;
    int up = 0, low = 0;

    printf("Enter a string: ");
    fgets(str, MAX_LEN, stdin);
    str[strcspn(str, "\n")] = 0;

    for (i = 0; i < strlen(str); i++)
    {
        if (str[i] >= 'A' && str[i] <= 'Z')
        {
            upper[up] = str[i];
            up++;
        }
        else if (str[i] >= 'a' && str[i] <= 'z')
        {
            lower[low] = str[i];
            low++;
        }
    }

    printf("%s\n", upper);

    printf("%s", lower);

    getch();
    return 0;
}
person Yousaf    schedule 10.03.2017

Вы используете j как итератор для обоих ваших массивов. Вы этого не делаете. Если вы сделаете это, у вас может быть «\ 0» на первом месте вашего другого массива, и он не будет записан.

поэтому вы должны сделать это:

 #include <stdlib.h>
    #include <stdio.h>
    #include <string.h>
    #include <time.h>
    #include <math.h>

    #define MAX_LEN 50

    int main()
    {
        char str[MAX_LEN] = { 0 };
        char upper[MAX_LEN] = { 0 };
        char lower[MAX_LEN] = { 0 };
        int i = 0;
        int j = 0, h = 0;

        printf("Enter a string: ");
        fgets(str, MAX_LEN, stdin);
        str[strcspn(str, "\n")] = 0;

        for (i = 0; i < strlen(str); i++)
        {
            if (str[i] >= 'A' && str[i] <= 'Z')
            {
                upper[j++] = str[i];
            }
            else if (str[i] > 'a' && str[i] < 'z')
            {
                lower[h++] = str[i];
            }
        }

        printf("%s", upper);
        printf("%s", lower);

        return 0;
    }

Здесь вы повторяете свои массивы только тогда, когда добавляете одно значение. Также, как сказано в комментариях, вы должны делать str[i] >= 'A' && str[i] <= 'Z', а не str[i] > 'A' && str[i] < 'Z'

person Gabriel de Grimouard    schedule 10.03.2017