Converting to uppercase in C++

这一生的挚爱 提交于 2019-12-08 04:20:14

问题


Let's say you have:

const char * something = "m";

How would one make this uppercase, using toupper (or something else, if applicable)?

I want to use a char * instead of a string (I can use a string, but then I have to use str.c_str()).

So, how can I make char * something = "m"; contain "M"?


回答1:


I find you choice of C strings disturbing.. but anyway.

You can't change a string literal (char *something). Try an array:

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

To change an entire string:

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

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



回答2:


As explained in the very famous C book - The C Programming Language by Kernighan & Ritchie in section 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, in C, to convert to upper case letters, you can use the following program as a reference.

#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;
}

In 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: Adding pointer version (as requested by @John) for the C version

#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;
}

Hope it helps!




回答3:


You can use the same algorithmic approach that you know for std::string for raw arrays:

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

You cannot do this for immutable string literals (like const char * s = "hello world;") for obvious reasons, so you won't get around an additional allocation/copy for that.

Update: As Ildjarn says in the comment, it's important to note that string literals are always read-only, even though for historical reasons you are allowed to bind them to a pointer-to-mutable, like char * s = "hello world";. Any decent C++ compiler should slap you in the face if you attempt this, but it is valid C++ -- but any attempt to actually modify any element of s is undefined behaviour.




回答4:


You can convert C-string to std::string and then use boost::to_upper to change string in place or boost::to_upper_copy to create upper case copy of the string. Here is the code example:

#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;
}

Hope this helps.




回答5:


You could do:

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

char test[] = "m";

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

This applies the ::toupper function to character of the string. This is the ::toupper function in the global namespace that comes from C. std::toupper has multiple overloads and ::toupper looks more elegant than static_cast<int (*)(int)>(&std::toupper).



来源:https://stackoverflow.com/questions/8693990/converting-to-uppercase-in-c

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!