String vs char arrays

Started by
23 comments, last by MaulingMonkey 15 years, 5 months ago
Quote:Original post by MikeTacular
The rule of thumb is to use std::string whenever possible. It's part of "good" C++. Checking user input (or any other form of text) is going to be a lot easier if it's a std::string rather than a char array. Example:
std::string name = getSomeName();if (name == "Bob"){    doSomething();}char* name = getSomeName();if (strcmp(name, "Bob") == 0){    doSomething();}


You tell me which of the two is cleaner (if you say the second one you're crazy [smile]).



hehe. I remember bits and pieces from my studies for my computer science degree. One of them was about ambiguity when overloading the "==" operator for comparision operations, because its C++ it could mean anything you like. Using the function strcmp described a little more about what the function did. For example in the first example its unclear (if you had never seen the string library before) whether the comparison is case sensitive or otherwise (I guess you could argue the same case for the second example, but at least the comparison is a little more descriptive as too what it is comparing).

also, when I was learning Java and was confronted with string classes, I got very frustrated with the higher level of abstraction it provided; I felt it was a little too much away from "just storing some numbers in an array". Of course they're big advantages to the string class, but sometimes a char array will do. I hate having to trawl through documentation detailing how to get an ascii character number out of a string when I've forgotten the function name, or visa versa when I know its probably stored as an ascii number anyway. (I know, because I'm the one who put it there)

I do truely believe there is nothing wrong with a char array, as there is nothing wrong with using the string class to store strings; its all about abstraction and who provides that abstraction, the api or the programmer. A bad programmer (or one of little understanding of how a string is interpreted by the hardware) is going to misuse a char array. If somebody looks over my code and frowns at my char array, and the only answer they can give as too why its bad is to say "you should be using the std:string class instead"; I'd like to belt them into submission until I get a more rational explanation out of them. One method should be used against the other when you're sure you know the differences and why you have choosen the method.

rant over.
http://www.fotofill.co.uk
Advertisement
Quote:Original post by moosedude
One of them was about ambiguity when overloading the "==" operator for comparision operations, because its C++ it could mean anything you like.

That argument never gets old, does it? :)
Operator overloading doesn't involve more ambiguity than using functions. strcmp could do ANYTHING as well.

Quote:Original post by moosedude
Of course they're big advantages to the string class, but sometimes a char array will do.

There's so many differences, I don't know where to start... for example, Strings are immutable in Java, char arrays are not.

Quote:Original post by moosedude
I hate having to trawl through documentation detailing how to get an ascii character number out of a string when I've forgotten the function name

That's where operator overloading kicks in.

std::string s = "hello";
char c = s[4]; // awesome, isn't it?

Unfortunately, Java doesn't provide operator overloading, so you have to call the member function get(index) or something. Just write "s." and then press Ctrl+Space in Eclipse, you'll find the function pretty quickly.

Quote:Original post by moosedude
I do truely believe there is nothing wrong with a char array

Arrays are second class citizens in C and C++ which means you cannot pass them to functions, you cannot return them from functions, and you cannot assign them. Doesn't that bother you at all?
Use std::string unless it's not available.
I tend to be in disagreement when people say use std::string all the time, being bitten by string classes before because of memory fragmentation. First commercial project I worked on everyone has abused the string class all over, and last resort was to make it use its own heap for allocation, which needed to be 8MB! On a PS2, that is a pretty big chunk of memory to lose to strings!

Though I will say, developing for PC? Use std::string, or whatever string class you want if you want. I'll personally stick with char arrays so I know I'm in control!
Adventures of a Pro & Hobby Games Programmer - http://neilo-gd.blogspot.com/Twitter - http://twitter.com/neilogd
Like many of the standard container classes, std::basic_string has an allocator type parameter.
Quote:Original post by rip-off
Like many of the standard container classes, std::basic_string has an allocator type parameter.


Still potentially gives you unnessisary memory overhead - A heap size of 64k does NOT give you a total of 64kb to play with, depends entirely on the number of allocations.

However on the other side of the argument, it could save you memory as you won't be allocating nearly as much as needed - but the heap you've created to allocate from is typically going to be a fixed max size, which would need to cater for worst case anyways.

PS: I normally won't go and tell anyone to use std::string or char arrays because one is better - simply because I don't really believe either is globally 'better'. I actually avoid ALL STL in my engine and game code as I prefer to be in full control of memory and keep allocation count to a minimum. In my toolchain - I don't care, I allocate freely, use STL, and don't worry myself since I want convenience there.
Adventures of a Pro & Hobby Games Programmer - http://neilo-gd.blogspot.com/Twitter - http://twitter.com/neilogd
- Do you need to modify strings?
- If the are modified, how?
- What is the life-cycle of your strings?
- What interoperability do you need (C fallback or similar)
- What are the characteristics of your memory?
- What type of computing power do you have?
- What are the usage patterns for your strings?
- What about internationalization?
- Which methodology are users of the code most familiar with?
- Which can you afford, how much will improper choice cost?
- Are you aware of portability issues of basic_string and even const char *?
- Is serialization/persistence important?

And more....

After understanding the implications of your entire problem domain, one can make an informed decision over which is optimal.

Note that either choice meets only a small number of above requirements. Sometimes neither is directly usable. Often, std::string is good enough, and covers more ground than plain char strings.
Quote:Original post by Richy2k
I'll personally stick with char arrays so I know I'm in control!

I'd prefer to write a fixed-length equivalent of std::string than piss all control over invariants (like keeping the string NUL terminated) into the wind, which is exactly what using char arrays directly would do.
Quote:everyone has abused the string class all over

You'll get bitten by anything if you abuse it enough.

[Edited by - MaulingMonkey on November 8, 2008 12:31:27 PM]
Quote:Original post by moosedude
One of them was about ambiguity when overloading the "==" operator for comparision operations, because its C++ it could mean anything you like. Using the function strcmp described a little more about what the function did. For example in the first example its unclear (if you had never seen the string library before) whether the comparison is case sensitive or otherwise (I guess you could argue the same case for the second example, but at least the comparison is a little more descriptive as too what it is comparing).

While you could overload the operators to do something weird, why would you? Any sane programmer is going to make their overloaded operators logical. And since the STL is made by good programmers, any noob could easily guess correctly what == does. strcmp() is no more descriptive than ==. In ==, you know you are testing if one string is equal to another. strcmp() compares two strings. How is strcmp() more descriptive than ==? Besides, strcmp returns an integer, not a boolean, and dealing with -1, 0, and 1 when testing equality is much more cryptic than a simple true/false.

Quote:Original post by moosedude
also, when I was learning Java and was confronted with string classes, I got very frustrated with the higher level of abstraction it provided; I felt it was a little too much away from "just storing some numbers in an array". Of course they're big advantages to the string class, but sometimes a char array will do. I hate having to trawl through documentation detailing how to get an ascii character number out of a string when I've forgotten the function name, or visa versa when I know its probably stored as an ascii number anyway. (I know, because I'm the one who put it there)

I personally am not a big fan of Java's string class implementation. Why? Because I like my operator overloading :). But this is C++ we are talking about, and even though some of the details are abstracted away in std::string, std::string gives you all the power and access you need if you want to go to a lower level. But in both C++ and Java, isn't abstraction kind of the whole point of OOP?

Quote:Original post by moosedude
I do truely believe there is nothing wrong with a char array, as there is nothing wrong with using the string class to store strings; its all about abstraction and who provides that abstraction, the api or the programmer. A bad programmer (or one of little understanding of how a string is interpreted by the hardware) is going to misuse a char array. If somebody looks over my code and frowns at my char array, and the only answer they can give as too why its bad is to say "you should be using the std:string class instead"; I'd like to belt them into submission until I get a more rational explanation out of them. One method should be used against the other when you're sure you know the differences and why you have choosen the method.

Yes, I agree that there are definitely times where a char array is perfectly acceptable. If what you really need is a char array and not a whole string class, then go ahead and use a char array. But std::string is often simpler, cleaner, and more elegant. For this reason people should try to use std::string if they can, but if they can't it's not the end of the world.
[size=2][ I was ninja'd 71 times before I stopped counting a long time ago ] [ f.k.a. MikeTacular ] [ My Blog ] [ SWFer: Gaplessly looped MP3s in your Flash games ]
Quote:Original post by MaulingMonkey
I'd prefer to write a fixed-length equivalent of std::string than piss all control over invariants (like keeping the string NUL terminated) into the wind, which is exactly what using char arrays directly would do.


I was actually tempted to do this, however I'd prefer to keep a template parameter for maximum size, rather than just have, say, 1024 as maximum size, which would make performing comparisons via ==, or any other operation, difficult. Probably possible and easy, but as of now, I don't know how to make the following work:

MyString< 128 > StringA;MyString< 256 > StringB;if( StringA == StringB ){    // ...}


Quote:Original post by MaulingMonkey
You'll get bitten by anything if you abuse it enough.


Agreed [smile] But to prevent it happening with strings, I've strayed away for the meantime. Well, I lie slightly...as they are technically used inside of Python since I bind that to my engine and framework, however, high level string manipulation in a high level language is how I'll keep it for now.

Actually, I'll mention another reason I stick to char arrays personally. This is not a reason to stick entirely to them, but a reason to use them where you might have once considered using std::string:

struct CsResource{	BcU32					ResourceType_;		// 4	BcChar					ResourceName_[128];	// 132	BcU32					ResourceID_;		// 136	BcU32					DataOffset_;		// 140	BcU32					DataSize_;			// 144	void*					pActualResource_;	// 148	// Pad to 32 bytes	BcU8					Padding_[12];};


CsResource is a structure stored in a file, packed tightly into an array of x amount of resources. Using char arrays, I don't need to mess about with varying length strings. (Just before someone points out, yes I know void* is not nessisarily fixed size, its something I'm busy fixing in my engine for 64-bit compatibility)
Adventures of a Pro & Hobby Games Programmer - http://neilo-gd.blogspot.com/Twitter - http://twitter.com/neilogd

This topic is closed to new replies.

Advertisement