GotW # 29 is not case sensitive String (Case-InSitive Strings)
Difficult: 7/10
Do you expect a string type regardless of case? Your mission is that you should choose a ready-made and accept it, or write one yourself.
problem
Write a string type in isolation, which is the same as the "String" class in the standard library, just on the case, and (non-standard, but widely used) C function stricp ():
Ci_String S ("Abcde");
// case insensitive
Assert (s == "abcde");
Assert (s == "abcde");
// still case-preserving, of course
Assert (STRCMP (S.c_STR (), "ABCDE") == 0);
Assert (STRCMP (S.c_STR (), "ABCDE")! = 0);
solution
Write a string type in isolation, which is the same as the "String" class in the standard library, just on the case, and (non-standard, but widely used) C function stricp ():
"How to achieve a string type of an inordant and small-sized string" is so common, so that it requires a proprietary FAQ - so discusses it in GOTW.
Note 1: StriCMP () This distinctive string comparison function is not part of the C standard, but it is available for many C compiler extensions.
Note 2: The actual meaning of "Do not vase the case" is completely dependent on your program and national language. For example, many languages have no casements at all; but even so, you still need decision reread and non-reading characters equivalent, and so.
Below is the goal we expect: this GOTW guides how to implement "not distinguish cases" for standard String classes, no matter what you are in any context.
Ci_String S ("Abcde");
// case insensitive
Assert (s == "abcde");
Assert (s == "abcde");
// still case-preserving, of course
Assert (STRCMP (S.c_STR (), "ABCDE") == 0);
Assert (STRCMP (S.c_STR (), "ABCDE")! = 0);
The key point is to understand what the "String class" is in the standard C . If you look at the string header file, you will see the following:
Typedef Basic_String
So, String is not a real class, it is a template (special) typef. Under the next, the Basic_String <> template has declared as follows, which is the whole picture:
Template Class traits = char_traits Class allocator = allocator Class Basic_String; Therefore, "String" is actually "Basic_String If you want to have different behaviors in these operations, we have to do just provide a different char_traits template. This is the easiest way: Struct Ci_char_Traits: Public Char_Traits // Inherit in order to get the function we don't have to overload { Static Bool EQ (Char C1, Char C2) {Return Toupper (C1) == TouPper (C2); Static Bool Ne (Char C1, Char C2) {Return Toupper (C1)! = Toupper (C2); Static Bool LT (Char C1, Char C2) {RETURN TouPper (C1) Static int COMPARE (Const Char * S1, Const char * S2, SIZE_T N) { Return Memicmp (S1, S2, N); // If your compiler provides it, / / Otherwise you have to achieve one yourself. } Static const char * Find (const char * s, int N, char a) { While (n--> 0 && Toupper (* s)! = TouPper (a)) { S; } Return S; } } Finally, take them together: Typedef Basic_String We redefine a "ci_string", its operation is very like standard "string", just it replaces char_traits This GOTW reveals the working principle of the Basic_String template and the flexibility to implement. If you expect these comparison functions that don't have to be implemented above, you only need to replace these 5 functions with your own code, how to meet your own programs, how to implement them. exercise 1. Is this safe from char_traits (WQ note, this code is already compiled by C , and it is running normally!) Ci_String S = "ABC"; Cout << s << endl; Tip 1: See gotw # 19. Tip 2: Excerpt from 21.3.7.9 [lib.string.io], Basic_String Operator << operation declared as follows (it is offset): Template Basic_OStream Operator << (Basic_OStream Const Basic_String (WQ note, C standard library, now "Basic_Ostream ANSWER: Notice first that cout is actually a basic_ostream (Due to errors, it is not translated.) There are two solutions: Define CI_Strings its own inflow / outflow function, or use ".c_str ()": Cout << S.c_str () << endl; 3. What happens when using other operations (such as , =, =) between standard String objects and CI_String objects? E.g: String a = "aaa"; Ci_String B = "BBB"; String c = a b; Answer: Or, define these operations of CI_String, or use ".c_str (): String c = a b.c_str ();