'toupper' и 'tolower' не влияют на массив символов в C - PullRequest
0 голосов
/ 17 февраля 2019

Я создаю функцию, которая создает имя пользователя.У пользователя спрашивают имя, затем фамилию.Фамилия соединяется с первой буквой имени.Кроме того, любая заглавная буква должна быть преобразована в строчные буквы.Таким образом, ввод 'John DoE' должен быть равен 'jdoe'.

Другая функция подсчитывает количество строчных букв в строке "У ЭТОГО ПРЕДЛОЖЕНИЯ НЕКОТОРЫЕ НИЗКИЕ СЛУЧАЙНЫЕ ХАРАКТЕРЫ".Затем строчные буквы преобразуются в прописные, и строка печатается.

Первая функция не преобразует прописные буквы в строчные.Вторая функция даже не распознает значение ASCII какого-либо символа.

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

void createUsername()
{
int j = 1;
char firstName[15], lastName[15], userName[20];

printf("Enter your first name : ");
fgets(firstName, 15, stdin);
firstName[strlen(firstName) - 1] = '\0';

printf("Enter your last name : ");
fgets(lastName, 15, stdin);
lastName[strlen(lastName) - 1] = '\0';

userName[0] = tolower(firstName[0]);

for (int i = 0, j; lastName[i] != '\0'; i++, j++)
    userName[j] = tolower(lastName[i]);
userName[j+1] = '\0';

printf("User name : %s", userName);
}

void lowerToUpperCase()
{
char sentence[] = "THiS SentENCE HAS SOMe LoWEr CASE ChARAcTERs";
int lowerCases = 0;
for (int i = 0; sentence[i] != '\0'; i++)
{
    if ((sentence[i] >= 97) && (sentence[i] <= 122))
    {
        lowerCases++;
        sentence[i] = toupper(sentence[i]);
    }
}
printf("Number of lower case characters= %d \n", lowerCases);
printf("Upper case sentence : %s \n", sentence);
}

Ожидаемый вывод Джо Смита должен быть jsmith.Количество строчных букв должно быть 10, а предложение должно печатать все заглавные буквы.

Фактический вывод дает JSMITH, количество строчных букв равно 0, а предложение печатает оригинал.

Ответы [ 2 ]

0 голосов
/ 17 февраля 2019

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

#include <ctype.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

void createUsername() {
    printf("Enter your first name : ");
    char *firstName;
    errno = 0;
    int n = scanf("%ms", &firstName);
    if (n != 1) {
        perror("scanf");
        exit(EXIT_FAILURE);
    }

    printf("Enter your last name : ");
    char *lastName;
    errno = 0;
    n = scanf("%ms", &lastName);
    if (n != 1) {
        perror("scanf");
        free(firstName);
        exit(EXIT_FAILURE);
    }

    char *userName = (char *) malloc(1u + strlen(lastName) + 1u);
    userName[0] = tolower(firstName[0]);
    char *userNameIter = userName + 1;
    char *lastNameIter = lastName;
    while ((*userNameIter = tolower((unsigned char) *lastNameIter))) {
        userNameIter++;
        lastNameIter++;
    }

    printf("User name : %s\n", userName);
    free(userName);
    free(lastName);
    free(firstName);
}

void lowerToUpperCase() {
    char sentence[] = "THiS SentENCE HAS SOMe LoWEr CASE ChARAcTERs";
    int lowerCases = 0;
    for (int i = 0;; i++) {
        unsigned char const ch = (unsigned char) sentence[i];
        if (islower(ch)) {
            lowerCases++;
            sentence[i] = toupper(ch);
        } else if (ch == '\0') {
            break;
        }
    }
    printf("Number of lower case characters = %d\n", lowerCases);
    printf("Upper case sentence : %s\n", sentence);
}
0 голосов
/ 17 февраля 2019

Давайте начнем с простых вещей, и мы пойдем оттуда:

Вы можете легко сравнить a с sentence[i].Сделайте это:

if ((sentence[i] >= 'a') && (sentence[i] <= 'z'))
{
    lowerCases++;
    sentence[i] = toupper(sentence[i]);
}

, а затем этот бит:

i < lastName[i] != '\0'

Что это, черт возьми, на земле?Если вы посмотрите на эту страницу: https://en.cppreference.com/w/c/language/operator_precedence вы увидите, что < имеет приоритет над !=.

РЕДАКТИРОВАТЬ:

for (int i = 0, j; lastName[i] != '\0'; i++, j++)

j isпереинициализируется здесь как локальная переменная для цикла for(), так что он может получить 0, но в моем случае он всегда получает мусор и setfault.Так что поставьте это:

for (int i = 0; lastName[i] != '\0'; i++, j++)

, и вы будете готовы идти.

...