16

Possible Duplicate:
C++ char* vs std::string

I'm new to C++ coming from C# but I really do like C++ much better.

I have an abstract class that defines two constant strings (not static). And I wondered if a const char* would be a better choice. I'm still getting the hang of the C++ standards, but I just figured that there really isn't any reason why I would need to use std::string in this particular case (no appending or editing the string, just writing to the console via printf).

Should I stick to std::string in every case?

Wilfred Hughes
  • 29,846
  • 15
  • 139
  • 192
Noah Roth
  • 9,060
  • 5
  • 19
  • 25
  • Yes, it is quite versatile and you have the whole algorithm set to help you. If you use a char you may have to write the same method which already exists. Shortens your work process. – DumbCoder Jun 07 '12 at 18:37
  • 7
    I disagree with `printf` vs `cout`. I find C++ I/O to be a bit ugly, rather ungainly, and quite fragile with it's hidden globals. – David Hammen Jun 07 '12 at 18:40
  • @DavidHammen: Agreed. There are safe versions of C I/O routines, and C++ (STL) I/O is just a confusing mess. – Ed S. Jun 07 '12 at 18:49
  • 2
    @DavidHammen Hidden globals? The only thing that occurs to me is the locale stuff, but it's C i/o which has that whereas C++ streams get their own private copies at construction time. What else is there? – bames53 Jun 07 '12 at 18:55
  • 1
    @bames53 All of the std::ios_base junk. It's a convoluted and verbose mess, and changes are permanent (e.g., global) until you explicitly make another change. – David Hammen Jun 07 '12 at 20:20
  • @DavidHammen Okay, I understand what you mean now but I wouldn't use the term 'global' just because a stream object is stateful. – bames53 Jun 07 '12 at 20:41

5 Answers5

12

Should I stick to std::string in every case?

Yes.

Except perhaps for a few edge cases where you writing a high performance multi-threaded logging lib and you really need to know when a memory allocation is going to take place, or perhaps in fiddling with individual bits in a packet header in some low level protocol/driver.

The problem is that you start with a simple char and then you need to print it, so you use printf(), then perhaps a sprintf() to parse it because std::stream would be a pain for just one int to string. And you end up with an unsafe and unmaintainable mix oc c/c++

Martin Beckett
  • 94,801
  • 28
  • 188
  • 263
  • 15
    I think an explanation is warranted – Ed S. Jun 07 '12 at 18:34
  • 2
    There are 2 big exceptions to this: Binary data, and C interop. When it comes to binary data, especially considering that you are going to be using `write` rather than `<<`, etc., `char*`s are better. And if you're using OS APIs, you need `char*`s. Also, `char*`s give you easier control over the memory allocation. – Linuxios Jun 07 '12 at 18:45
  • Binary data should use std::vector if you are calling a C function convert to c string at that point, same as calling a Win32 COM function. – Martin Beckett Jun 07 '12 at 18:46
  • @MartinBeckett: Again, sometimes you want control over exact allocation, etc. Disclaimer: All of the C++ programming I've done has basically been C and the POSIX API, just taking advantage of exceptions and classes. I've barely used the STD lib. – Linuxios Jun 07 '12 at 18:57
  • @Linux_iOS.rb.cpp.c.lisp.m.sh if you are programming 'C' then using C strings makes sense. "I need exact control over...." is often necessary in fewer cases than you would think. – Martin Beckett Jun 07 '12 at 19:14
  • @MartinBeckett: I understand that. I happened to be doing POSIX network programing, and I want to control allocation to the byte. – Linuxios Jun 07 '12 at 19:16
  • @Linux_iOS.rb.cpp.c.lisp.m.sh - yes, as I said in the answer. If these are really "bytes" use char[] or vector, if they are "text" AND you are doing c++ there is no reason not to use string (in the vast majority of cases). A lot of new c->C++ programmers think std::stringstream looks complicated, I'll stick to printf() and claim I need it for control/performance reasons. – Martin Beckett Jun 07 '12 at 19:20
  • @MartinBeckett: I know. I just do almost all byte (not text) processing, and because it is sent in a formatted network packet, it tells me how many bytes I need. – Linuxios Jun 07 '12 at 19:24
6

I would stick to using std::string instead of const char*, simply because most of the built-in C++ libraries work with strings and not character arrays. std::string has a lot of built-in methods and facilities that give the programmer a lot of power when manipulating strings.

Z. Charles Dziura
  • 933
  • 4
  • 18
  • 41
4

Should I stick to std::string in every case?

There are cases where std::string isn't needed and just a plain char const* will do. However you do get other functionality besides manipulation, you also get to do comparison with other strings and char arrays, and all the standard algorithms to operate on them.

I would say go with std::string by default (for members and variables), and then only change if you happen to see that is the cause of a performance drop (which it won't).

K-ballo
  • 80,396
  • 20
  • 159
  • 169
  • 1
    The most important feature you get is a known size. The standard algorithms do work on `char const*`, btw, as long as you have a size. – R. Martinho Fernandes Jun 07 '12 at 18:37
  • 1
    Another caveat is interacting with a legacy C API. – Oliver Charlesworth Jun 07 '12 at 18:37
  • 1
    http://stackoverflow.com/questions/801209/c-char-vs-stdstring - There are is a wealth of additional information in this question and the subsequent answers – joverboard Jun 07 '12 at 18:38
  • 3
    @Oli Charlesworth: Luckily we have `c_str()` for that. – K-ballo Jun 07 '12 at 18:38
  • @joverboard: Good information, I will vote to close this question as a duplicate. – K-ballo Jun 07 '12 at 18:38
  • @K-ballo: That's doesn't work in all situations. e.g. if the C API modifies a user-supplied buffer. Although that's usually a trivial work around by copying to and from a `vector` or something (at which point we're back to a performance argument...) – Oliver Charlesworth Jun 07 '12 at 18:38
  • @Oli Charlesworth: Oh that's true... luckily its been ages since I were in that situation and I forgotten about that. For those cases we have `std::vector< char >`. – K-ballo Jun 07 '12 at 18:39
  • Re *I would say go with std::string by default (for members and variables), and then only change if you happen to see that is the cause of a performance drop (which it won't).* I suggest changing the latter to clarity instead of performance. Performance is only an issue when it becomes one. Clarity of the code is almost always an issue. – David Hammen Jun 07 '12 at 18:42
1

Use std::string when you need to store a value.

Use const char * when you want maximum flexibility, as almost everything can be easily converted to or from one.

Mark Ransom
  • 299,747
  • 42
  • 398
  • 622
1

This like comparing Apples to Oranges. std::string is a container class while char* is just a pointer to a character sequence.

It really all depends on what you want to do with the string.

Std::string on the other hand can give you a quick access for simple string calculation and manipulation function. Most of those are simple string manipulation functions, nothing fancy really.

So it basically depends on your needs and how your functions are declared. The only advantage for std::string over a char pointer is that it doesnt require a specific lenghth decleration.

Zaid Amir
  • 4,727
  • 6
  • 52
  • 101