Professional C__ - Marc Gregoire [247]
char* copyString(const char* inString)
{
char* result = new char[strlen(inString) + 1];
strcpy(result, inString);
return result;
}
Code snippet from CStrings\strcpy.cpp
One way to remember that strlen()returns only the number of actual characters in the string is to consider what would happen if you were allocating space for a string made up of several others. For example, if your function took in three strings and returned a string that was the concatenation of all three, how big would it be? To hold exactly enough space, it would be the length of all three strings, added together, plus one for the trailing '\0' character. If strlen() included the '\0' in the length of the string, the allocated memory would be too big. The following code uses the strcpy() and strcat() functions to perform this operation.
char* appendStrings(const char* inStr1, const char* inStr2, const char* inStr3)
{
char* result = new char[strlen(inStr1) + strlen(inStr2) + strlen(inStr3) + 1];
strcpy(result, inStr1);
strcat(result, inStr2);
strcat(result, inStr3);
return result;
}
Code snippet from CStrings\strcpy.cpp
Note that sizeof() is not the same as strlen(). You should never use sizeof() to try to get the size of a string. For example:
char text1[] = "abcdef";
size_t s1 = sizeof(text1); // is 7
size_t s2 = strlen(text1); // is 6
char* text2 = "abcdef";
size_t s3 = sizeof(text2); // is 4
size_t s4 = strlen(text2); // is 6
Code snippet from CStrings\strlen.cpp
s3 will be 4 when compiled in 32-bit mode and will be 8 when compiled in 64-bit mode because it is returning the size of a char* which is a pointer.
A complete list of C functions to operate on strings can be found in the When you use the C-style string functions with Microsoft Visual Studio, the compiler is likely to give security-related warnings about these functions being deprecated. You can eliminate these warnings by using the new C standard library functions, such as strcpy_s() or strcat_s(), which are part of the new “secure C library” standard (ISO/IEC TR 24731). However, the best solution is to switch to the C++ string class, which is discussed later in this chapter. String Literals You’ve probably seen strings written in a C++ program with quotes around them. For example, the following code outputs the string hello by including the string itself, not a variable that contains it: cout << "hello" << endl; In the preceding line, "hello" is a string literal because it is written as a value, not a variable. String literals can be assigned to variables, but doing so can be risky. The actual memory associated with a string literal is in a read-only part of memory. This allows the compiler to optimize memory usage by reusing references to equivalent string literals. That is, even if your program uses the string literal "hello" 500 times, the compiler can create just one instance of hello in memory. This is called literal pooling. The C++ standard officially says that string literals are of type “array of n const char,” however, for backward compatibility with older non-const aware code, most compilers do not enforce your program to assign a string literal only to a variable of type const char* or const char[]. They let you assign a string to a char* without const, and the program will work fine unless you attempt to change the string. Generally, attempting to change the string will immediately crash your program, as demonstrated in the following code: char* ptr = "hello"; // Assign the string literal to a variable. ptr[1] = 'a'; // CRASH! Attempts to write to read-only memory A much safer way to