2

Although I know that converting const char * to char * is almost banned in C/C++ because of many problems, I am caught up in a situation where I think I have to convert const char * to char *.

I get a string from a text file as string by using c_str and I want to modify this string. However the problem is that c_str converts string into const char *. So is it a good choice to use strdup in this case or is there any better idea in doing this?

das-g
  • 9,718
  • 4
  • 38
  • 80
wannaqc
  • 21
  • 3
  • 3
    Don't use `c_str`. Use `&s[0]`. – Kerrek SB Jul 31 '16 at 11:36
  • 1
    The best way is to copy, modify copy and then create a new string. Of course this guarantees correctness at a performance cost. You may also do the previous comment if you keep the same length. Shortening is implementation defined, lengthening is undefined. – Paul Stelian Jul 31 '16 at 11:38
  • Thanks a lot! and yes, I will keep the same length. @KerrekSB Why is using &s[0] better than c_str? – wannaqc Jul 31 '16 at 11:44
  • That depends on how you are going to use the modified string. Do you need the modified string as std::string, or you need it as an old C string? – user31264 Jul 31 '16 at 11:46
  • @user31264 I actually need std::string. My way of doing this was by extracting char* from the string, modifying it, and then declaring new string with the modified char*. I came up with this idea because I had to modify sparsely located characters which seems to be inefficient if I use replase function. – wannaqc Jul 31 '16 at 11:52
  • What is `replase function`? Also, are you allowed to modify the existing string, and not need to create a new one? – PaulMcKenzie Jul 31 '16 at 12:06
  • @PaulMcKenzie I actuall meant replace. Sorry for causing confusion – wannaqc Jul 31 '16 at 12:11
  • @wannaqc - if you need std::string, don't mess with old C strings. Aconcagua's solution is good, I upvoted it. – user31264 Aug 01 '16 at 01:20

2 Answers2

2

Actually, you can modify the std::string object directly, as illustrated in the little program below:

int main()
{
    std::string s("Hello World");
    for(char& c : s)
    {
        c = toupper(c);
    }
    s[0] = 'h';
    s[6] = 'w';
    s.resize(12);
    s[11] = '!';
    std::cout << s;
    return 0;
}

I think, it is self-explaining. Although you mentioned that size does not change, I added an example for that case, too, see resize. There are yet other ways to manipulate the string, such as insert. Have a look at the std::string documentation.

Aconcagua
  • 24,880
  • 4
  • 34
  • 59
0

Why is using &s[0] better than c_str?

std::basic_string class has data() and c_str(). However, as you know, these function's result type is const CharType*(CharType: char, wchar_t, char16_t, char32_t).

There is two way to get CharType*.

  1. use const_cast. However, this is very dirty and break type system.
  2. use &s[0]. operator[] does not break type system.

    #include <string>
    #include <type_traits>
    int main(){
        std::string s1 = "Hello world";
        static_assert(std::is_same<char&, decltype(s1[0])>::value, "err");
        static_assert(std::is_same<char*, decltype(&s1[0])>::value, "err");
        const std::string s2 = "Hello world";
        static_assert(std::is_same<const char&, decltype(s2[0])>::value, "err");
        static_assert(std::is_same<const char*, decltype(&s2[0])>::value, "err");
    }
    
yumetodo
  • 1,147
  • 7
  • 19