diff --git a/Assignment1/makefile b/Assignment1/makefile
new file mode 100644
index 0000000000000000000000000000000000000000..98655dade808fd2c6a73f8197139945b63ec66b6
--- /dev/null
+++ b/Assignment1/makefile
@@ -0,0 +1,20 @@
+# Compiler settings
+CC = gcc
+CFLAGS = -Wall -Wextra -g
+
+# Target executable name
+TARGET = stringfun
+
+# Default target
+all: $(TARGET)
+
+# Compile source to executable
+$(TARGET): stringfun.c
+	$(CC) $(CFLAGS) -o $(TARGET) $^
+
+# Clean up build files
+clean:
+	rm -f $(TARGET)
+
+# Phony targets
+.PHONY: all clean
\ No newline at end of file
diff --git a/Assignment1/stringfun b/Assignment1/stringfun
new file mode 100755
index 0000000000000000000000000000000000000000..1714fc3b9af4d5cb39e2031252aad3a790777591
Binary files /dev/null and b/Assignment1/stringfun differ
diff --git a/Assignment1/stringfun.c b/Assignment1/stringfun.c
new file mode 100644
index 0000000000000000000000000000000000000000..2ca07c415a6daed87adc572e240bead8e6c938cd
--- /dev/null
+++ b/Assignment1/stringfun.c
@@ -0,0 +1,365 @@
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+
+#define BUFFER_SZ 50
+
+//prototypes
+void usage(char *);
+void print_buff(char *, int);
+int  setup_buff(char *, char *, int);
+
+//prototypes for functions to handle required functionality
+int  count_words(char *, int, int);
+//add additional prototypes here
+int reverse_string(char *, int);
+int print_words(char *, int);
+int replace_words(char *, const char *, const char *, int);
+
+int setup_buff(char *buff, char *user_str, int len){
+    //TODO: #4:  Implement the setup buff as per the directions
+    char *src = user_str;
+    char *dest = buff;
+    int count = 0, is_space = 0;
+
+    // Skip leading spaces
+    while (*src == ' ' || *src == '\t') {
+        src++;
+    }
+
+    // Process the string
+    while (*src != '\0' && count < len) {
+        // Check for space
+        if (*src == ' ' || *src == '\t') {
+            if (!is_space) {  // Avoid consecutive spaces
+                *dest++ = ' ';
+                count++;
+                is_space = 1;
+            }
+        } else {
+            *dest++ = *src;
+            count++;
+            is_space = 0;
+        }
+        src++;
+    }
+
+    // Trim trailing space
+    if (count > 0 && *(dest - 1) == ' ') {
+        dest--;
+        count--;
+    }
+
+    if (*src != '\0') return -1;  // Input exceeds buffer size
+
+    // Fill remaining buffer with dots
+    while (count < len) {
+        *dest++ = '.';
+        count++;
+    }
+
+    return count;
+}
+
+void print_buff(char *buff, int len){
+    printf("Buffer:  ");
+    putchar('[');
+    for (int i=0; i<len; i++){
+        putchar(*(buff+i));
+    }
+    putchar(']');
+    putchar('\n');
+}
+
+void usage(char *exename){
+    printf("usage: %s [-h|c|r|w|x] \"string\" [other args]\n", exename);
+
+}
+
+int count_words(char *buff, int len, int str_len){
+    if (buff == NULL || len <= 0 || str_len <= 0) {
+        return -1; // Error
+    }
+
+    int word_count = 0;
+
+    for (int i = 0; i < str_len; i++){
+        if (*(buff + i) == ' '){
+            word_count++;
+        }
+    }
+
+    return word_count;
+}
+
+//ADD OTHER HELPER FUNCTIONS HERE FOR OTHER REQUIRED PROGRAM OPTIONS
+int reverse_string(char *buff, int str_len) {
+    if (buff == NULL || str_len <= 0) {
+        return -1; // Error
+    }
+
+    // Determine the actual length
+    int actual_len = 0;
+    while (actual_len < str_len && *(buff + actual_len) != '.') {
+        actual_len++;
+    }
+
+    // Reverse string
+    char *start = buff;
+    char *end = buff + actual_len - 1;
+    char temp;
+
+    while (start < end) {
+        temp = *start;
+        *start = *end;
+        *end = temp;
+
+        start++;
+        end--;
+    }
+
+    // Print the reversed string
+    printf("Reversed String: ");
+    for (int i = 0; i < actual_len; i++) {
+        putchar(*(buff + i));
+    }
+    putchar('\n');
+
+    return 0;
+}
+
+int print_words(char *buff, int str_len) {
+    if (buff == NULL || str_len <= 0) {
+        return -1; // Error
+    }
+
+    // Determine the actual length
+    int actual_len = 0;
+    while (actual_len < str_len && *(buff + actual_len) != '.') {
+        actual_len++;
+    }
+
+    printf("Word Print\n----------\n");
+    int word_start = 0, word_length = 0, word_count = 1;
+
+    for (int i = 0; i <= actual_len; i++) {
+        // Detect the end of a word
+        if (i == actual_len || *(buff + i) == ' ') {
+            if (word_length > 0) {
+                // Print the current word
+                printf("%d. ", word_count++);
+                for (int j = word_start; j < word_start + word_length; j++) {
+                    putchar(*(buff + j));
+                }
+                printf(" (%d)\n", word_length);
+                word_length = 0;
+            }
+        } else {
+            // Track the start of a word and its length
+            if (word_length == 0) word_start = i;
+            word_length++;
+        }
+    }
+
+    return 0;
+}
+
+int replace_word(char *buff, const char *find, const char *replace, int len) {
+    if (buff == NULL || find == NULL || replace == NULL || len <= 0) {
+        return -1; // Error
+    }
+
+    char *start = buff;
+    char *match = NULL;
+    int find_len = 0, replace_len = 0;
+
+    // Calculate lengths of `find` and `replace`
+    while (*(find + find_len) != '\0') {
+        find_len++;
+    }
+    while (*(replace + replace_len) != '\0') {
+        replace_len++;
+    }
+
+    // Search for the word to replace
+    while (*start != '\0' && start < buff + len) {
+        if (*start == *find) { // Possible match found
+            char *temp_buff = start;
+            char *temp_find = (char *)find;
+            while (*temp_buff == *temp_find && *temp_find != '\0') {
+                temp_buff++;
+                temp_find++;
+            }
+
+            if (*temp_find == '\0') { // Full match found
+                match = start;
+                break;
+            }
+        }
+        start++;
+    }
+
+    if (match == NULL) {
+        printf("Word not found: %s\n", find);
+        return -1; // No replacement found
+    }
+
+    // If replacement makes the string too long, truncate
+    int remaining_len = len - (match - buff);
+    if (replace_len > find_len && replace_len - find_len > remaining_len) {
+        printf("Error: Replacement would exceed buffer size\n");
+        return -1; // Error
+    }
+
+    // Perform the replacement
+    char *end_of_buff = buff + len; // To prevent buffer overflow
+    char *src = match + find_len;        // Start of the rest of the string
+    char *dest = match + replace_len;    // New position after replacement
+
+    if (replace_len != find_len) {
+        // Shift the remaining part of the string
+        while (end_of_buff > dest && src < end_of_buff) {
+            *(end_of_buff - 1) = *(src + (end_of_buff - dest - 1));
+            end_of_buff--;
+        }
+    }
+
+    // Copy the replacement word into the buffer
+    for (int i = 0; i < replace_len; i++) {
+        *(match + i) = *(replace + i);
+    }
+
+    printf("Modified String: ");
+    for (int i = 0; i < len && *(buff + i) != '.'; i++) {
+        putchar(*(buff + i));
+    }
+    putchar('\n');
+
+    return 0;
+}
+
+
+int main(int argc, char *argv[]){
+
+    char *buff;             //placehoder for the internal buffer
+    char *input_string;     //holds the string provided by the user on cmd line
+    char opt;               //used to capture user option from cmd line
+    int  rc;                //used for return codes
+    int  user_str_len;      //length of user supplied string
+
+    //TODO:  #1. WHY IS THIS SAFE, aka what if arv[1] does not exist?
+    // argc < 2, ensures that the program does not attempt to access 
+    // argv[1] if no arguments are passed (avoiding out-of-bounds
+    // memory access).
+    // *argv[1] != '-', validates that the provided argument starts with a -,
+    // ensuring it's an option flag.
+
+    if ((argc < 2) || (*argv[1] != '-')){
+        usage(argv[0]);
+        exit(1);
+    }
+
+    opt = (char)*(argv[1]+1);   //get the option flag
+
+    //handle the help flag and then exit normally
+    if (opt == 'h'){
+        usage(argv[0]);
+        exit(0);
+    }
+
+    //WE NOW WILL HANDLE THE REQUIRED OPERATIONS
+
+    //TODO:  #2 Document the purpose of the if statement below
+    // This ensures that the program does not proceed if the user has not 
+    // provided the required input string, as any other operator other than
+    // -h need string as input.
+    if (argc < 3){
+        usage(argv[0]);
+        exit(1);
+    }
+
+    input_string = argv[2]; //capture the user input string
+
+    //TODO:  #3 Allocate space for the buffer using malloc and
+    //          handle error if malloc fails by exiting with a 
+    //          return code of 99
+    
+    buff = (char *) malloc(BUFFER_SZ * sizeof(char));
+    if (!buff){
+        printf("Error: Memory allocation failed\n");
+        exit(99);
+    }
+
+
+    user_str_len = setup_buff(buff, input_string, BUFFER_SZ);     //see todos
+    if (user_str_len < 0){
+        printf("Error setting up buffer, error = %d", user_str_len);
+        exit(2);
+    }
+
+    switch (opt) {
+    case 'c':
+        rc = count_words(buff, BUFFER_SZ, user_str_len);
+        if (rc < 0) {
+            printf("Error counting words, rc = %d\n", rc);
+            free(buff);
+            return -1;
+        }
+        printf("Word Count: %d\n", rc);
+        break;
+
+    case 'r':
+        rc = reverse_string(buff, user_str_len);
+        if (rc < 0) {
+            printf("Error reversing string, rc = %d\n", rc);
+            free(buff);
+            return -1;
+        }
+        break;
+
+    case 'w':
+        rc = print_words(buff, user_str_len);
+        if (rc < 0) {
+            printf("Error printing words, rc = %d\n", rc);
+            free(buff);
+            return -1;
+        }
+        break;
+    case 'x':
+        if (argc < 5) {
+            printf("Error: Missing arguments for -x. Usage: ./program -x \"string\" \"find\" \"replace\"\n");
+            free(buff);
+            return -1;
+        }
+
+        rc = replace_word(buff, argv[3], argv[4], BUFFER_SZ);
+        if (rc < 0) {
+            printf("Error replacing word\n");
+            free(buff);
+            return -1;
+        }
+        break;
+
+        default:
+            usage(argv[0]);
+            free(buff);
+            exit(1);
+    }
+
+    //TODO:  #6 Dont forget to free your buffer before exiting
+    print_buff(buff,BUFFER_SZ);
+    free(buff);
+    exit(0);
+}
+
+//TODO:  #7  Notice all of the helper functions provided in the 
+//          starter take both the buffer as well as the length.  Why
+//          do you think providing both the pointer and the length
+//          is a good practice, after all we know from main() that 
+//          the buff variable will have exactly 50 bytes?
+//  
+//          PLACE YOUR ANSWER HERE
+// Although we know buff has exactly 50 bytes, passing the length explicitly
+// Makes the function reusable with buffers of different sizes in other contexts.
+// Improves code readability by clarifying the buffer's size directly in the function call.
\ No newline at end of file
diff --git a/Assignment1/test.sh b/Assignment1/test.sh
new file mode 100755
index 0000000000000000000000000000000000000000..f2b431b8bdf429bc90753656d0f73ef64cd3b2cc
--- /dev/null
+++ b/Assignment1/test.sh
@@ -0,0 +1,100 @@
+#!/usr/bin/env bats
+
+@test "no args shows usage" {
+    run ./stringfun
+    [ "$status" -eq 1 ]
+    [ "${lines[0]}" = "usage: ./stringfun [-h|c|r|w|x] \"string\" [other args]" ]
+}
+
+@test "bad args shows usage" {
+    run ./stringfun -z "Bad arg usage"  
+    [ "$status" -eq 1 ]
+    [ "${lines[0]}" = "usage: ./stringfun [-h|c|r|w|x] \"string\" [other args]" ]
+}
+
+@test "check -h" {
+    run ./stringfun -h
+    [ "$status" -eq 0 ]
+    [ "${lines[0]}" = "usage: ./stringfun [-h|c|r|w|x] \"string\" [other args]" ]
+}
+
+@test "wordcount" {
+    run ./stringfun -c "There should be eight words in this sentence"
+    [ "$status" -eq 0 ]
+    [ "$output" = "Word Count: 8
+Buffer:  [There should be eight words in this sentence......]" ]
+}
+
+@test "remove extra spaces" {
+    run ./stringfun -c "   The   strange    spaces    should   be     removed   from this    "
+    [ "$status" -eq 0 ]
+    [ "$output" = "Word Count: 8
+Buffer:  [The strange spaces should be removed from this....]" ]
+}
+
+@test "reverse" {
+    run ./stringfun -r "Reversed sentences look very weird"
+    [ "$status" -eq 0 ]
+    [ "$output" = "Buffer:  [driew yrev kool secnetnes desreveR................]" ]
+}
+
+@test "print words" {
+    run ./stringfun -w "Lets get a lot of words to test"
+    [ "$status" -eq 0 ]
+    [ "$output" = "Word Print
+----------
+1. Lets(4)
+2. get(3)
+3. a(1)
+4. lot(3)
+5. of(2)
+6. words(5)
+7. to(2)
+8. test(4)
+
+Number of words returned: 8
+Buffer:  [Lets get a lot of words to test...................]" ]
+}
+
+@test "check max length" {
+    run ./stringfun -r "This is the maximum length string that should work"
+    [ "$status" -eq 0 ]
+    [ "$output" = "Buffer:  [krow dluohs taht gnirts htgnel mumixam eht si sihT]" ]
+}
+
+@test "check over max length" {
+    run ./stringfun -w "This is a string that does not work as it is too long"
+    [ "$status" -ne 0 ]
+}
+
+
+
+@test "basic string search replace" {
+    run ./stringfun -x "This is a bad test" bad  great
+    [ "$output" = "Buffer:  [This is a great test..............................]" ] ||
+    [ "$output" = "Not Implemented!" ]
+}
+
+@test "search replace not found" {
+    run ./stringfun -x "This is a a long string for testing" bad  great
+    [ "$status" -ne 0 ] || 
+    [ "$output" = "Not Implemented!" ]
+}
+
+@test "basic overflow search replace" {
+    run ./stringfun -x "This is a super long string for testing my program" testing  validating
+    [ "$output" = "Buffer:  [This is a super long string for validating my prog]" ] ||
+    [ "$output" = "Not Implemented!" ]
+}
+
+@test "test overflow string replace" {
+    run ./stringfun -x "This is a super long string for testing my program" testing  validating
+    [ "$output" = "Buffer:  [This is a super long string for validating my prog]" ] ||
+    [ "$output" = "Not Implemented!" ]
+}
+
+@test "test shorter string replace" {
+    run ./stringfun -x "This is a super long string for testing my program" program  app
+    [ "$output" = "Buffer:  [This is a super long string for testing my app....]" ] || 
+    [ "$output" = "Not Implemented!" ]
+}