Преобразование в верхний регистр в C ++ - PullRequest
1 голос
/ 01 января 2012

Допустим, у вас есть:

const char * something = "m";

Как можно сделать этот верхний регистр, используя toupper (или что-то еще, если применимо)?

Я хочу использовать вместо char *string (я могу использовать строку, но тогда я должен использовать str.c_str()).

Итак, как я могу сделать char * something = "m"; содержать "M"?

Ответы [ 5 ]

6 голосов
/ 01 января 2012

Я считаю, что выбор строк C вызывает беспокойство ... но в любом случае.

Вы не можете изменить строковый литерал (char *something).Попробуйте массив:

char something[] = "m";
something[0] = toupper(something[0]);

Чтобы изменить всю строку:

char something[] = "hello";
char *p = something;

while (*p) {
    *p = toupper(*p);
    p++;
}
4 голосов
/ 01 января 2012

Как объяснено в очень известной книге C - The C Programming Language на Kernighan & Ritchie в разделе 5.5 Character Pointers and Functions,

char amessage[] = "now is the time";    /* an array */
char *pmessage = "now is the time";     /* a pointer */

`amessage` is an array, just big enough to hold the 
sequence of characters and `'\0'` that initializes it. 
Individual characters within the array may be changed 
but `amessage` will always refer to the same storage. 
On the other hand, `pmessage` is a pointer, initialized 
to point to a string constant; the pointer may subsequently 
be modified to point elsewhere, but the result is undefined
if you try to modify the string contents.

OTOH, в C, для преобразования в заглавные буквы, вы можете использоватьСледующая программа в качестве справки.

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

int main(void)
{
    int i=0;
    char str[]="Test String.\n";
    char c;

    while (str[i]) {
        c=str[i];
        putchar(toupper(c));
        i++;
    }

    return 0;
}

В C ++

#include <iostream>
#include <string>
#include <locale>
using namespace std;

int main ()
{
    locale loc;

    string str="Test String.\n";

    for (size_t i=0; i<str.length(); ++i)
        cout << toupper(str[i],loc);

    return 0;
}

РЕДАКТИРОВАТЬ: Добавление версии указателя (в соответствии с запросом @John) для версии C

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

int main(void)
{
    int i=0;
    char str[]="Test String.\n";
    char *ptr = str;

    while (*ptr) {
        putchar(toupper(*ptr));
        ptr++;  
    }   

    return 0;
}

Надеюсь, поможет!

4 голосов
/ 01 января 2012

Вы можете использовать тот же алгоритм, который вы знаете для std::string для необработанных массивов:

char s[] = "hello world";
std::transform(s, s + std::strlen(s), s, static_cast<int(*)(int)>(std::toupper));

Вы не можете сделать это для неизменяемых строковых литералов (например, const char * s = "hello world;") по понятным причинам, поэтому вы не сможете обойтись без дополнительного выделения / копирования для этого.

Обновление: Как говорит Илджарн в комментарии, важно отметить, что строковые литералы всегда только для чтения, хотя по историческим причинам вам разрешено связывать их с указатель на изменяемый, как char * s = "hello world";. Любой приличный компилятор C ++ должен дать вам пощечину, если вы попытаетесь это сделать, но он является допустимым C ++ - но любая попытка фактически изменить любого элемента s является неопределенным поведением.

1 голос
/ 01 января 2012

Вы можете преобразовать C-строку в std :: string и затем использовать boost :: to_upper, чтобы изменить строку на месте, или boost :: to_upper_copy, чтобы создать копию строки в верхнем регистре.Вот пример кода:

#include <iostream>
#include <boost/algorithm/string/case_conv.hpp>

int main ()
{
  char const * s = "Test String.\n";
  std::string str(s);

  std::cout << boost::to_upper_copy(str).c_str() << std::endl;

  return 0;
}

Надеюсь, это поможет.

0 голосов
/ 29 декабря 2015

Вы можете сделать:

#include <algorithm>
#include <iterator>
#include <ctype.h>

char test[] = "m";

std::transform(std::begin(test), std::end(test), std::begin(test), ::topper);

Это применяет функцию ::toupper к символу строки.Это функция ::toupper в глобальном пространстве имен, происходящем из C. std::toupper имеет несколько перегрузок, а ::toupper выглядит более элегантно, чем static_cast<int (*)(int)>(&std::toupper).

...