Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 44 additions & 0 deletions cstring.h
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,8 @@ void stringMapIndex(TString *s, char (*func)(size_t, char));
void stringRemove(TString *s, size_t pos, size_t len);
void stringDestroy(TString *s);

void stringCapitalize(TString *s);

#endif

// for testing:
Expand Down Expand Up @@ -910,5 +912,47 @@ void stringDestroy(TString *s) {
*s = (TString) {0};
}

bool charIsSep(char cur_ch){
char sep[5] = {' ', '\t', '\n', ',', '.'};
for (int i=0; i<5; i++){
Comment on lines +916 to +917
Copy link
Owner

@Tnirpps Tnirpps May 24, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
char sep[5] = {' ', '\t', '\n', ',', '.'};
for (int i=0; i<5; i++){
static const char sep[] = {' ', '\t', '\n', ',', '.'};
size_t len = sizeof(sep) / sizeof(*sep)
for (int i=0; i < len; i++){
  1. Можно создать массив, не указывая длину, а затем используя sizeof подсчитать её. Это полезно, так как в случае если захотим добавить новый символ в массив разделителей, то придётся только дописать его в конец, ничего больше не изменяя в коде
  2. Лучше объявить массив static const char чтобы подчеркнуть, что это некая константа и помочь компилятору в оптимизации кода

if (cur_ch == sep[i]) return true;
}
return false;
}

void stringCapitalize(TString *s){
typedef enum Tstate{
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Очень красивое применение конечных автоматов! Конечно на много понятнее был бы код, если просто для каждой буквы проверять, что перед ней был разделитель
Но крайне интересно увидеть здесь КА, хорошая работа

start,
end
} Tstate;
Tstate state = start;
size_t len = s->size;
for(size_t idx=0; idx<len; idx++){
char symb = s->data[idx];
switch(state){
case start:
if ( charIsSep(symb) ){
state = start;
}
else{
if ( stringCharIsAlpha(symb)){
stringCharToUpper(symb);
state = end;
} else state = end;
}
break;
case end:
if (charIsSep(symb)){
state = start;
} else state = end;
break;

default:
state = end;
break;
}
}
}


#endif
22 changes: 22 additions & 0 deletions tests/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -471,6 +471,27 @@ void test_stringRemove() {
printGreen("test_stringRemove\n");
}

void test_stringCapitalize(){
TString s1 = stringInitWithCharArr("Hello, World! testing remove");
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Можно было бы добавить ещё вид тестов, где несколько разделителей идёт подряд

TString res1 = stringInitWithCharArr("Hello, World! Testing Remove");
stringCapitalize(&s1);
assertEq(stringCompare(s1, res1), 0);
TString s2 = stringInitWithCharArr("1ello, World! testing remove");
TString res2 = stringInitWithCharArr("1ello, World! Testing Remove");
stringCapitalize(&s2);
assertEq(stringCompare(s2, res2), 0);
TString s3 = stringInitWithCharArr("Hello, World! tes&ting remove");
TString res3= stringInitWithCharArr("Hello, World! Tes&ting Remove");
stringCapitalize(&s3);
assertEq(stringCompare(s3, res3), 0);
TString s4 = stringInitWithCharArr("Hello, World!,testing remove");
TString res4 = stringInitWithCharArr("Hello, World!,Testing Remove");
stringCapitalize(&s4);
assertEq(stringCompare(s4, res4), 0);

printGreen("test_stringCapitalize\n");
}

int main() {
test_stringStartWith();
test_stringEndWith();
Expand Down Expand Up @@ -498,6 +519,7 @@ int main() {
test_stringIsPalindrome();
test_stringPad();
test_stringRemove();
test_stringCapitalize();
return 0;
}

Expand Down