Select Git revision
-
Matt Bunkin authoredMatt Bunkin authored
stringfun.c 4.75 KiB
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
#define BUFFER_SZ 50
// Prototypes
void usage(char *);
void print_buff(char *);
int setup_buff(char *, char *, int);
int count_words(char *, int);
void reverse_buffer(char *);
void print_words(char *);
int search_replace(char *, char *, char *);
// Helper function: Clean spaces
void clean_spaces(char *buff, int *len) {
char *src = buff, *dst = buff;
int in_space = 0;
while (*src) {
if (isspace(*src)) {
if (!in_space) {
*dst++ = ' ';
in_space = 1;
}
} else {
*dst++ = *src;
in_space = 0;
}
src++;
}
// Remove trailing space
if (dst > buff && isspace(*(dst - 1))) {
dst--;
}
*dst = '\0';
*len = strlen(buff);
}
// Setup buffer
int setup_buff(char *buff, char *user_str, int len) {
if (!buff || !user_str) {
return -1;
}
int user_str_len = strlen(user_str);
if (user_str_len >= len) {
memcpy(buff, user_str, len - 1);
buff[len - 1] = '\0';
} else {
strcpy(buff, user_str);
memset(buff + user_str_len, '.', len - user_str_len);
}
return strlen(buff);
}
// Print buffer
void print_buff(char *buff) {
printf("Buffer: [");
for (int i = 0; i < BUFFER_SZ; i++) {
putchar(buff[i] ? buff[i] : '.');
}
printf("]\n");
}
// Word counting
int count_words(char *buff, int str_len) {
if (!buff || str_len <= 0) {
return -1;
}
clean_spaces(buff, &str_len);
int word_count = 0, in_word = 0;
for (int i = 0; i < str_len; i++) {
if (!isspace(buff[i])) {
if (!in_word) {
word_count++;
in_word = 1;
}
} else {
in_word = 0;
}
}
return word_count;
}
// Reverse buffer
void reverse_buffer(char *buff) {
if (!buff) return;
int end = strlen(buff) - 1;
for (int i = 0; i < end; i++, end--) {
char temp = buff[i];
buff[i] = buff[end];
buff[end] = temp;
}
}
// Print words
void print_words(char *buff) {
int word_count = 0;
printf("Word Print\n----------\n");
char *token = strtok(buff, " ");
while (token) {
printf("%d. %s(%ld)\n", ++word_count, token, strlen(token));
token = strtok(NULL, " ");
}
printf("\nNumber of words returned: %d\n", word_count);
}
// Search and replace
int search_replace(char *buff, char *old, char *new_str) {
char temp[BUFFER_SZ];
char *pos, *curr = buff;
int old_len = strlen(old), new_len = strlen(new_str);
int temp_len = 0;
if (!buff || !old || !new_str) return -1;
while ((pos = strstr(curr, old))) {
if (temp_len + (pos - curr) + new_len >= BUFFER_SZ) break;
memcpy(temp + temp_len, curr, pos - curr);
temp_len += pos - curr;
memcpy(temp + temp_len, new_str, new_len);
temp_len += new_len;
curr = pos + old_len;
}
if (temp_len + strlen(curr) >= BUFFER_SZ) return -1;
strcpy(temp + temp_len, curr);
strncpy(buff, temp, BUFFER_SZ - 1);
buff[BUFFER_SZ - 1] = '\0';
return 0;
}
// Usage
void usage(char *exename) {
printf("usage: %s [-h|c|r|w|x] \"string\" [other args]\n", exename);
}
// Main function
int main(int argc, char *argv[]) {
char *buff = (char *)malloc(BUFFER_SZ * sizeof(char));
if (!buff) {
fprintf(stderr, "Error: Memory allocation failed\n");
exit(99);
}
if ((argc < 2) || (*argv[1] != '-')) {
usage(argv[0]);
free(buff);
exit(1);
}
char opt = argv[1][1];
if (opt == 'h') {
usage(argv[0]);
free(buff);
exit(0);
}
if (argc < 3) {
usage(argv[0]);
free(buff);
exit(1);
}
char *input_string = argv[2];
int user_str_len = setup_buff(buff, input_string, BUFFER_SZ);
if (user_str_len < 0) {
fprintf(stderr, "Error setting up buffer\n");
free(buff);
exit(2);
}
switch (opt) {
case 'c':
printf("Word Count: %d\n", count_words(buff, user_str_len));
break;
case 'r':
reverse_buffer(buff);
break;
case 'w':
print_words(buff);
break;
case 'x':
if (argc < 5) {
usage(argv[0]);
free(buff);
exit(1);
}
if (search_replace(buff, argv[3], argv[4]) != 0) {
printf("Not Implemented!\n");
free(buff);
exit(1);
}
break;
default:
usage(argv[0]);
free(buff);
exit(1);
}
print_buff(buff);
free(buff);
exit(0);
}