diff --git a/stringfun.c b/stringfun.c new file mode 100644 index 0000000000000000000000000000000000000000..7e79e1458db12cfebe4c3d11eae820d120782c53 --- /dev/null +++ b/stringfun.c @@ -0,0 +1,214 @@ +#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); +} \ No newline at end of file