Как перевести первую букву строки в верхний регистр - PullRequest
0 голосов
/ 17 марта 2019

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

Мой вопрос: как мне использовать заглавные буквы первой буквы каждого предложения? Я попытался установить первую позицию в строке равной символу в этой позиции - 32, но это просто вылетало из программы.

void randomize(void) {

    char *article[] = {"the", "a", "one", "some", "any"};
    char *noun[] = {"boy", "girl", "dog", "town", "car"};
    char *verb[] = {"drove", "jumped", "ran", "walked", "skipped"};
    char *preposition[] = {"to", "from", "over", "under", "on"};
    char *sentence[6];

    int running = 1;

    while(running){

        int location = rand()%5;

        char *captFirstLetter = article[location];

        captFirstLetter[0] = captFirstLetter[0] - 32 ;

        sentence[0] = captFirstLetter;

        sentence[1] = noun[rand()%5];

        sentence[2] = verb[rand()%5];

        sentence[3] = preposition[rand()%5];

        sentence[4] = article[rand()%5];

        sentence[5] = noun[rand()%5];

        for(int i = 0; i < 7; i++){
            printf("%s%s%s", (i == 6) ? "" : sentence[i], (i > 4) ? "" : " ", (i == 5)? ".\n" : "" );
        }
        running ++;

        if(running == 21){
            running = 0;
        }
    }
}

1 Ответ

5 голосов
/ 17 марта 2019

О, нет, нет - SegFault:

Вы создаете указатель на строковый литерал с:

    char *captFirstLetter = article[location];

Вы не можете изменять строковые литералы , на которые ссылаются указатели в article. Ваша попытка изменить их, например,

    captFirstLetter[0] = captFirstLetter[0] - 32 ;

Вызывает Неопределенное поведение и, скорее всего, немедленный SegFault. Строковые литералы хранятся в постоянной памяти и не могут быть изменены (на всех, кроме самых древних и неясных аппаратных средств)

Чтобы устранить проблему, убедитесь, что строки, на которые указывает article, являются массивами, а не строковыми литералами. Например, объявите article как двумерный массив достаточного размера:

    char article[][8] = {"the", "a", "one", "some", "any"};

Кроме того, хотя вы правильно вычитаете 32, чтобы перевернуть 6-й бит (бит нижнего регистра выключен), стандартная библиотека предоставляет макрос toupper() в <ctype.h> для обработки этого случая с надлежащими проверками, чтобы гарантировать изменение регистра ограничено строчными буквами. Например:

#include <ctype.h>
...
    captFirstLetter[0] = toupper(captFirstLetter[0]);

Наконец, собрав его в коротком примере, объясняющем две проблемы выше, вы получите:

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

int main (void) {

    char article[][8] = {"the", "a", "one", "some", "any"};
    size_t n = sizeof article / sizeof *article;
    int location = 2;
    char *captFirstLetter = article[location];

    captFirstLetter[0] = toupper(captFirstLetter[0]);

    for (size_t i = 0; i < n; i++)
        puts (article[i]);
}

Пример использования / Вывод

$ ./bin/cmplitp2a
the
a
One
some
any

Дайте мне знать, если у вас есть дополнительные вопросы.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...