Memo on strings in C and C++
0. char*
The 2 following statements are equivalent:
char s[50] = {'H', 'e', 'l', 'l', 'o', '\0'}; // 50 bytes reserved, but only the first 6 initialized
char s[50] = "Hello"; // the same.
1. null terminated char*-strings
Most operations on char* strings assume that they are terminated by a character zero:
char s[20] = {'1', '2', '\0', '4', '5', '\0'}; // length is 2
- strlen
- strcpy
- strncpy
- sprintf
- snprintf
- strcat
- strncat
- strdup
- etc.
To add the terminating zero, do this:
char myString[MAX_LENGTH+1];
myString[MAX_LENGTH] = 0;
// or
myString[MAX_LENGTH] = '\0';
Don't do that:
char myString[MAX_LENGTH+1];
myString[strlen(myString)] = 0; // wrong! because strlen needs the zero!
strcat(myString, "0"); // wrong! because strcat needs the zero!
/!\ Using memcpy for a string is error prone.
Don't do that:
char myString[100];
memcpy(myString, "12345", 5); // wrong! missing terminating zero!
2. char*-string operations
char s[100] = "123";
strcpy(s, "1234"); // 5 characters copied, including zero
strncpy(s, "1234", 4); // wrong! 4 characters copied, missing zero
strncpy(s, "1234", 5); // 5 characters copied, including zero
strncpy(s, "1234", 10); // 10 characters copied, including 6 zeros
strcat(s, "-4"); // { '1', '2', '3', '-', '4', '\0' }
strncat(s, "-4", 1); // { '1', '2', '3', '-', '\0' }
With strcat and strncat the resulting string is always null terminated.
sprintf(s, "%02X", 255); // { 'F', 'F', '\0' }
sprintf(s, "%02X", 1048575); // { 'F', 'F', 'F', 'F', 'F', '\0' }
// (not limited to 2 characters!)
snprintf(s, 4, "%02X", 1048575); // { 'F', 'F', 'F', '\0' }
// 4 characters copied
snprintf() writes at most N bytes (including the trailing null byte ('\0')).
3. sizeof
char name[100];
sizeof(name); // returns 100
char *city;
city = (char*)malloc(100);
sizeof(city); // returns the size of an integer. 4 on a 32-bit CPU.
4. Other string types
4.1 std::string (STL library)
In this paragraph, we use [ ] to represent the contents of string objects.
std::string s;
s = "abc"; // [ 'a', 'b', 'c' ] size = 3
s += "-12"; // [ 'a', 'b', 'c', '-', '1', '2' ] size = 6
s += '\0'; // [ 'a', 'b', 'c', '-', '1', '2', '\0' ] size = 7
s.c_str(); // returns a null-terminated char*, suitable for use with strcpy, strlen, etc.
s.size(); // returns the size of the string
4.1 std::ostringstream (STL library)
std::ostringstream oss;
oss << hex << 1048575 << "-" << dec << 123; // contents: "fffff-123"
std::string s = oss.str(); // converts to a std::string object
oss.str(""); // contents: ""
4.3 CString (MFC library)
CString s;
s.GetBuffer(0); // returns a null-terminated char*, suitable for use with strcpy, etc.