nd_sys_prog/homework06/str.c
2025-03-22 20:47:26 -04:00

159 lines
3.5 KiB
C

/* str.c: string library */
#include "str.h"
#include <ctype.h>
#include <stdbool.h>
#include <stdlib.h>
/* Functions */
/**
* Convert string to lowercase.
* @param s String to convert
* @param w Pointer to buffer that holds result of conversion
**/
void str_lower(const char *s, char *w) {
while (*s) {
*w = tolower(*s);
s++;
w++;
}
*w = '\0';
}
/**
* Convert string to uppercase.
* @param s String to convert
* @param w Pointer to buffer that holds result of conversion
**/
void str_upper(const char *s, char *w) {
while (*s) {
*w = toupper(*s);
s++;
w++;
}
*w = '\0';
}
/**
* Convert string to titlecase.
* @param s String to convert
* @param w Pointer to buffer that holds result of conversion
**/
void str_title(const char *s, char *w) {
if (*s) {
*w = toupper(*s);
w++;
s++;
while (*s) {
if (!isalpha(*(s - 1))) {
*w = toupper(*s);
} else {
*w = tolower(*s);
}
s++;
w++;
}
}
*w = '\0';
}
/**
* Strip characters from back of string (if present).
* @param s String to strip
* @param chars Characters to strip (if NULL, then all whitespace)
* @param w Pointer to buffer that holds result of strip
**/
void str_rstrip(const char *s, const char *chars, char *w) {
bool strip_chars[256] = {0};
// Create the lookup table
if (chars == NULL) {
// If chars is NULL, strip whitespace
strip_chars[' '] = true;
strip_chars['\t'] = true;
strip_chars['\n'] = true;
} else {
// Otherwise, strip specified characters
while (*chars) {
strip_chars[(unsigned char)*chars] = true;
chars++;
}
}
// Copy s to w
const char *src = s;
char *dst = w;
while (*src) {
*dst++ = *src++;
}
*dst = '\0';
if (dst > w) {
dst--;
while (dst >= w && strip_chars[(unsigned char)*dst]) {
dst--;
}
*(dst + 1) = '\0';
}
}
/**
* Delete characters from string.
* @param s String to delete from
* @param chars Characters to delete
* @param w Pointer to buffer that holds result of deletion
**/
void str_delete(const char *s, const char *chars, char *w) {
bool del_chars[256] = {0};
// Create lookup table
while (*chars) {
del_chars[(unsigned char)*chars] = true;
chars++;
}
// Copy non-deleted chars to w
while (*s) {
if (!del_chars[(unsigned char)*s]) {
*w = *s;
w++;
}
s++;
}
*w = '\0';
}
/**
* Translate characters in 'from' with corresponding characters in 'to'.
* @param s String to translate
* @param from String with characters to translate
* @param to String with corresponding translation characters
* @param w Pointer to buffer that holds result of translation
**/
void str_translate(const char *s, const char *from, const char *to, char *w) {
unsigned char translate_table[256];
int i;
for (i = 0; i < 256; i++) {
translate_table[i] = i;
}
// Create the translation map
while (*from && *to) {
translate_table[(unsigned char)*from] = *to;
from++;
to++;
}
// Translate
while (*s) {
*w = translate_table[(unsigned char)*s];
s++;
w++;
}
*w = '\0';
}
/* vim: set sts=4 sw=4 ts=8 expandtab ft=c: */