Skip to content

Commit 379ff5e

Browse files
authored
Merge pull request #29 from urboob21/dev_branch
id 1765122409
2 parents 4861c40 + 07d126a commit 379ff5e

2 files changed

Lines changed: 204 additions & 0 deletions

File tree

CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,7 @@ set(APP_SOURCES
9797
"src/core/datatypes/class/CDestructors.cpp"
9898
"src/core/datatypes/class/SallowDeepCopying.cpp"
9999
"src/core/datatypes/class/RoleOfThreeFiveZero.cpp"
100+
"src/core/string/CString.cpp"
100101
"src/patterns/structural/Adapter.cpp"
101102
"src/patterns/structural/Bridge.cpp"
102103
"src/patterns/structural/Proxy.cpp"

src/core/string/CString.cpp

Lines changed: 203 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,203 @@
1+
#include <string.h>
2+
#include <iostream>
3+
4+
namespace {
5+
6+
namespace InitializeString {
7+
void run() {
8+
// Memory layout (addresses are illustrative):
9+
10+
// Stack (modifiable array)
11+
// 0x7fffc000: str2[0] = 'H'
12+
// 0x7fffc001: str2[1] = 'e'
13+
// 0x7fffc002: str2[2] = 'l'
14+
// 0x7fffc003: str2[3] = 'l'
15+
// 0x7fffc004: str2[4] = 'o'
16+
// 0x7fffc005: str2[5] = '\0'
17+
// (str2 starts at 0x7fffc000)
18+
19+
// Data / Read-only segment (string literal)
20+
// 0x00403000: 'H'
21+
// 0x00403001: 'e'
22+
// 0x00403002: 'l'
23+
// 0x00403003: 'l'
24+
// 0x00403004: 'o'
25+
// 0x00403005: '\0'
26+
// (str1 -> points to 0x00403000)
27+
28+
// Pointer variable
29+
// 0x7fffbff0: str1 = 0x00403000 // str1 holds address of string literal
30+
31+
// 1. As a character array (modifiable)
32+
char strArray[] = "this is a strArray literal";
33+
std::cout << strArray << " - size " << sizeof(strArray) << " - length "
34+
<< strlen(strArray) << "\n";
35+
strArray[0] ^= ' ';
36+
std::cout << strArray << "\n";
37+
38+
// 2. As a a pointer to a string literal const (read-only)
39+
char* strPtr = "this is a strPtr literal";
40+
std::cout << strPtr << " - size " << sizeof(strPtr) << " - length "
41+
<< strlen(strPtr) << "\n";
42+
// strPtr[0] ^= ' '; // ERROR
43+
44+
// 3. Using sprintf / snprintf (string formatting)
45+
char strFormatted[50];
46+
int numVar = 21;
47+
48+
// sprintf (unsafe if buffer too small)
49+
sprintf(strFormatted, "sprintf: %d", numVar);
50+
std::cout << strFormatted << " - size " << sizeof(strFormatted)
51+
<< " - length " << strlen(strFormatted) << "\n";
52+
53+
// snprintf (safer, limits buffer size)
54+
snprintf(strFormatted, sizeof(strFormatted), "snprintf %s %d", strArray,
55+
numVar);
56+
std::cout << strFormatted << " - size " << sizeof(strFormatted)
57+
<< " - length " << strlen(strFormatted) << "\n";
58+
}
59+
} // namespace InitializeString
60+
61+
namespace CopyString {
62+
void run() {
63+
const char src[] = "CopyStr";
64+
char dst[50];
65+
66+
// 1. Copy full string
67+
strcpy(dst, src);
68+
69+
std::cout << dst << " - size " << sizeof(dst) << " - length " << strlen(dst)
70+
<< "\n";
71+
72+
// 2. Copy the number of charactor
73+
strncpy(dst, "Hello123", 5);
74+
dst[5] = '\0'; // ensure null-termination
75+
76+
std::cout << dst << " - size " << sizeof(dst) << " - length " << strlen(dst)
77+
<< "\n";
78+
}
79+
} // namespace CopyString
80+
81+
namespace ConcatString {
82+
void run() {
83+
const char part1[] = "Hello";
84+
const char part2[] = "World";
85+
char dst[50] = "";
86+
87+
// 1. Append full str
88+
strcat(dst, part1);
89+
strcat(dst, part2);
90+
strcat(dst, " !!");
91+
std::cout << dst << " - size " << sizeof(dst) << " - length " << strlen(dst)
92+
<< "\n";
93+
94+
// 2. Append the number of charactors
95+
strncat(dst, "1234", 3);
96+
std::cout << dst << " - size " << sizeof(dst) << " - length " << strlen(dst)
97+
<< "\n";
98+
}
99+
} // namespace ConcatString
100+
101+
namespace CompareString {
102+
void run() {
103+
const char str1[] = "abc";
104+
const char str2[] = "abcde";
105+
106+
// 1. Compare full str
107+
int result1 = strcmp(str1, "abc");
108+
int result2 = strcmp(str1, str2);
109+
std::cout << "strcmp(str1, \"abc\") = " << result1 << "\n";
110+
std::cout << "strcmp(str1, str2) = " << result2 << "\n";
111+
112+
// 2. Compare first N characters
113+
int result3 = strncmp(str1, str2, 3);
114+
std::cout << "strncmp(str1, str2, 3) = " << result3 << "\n";
115+
}
116+
} // namespace CompareString
117+
118+
namespace ParseString {
119+
void run() {
120+
char str[] = "A,B,C,D,"; // OK
121+
// char* str = "A,B,C,D,"; // ERROR - const
122+
123+
// 1. Splitting a string by some delimiter
124+
// 1.1. strtok - not safe
125+
char* delimiter = ",";
126+
const char* token = strtok(str, delimiter);
127+
while (token != nullptr) {
128+
std::cout << "strtok - token :" << token << "\n";
129+
token = strtok(NULL, delimiter);
130+
}
131+
{
132+
std::cout << " === problem === \n";
133+
char str1[] = "a,b,c";
134+
char str2[] = "1,2,3";
135+
136+
// Parse str1
137+
const char* token1 = strtok(str1, delimiter); // token1 = "a"
138+
std::cout << "str1 first token: " << token1 << "\n";
139+
140+
// Parse str2
141+
const char* token2 = strtok(str2, delimiter); // token2 = "1"
142+
std::cout << "str2 first token: " << token2 << "\n";
143+
144+
// Continue parsing str1
145+
token1 = strtok(nullptr, delimiter); // Unexpected!
146+
std::cout << "str1 second token: " << token1 << "\n";
147+
}
148+
149+
// Have to Reset string for the next handle because strtok
150+
char str2[] = "one,two,three";
151+
// 1.2. strtok_r - safe
152+
char* saveptr;
153+
const char* token2 = strtok_r(str2, delimiter, &saveptr);
154+
while (token2 != nullptr) {
155+
std::cout << "strtok - token :" << token2 << "\n";
156+
token2 = strtok_r(NULL, delimiter, &saveptr);
157+
}
158+
159+
// 2. strcspn: find first occurrence of any chars in reject set
160+
const char sample[] = "hello123world";
161+
size_t pos = strcspn(sample, "0123456789"); // pos = 5
162+
163+
std::cout << "Sample string: " << sample << "\n";
164+
std::cout << "First digit from \"0123456789\" found at index: " << pos
165+
<< "\n";
166+
std::cout << "The digit is: " << sample[pos] << "\n";
167+
}
168+
} // namespace ParseString
169+
170+
namespace NumberConversion {
171+
void run() {
172+
// 1. string to integer
173+
const char strNum[] = "100";
174+
int num = atoi(strNum);
175+
std::cout << num << "\n";
176+
177+
// 2. string to double
178+
const char strNumD[] = "100.1234__123";
179+
double numD = atof(strNumD);
180+
std::cout << numD << "\n";
181+
182+
char* end;
183+
numD = strtod(strNumD, &end);
184+
std::cout << numD << " end part:" << end << "\n";
185+
}
186+
} // namespace NumberConversion
187+
} // namespace
188+
189+
struct CStringAutoRunner {
190+
CStringAutoRunner() {
191+
std::cout << "\n--- C String Example ---\n";
192+
193+
InitializeString::run();
194+
CopyString::run();
195+
ConcatString::run();
196+
CompareString::run();
197+
ParseString::run();
198+
199+
NumberConversion::run();
200+
}
201+
};
202+
203+
static CStringAutoRunner instance;

0 commit comments

Comments
 (0)