2012-01-01 4 views
1

C++ Допустим, у вас есть:Преобразование в верхний регистр в

const char * something = "m"; 

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

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

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

+5

Нет, используйте 'std :: string'. И выберите язык: нет такой вещи, как «C/C++». –

+0

И что вы хотите делать с 'char something [] =" \ xEF \ xAC \ x83 ";'? (то есть ffi) – ybungalobill

ответ

6

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

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

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

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

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

while (*p) { 
    *p = toupper(*p); 
    p++; 
} 
+0

В нем говорится: инициализатор не может определить размер «input» const char * input = «m»; char something [] = input; что-то [0] = toupper (что-то [0]); char * p = something; – John

+0

@John Это не то, что я сказал :-) Прочтите ответ еще раз. Еще лучше, посмотрите на ответ Керрекса. – cnicutar

+0

'p' здесь посторонний - используйте только« что-то », и пример будет намного более ясным IMO. – ildjarn

4

Вы можете использовать один и тот же алгоритмический подход, который вы знаете, для 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;") по понятным причинам, поэтому для этого вам не понадобится дополнительное выделение/копия.

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

+3

Я думаю, что, возможно, стоит объяснить более глубокое, почему 'char * s =" hello world; "', sans 'const', также неизменен - ​​это первичное зависание для новичков. – ildjarn

+0

@ DietmarKühl: Хорошая точка; вы, вероятно, должны использовать версию 'toupper', которая поставляется с' 'для более общего решения. –

+0

@ DietmarKühl: Никто не может идти в ногу с сумасшедшими немцами :-) Теперь у них * есть * есть [столичный SZ] (http://en.wikipedia.org/wiki/Capital_ß), но он не может быть представлен символом 'char '... * sigh * –

4

Как объяснен в очень известной 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. 

Ото, в 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; 
} 

EDIT: Добавление версии указателя (по желанию @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; 
} 

Надеется, что это помогает!

+0

как у вас есть указатель внутри массива? – John

+0

@ Джон, не могли бы вы рассказать о своем вопросе ?! Вы имеете в виду, как иметь указатель на массив? –

+0

@SangeethSaravanaraj, когда вы передаете 'char' в C toupper и другие функции, принимающие символ в' int', он должен быть сначала брошен в unsigned char, а затем в 'int'. – AProgrammer

1

Вы можете преобразовать 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

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

#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).