Skip to content
Merged
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
71 changes: 69 additions & 2 deletions cstring.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>

#include <stdbool.h>
#include <assert.h>
#include <inttypes.h>

typedef enum EErrorCode {
ERR_NO_ERROR,
Expand All @@ -17,6 +19,7 @@ typedef enum EErrorCode {
ERR_INVALID_STATE,
ERR_NULL_POINTER,
ERR_NUMBER_OVERFLOW,
ERR_INVALID_NUMBER_REPR,
ERR_NAN
} EErrorCode;

Expand All @@ -41,6 +44,8 @@ bool stringCharIsAlphanum(char c);
char stringCharToLower(char c);
char stringCharToUpper(char c);

int stringCharToInt(char c);

bool stringStartWith(TString s, TString pref);
bool stringStartWithCharArr(TString s, char *pref);
bool stringEndWith(TString s, TString pref);
Expand All @@ -61,6 +66,7 @@ int stringCompare(TString s1, TString s2);

int64_t stringFindFirst(TString s, TString pattern);
int64_t stringFindFirstCharArr(TString s, const char *pattern);
int64_t stringToInt(TString s);

TString stringRand(size_t size);
TString stringInit(size_t capacity);
Expand All @@ -76,6 +82,7 @@ TString stringJoinCharArr(TString s1, TString s2, const char *delim);
TString stringArrJoin(const TString *s, size_t count, TString delim);
TString stringArrJoinCharArr(const TString *s, size_t count, const char *delim);

char* stringConvertToCharArr(const TString s);
void stringScan(TString *s);
void stringPrint(TString s);
void stringDebug(TString s);
Expand Down Expand Up @@ -218,7 +225,7 @@ void stringIncreaseCap(TString *s) {
s->capacity = newCap;
}

// import
// import

bool stringCharIsDigit(char c) {
return ('0' <= c && c <= '9');
Expand All @@ -241,6 +248,14 @@ char stringCharToUpper(char c) {
return c;
}

int stringCharToInt(char c) {
clearError();
if ('0' <= c && c <= '9')
return c - '0';
setError(ERR_INVALID_NUMBER_REPR);
Copy link
Owner

Choose a reason for hiding this comment

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

If function can change error state, it have to clear error in the begin, to prevent smth like that:

// err = no_err
foo()                              // set err to smth, but result wasn't checked
...
//err = some_err
bar()                              // no error actually happened but flag wasn't cleaned
if (err == some_err) {             // check error in bar() result
    ...                            // but goes here because err after foo()
}

Copy link
Owner

Choose a reason for hiding this comment

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

although it is better to always check the error after each function call

return -1;
}

bool stringStartWith(TString s, TString pref) {
if (s.size < pref.size) return false;
return stringCompSubstr(s.data, 0, pref.size, pref.data,
Expand Down Expand Up @@ -361,6 +376,39 @@ int64_t stringFindFirstCharArr(TString s, const char *pattern) {
return -1;
}

int64_t stringToInt(TString s) {
clearError();

int64_t sign = 1;
int i = 0;

if (s.data[0] == '-') {
if (s.size == 1) {
setError(ERR_INVALID_NUMBER_REPR);
return 0;
}
sign = -1;
i++;
}

int64_t val = 0;
for (; i < s.size; i++) {
int64_t digit = stringCharToInt(s.data[i]);

// TODO: check for INT64_MIN overflow
if (val >= (INT64_MAX - digit) / 10) {
setError(ERR_NUMBER_OVERFLOW);
return val;
}
else {
val = val * 10 + digit;
}
}
val = val * sign;

return val;
}

TString stringInit(size_t capacity) {
TString s = {0};
s.data = (char *)malloc(sizeof(char) * capacity);
Expand Down Expand Up @@ -604,6 +652,25 @@ TString stringSubstring(TString s, size_t pos, size_t len) {
return res;
}

char* stringConvertToCharArr(const TString s) {
if (s.data == NULL)
return NULL;

clearError();
char *res = malloc(s.size + 1);

if(res == NULL) {
setError(ERR_NULL_POINTER);
return NULL;
}

for (size_t i = 0; i < s.size; ++i) {
res[i] = s.data[i];
}
res[s.size] = '\0';
return res;
}

void stringScan(TString *s) {
if (s == NULL) {
setError(ERR_NULL_POINTER);
Expand Down
17 changes: 17 additions & 0 deletions tests/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -467,6 +467,22 @@ void test_stringRemove() {
printGreen("test_stringRemove\n");
}

void test_stringToInt() {
TString s1 = stringInitWithCharArr("0");
TString s2 = stringInitWithCharArr("-2132456");
TString s3 = stringInitWithCharArr("18446744073709551615");

assertEq(stringToInt(s1), 0);
assertEq(stringToInt(s2), -2132456);
assertEq(stringToInt(s3), 18446744073709551615LL);

stringDestroy(&s1);
stringDestroy(&s2);
stringDestroy(&s3);

printGreen("test_stringToInt\n");
}

void test_stringToDouble() {
TString s1 = stringInitWithCharArr("0");
TString s2 = stringInitWithCharArr("12.34");
Expand Down Expand Up @@ -511,5 +527,6 @@ int main() {
test_stringIsPalindrome();
test_stringPad();
test_stringRemove();
test_stringToInt();
return 0;
}