Last active
December 23, 2015 15:39
-
-
Save oktal/6656683 to your computer and use it in GitHub Desktop.
String manipulation in C
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include "string.h" | |
#include <stdio.h> | |
#include <stdlib.h> | |
#include <string.h> | |
#include <assert.h> /* DEBUG */ | |
static string_err string_enlarge(String *this, size_t add) | |
{ | |
string_err err = STRING_ERR_OK; | |
size_t size = this->size; | |
size_t oldsize = this->size; | |
size_t newsize = size + add; | |
while (size < newsize) | |
{ | |
size *= 2; | |
} | |
if (this != NULL) | |
{ | |
this->s = realloc(this->s, size); | |
if (this->s != NULL) | |
{ | |
memset(this->s + oldsize, 0, size - oldsize); /* setting underminated memory to 0 */ | |
this->size = size; | |
} | |
else | |
{ | |
err = STRING_ERR_MEMORY; | |
} | |
} | |
else | |
{ | |
err = STRING_ERR_NULL; | |
} | |
return err; | |
} | |
static void string_purge(void) | |
{ | |
int c; | |
while ((c = fgetc(stdin)) != '\n' && c != EOF) | |
{ | |
} | |
} | |
String *new_string(void) | |
{ | |
String *this = malloc(sizeof *this); | |
if (this != NULL) | |
{ | |
this->size = 1; | |
this->index = 0; | |
this->s = malloc(1); | |
if (this->s != NULL) | |
{ | |
this->s[0] = 0; | |
} | |
} | |
return this; | |
} | |
string_err string_add_char(String *this, int const c) | |
{ | |
string_err err = STRING_ERR_OK; | |
if (this != NULL) | |
{ | |
if (this->s != NULL) | |
{ | |
size_t const s_len = 1; /* character's len */ | |
if (this->index + s_len >= this->size) | |
{ | |
err = string_enlarge(this, s_len); | |
} | |
if (err == STRING_ERR_OK) | |
{ | |
this->s[this->index++] = c; | |
this->s[this->index] = 0; | |
} | |
} | |
} | |
else | |
{ | |
err = STRING_ERR_NULL; | |
} | |
return err; | |
} | |
string_err string_add_str(String *this, char const *s) | |
{ | |
string_err err = STRING_ERR_NULL; | |
if (this != NULL) | |
{ | |
if (this->s != NULL && s != NULL) | |
{ | |
size_t const s_len = strlen(s); | |
if (this->index + s_len >= this->size) | |
{ | |
err = string_enlarge(this, s_len); | |
} | |
if (err == STRING_ERR_OK) | |
{ | |
memcpy(this->s + this->index, s, s_len); | |
this->index += s_len; | |
} | |
} | |
} | |
else | |
{ | |
err = STRING_ERR_NULL; | |
} | |
return err; | |
} | |
void string_puts(String *this) | |
{ | |
if (this != NULL && this->s != NULL) | |
{ | |
puts(this->s); | |
} | |
} | |
string_err string_gets(String *this) | |
{ | |
string_err err = STRING_ERR_OK; | |
if (this != NULL && this->s != NULL) | |
{ | |
size_t i = 0; | |
int c; | |
while ((c = fgetc(stdin)) != '\n' && c != EOF && err == STRING_ERR_OK) | |
{ | |
if (i >= this->size) | |
{ | |
err = string_enlarge(this, this->size * 2); /* growing by 2 */ | |
} | |
if (err == STRING_ERR_OK) | |
{ | |
this->s[this->index] = c; | |
this->index++; | |
} | |
i++; | |
} | |
this->s[this->index] = 0; | |
} | |
return err; | |
} | |
string_err string_ngets(String *this, size_t n) | |
{ | |
string_err err = STRING_ERR_OK; | |
if (this != NULL && this->s != NULL) | |
{ | |
size_t i = 0; | |
int c; | |
while ((c = fgetc(stdin)) != '\n' && c != EOF && err == STRING_ERR_OK) | |
{ | |
if (i < n - 1) | |
{ | |
if (i >= this->size) | |
{ | |
err = string_enlarge(this, this->size * 2); | |
} | |
if (err == STRING_ERR_OK) | |
{ | |
this->s[this->index] = c; | |
this->index++; | |
} | |
i++; | |
} | |
this->s[i] = 0; | |
} | |
} | |
return err; | |
} | |
char *string_str(String *this) | |
{ | |
char *ret = NULL; | |
if (this != NULL) | |
{ | |
ret = this->s; | |
} | |
return ret; | |
} | |
void string_clear(String *this) | |
{ | |
if (this != NULL) | |
{ | |
free(this->s), this->s = NULL; | |
this->index = this->size = 0; | |
} | |
} | |
void string_delete(String *this) | |
{ | |
if (this != NULL) | |
{ | |
free(this->s); | |
free(this); | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#ifndef STRING_H_INCLUDED | |
#define STRING_H_INCLUDED | |
#include <stddef.h> /* size_t */ | |
#include <string.h> | |
typedef struct string | |
{ | |
size_t size; | |
size_t index; | |
char *s; | |
} String; | |
typedef enum | |
{ | |
STRING_ERR_OK, STRING_ERR_MEMORY, STRING_ERR_NULL | |
} string_err; | |
String *new_string(void); | |
string_err string_add_char(String *this, int const c); | |
string_err string_add_str(String *this, char const *s); | |
void string_puts(String *this); | |
string_err string_gets(String *this); | |
string_err string_ngets(String *this, size_t n); | |
char *string_str(String *this); | |
void string_clear(String *this); | |
void string_delete(String *this); | |
#endif |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment