diff --git a/.DS_Store b/.DS_Store
new file mode 100644
index 0000000000000000000000000000000000000000..b1d5ffd05b4a2a5df0a3d7e7f0ab95a9d60d40d1
Binary files /dev/null and b/.DS_Store differ
diff --git a/Hw2/Makefile b/Hw2/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..98655dade808fd2c6a73f8197139945b63ec66b6
--- /dev/null
+++ b/Hw2/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/Hw2/stringfun b/Hw2/stringfun
new file mode 100755
index 0000000000000000000000000000000000000000..8cb7308c3a354760af3f736e12c9caff340d3342
Binary files /dev/null and b/Hw2/stringfun differ
diff --git a/Hw2/stringfun.c b/Hw2/stringfun.c
new file mode 100644
index 0000000000000000000000000000000000000000..6b962f14954e141daf70cd6d5ed24682c20b91ea
--- /dev/null
+++ b/Hw2/stringfun.c
@@ -0,0 +1,255 @@
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <stdbool.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 setup_buff(char *buff, char *user_str, int len){
+    //TODO: #4:  Implement the setup buff as per the directions
+    bool isSpace = false;
+    int count = 0;
+
+    while (*user_str != '\0' && count < BUFFER_SZ - 1) { // stop when reaching the end-of-buffer
+        if (*user_str != '\t'){
+            if (*user_str != ' ' || isSpace == false) {
+                *buff = *user_str;
+                if (*user_str == ' '){
+                    isSpace = true;
+                } else {
+                    isSpace = false;
+                }
+                buff++;
+                user_str++;
+                count++;
+            } else {
+                user_str++;
+                isSpace = false;
+            }
+        } else {
+            user_str++;
+        }
+    }
+    int ret = count;
+    if (count > len){
+        return -1;
+    }
+    while (count <= len){
+        *buff = '.';
+        buff++;
+        count++;
+    }
+
+    return ret; //for now just so the code compiles. 
+}
+
+void print_buff(char *buff, int len){
+    printf("Buffer:  ");
+    for (int i=0; i<len; i++){
+        putchar(*(buff+i));
+    }
+    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){
+    //YOU MUST IMPLEMENT
+    if (str_len > len){
+        return -1;
+    }
+
+    if (str_len==0){
+        return 0;
+    }
+    int words = 1;
+    for (int i=0; i<str_len; i++){
+        if (*buff == ' '){
+            words++;
+        }
+        buff++;
+    }
+    return words;
+}
+
+//ADD OTHER HELPER FUNCTIONS HERE FOR OTHER REQUIRED PROGRAM OPTIONS
+
+void reverse_string(char *buff, int len, int str_len){
+    int lim;
+    if (len < str_len){
+        lim = len;
+    } else {
+        lim = str_len;
+    }
+    char *newBuff = (char*)malloc(BUFFER_SZ);
+    for (int i=0; i<lim; i++){
+        *newBuff = *buff;
+        newBuff--;
+        buff++;
+    }
+
+    for (int i=0; i<lim; i++){
+        putchar(*(newBuff+i));
+    }
+
+    printf("\n");
+}
+
+void word_print(char *buff, int len, int str_len){
+    int lim;
+    if (len < str_len){
+        lim = len;
+    } else {
+        lim = str_len;
+    }
+
+    int count = 1;
+    int track = 0;
+    printf("Word Print\n");
+    printf("--------------\n");
+    printf("%d. ", count);
+    for (int i=0; i<lim; i++){
+        if (*buff != ' '){
+            putchar(*buff);
+            track++;
+        } else {
+            printf(" (%d)\n",track);
+            count++;
+            printf("%d. ", count);
+            track = 0;
+        }
+        buff++;
+    }
+    printf(" (%d)\n",track);
+}
+
+// void replace(char *buff, *new_buff)
+
+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?
+    //      PLACE A COMMENT BLOCK HERE EXPLAINING
+
+    /*
+    If arv[1] does not exist, the condition argc < 2, so the program will safely exit and print the usage:
+    usage: ./stringfun [-h|c|r|w|x] "string" [other args]
+    */
+
+    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
+    //      PLACE A COMMENT BLOCK HERE EXPLAINING
+
+    /*
+    This if statement make sure that users provide a string after the namefile and the operation (-h|c|r|w|x)
+    If not, it will print the usage
+    */
+    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
+    // CODE GOES HERE FOR #3
+    buff= (char*)malloc(BUFFER_SZ);
+    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);  //you need to implement
+            if (rc < 0){
+                printf("Error counting words, rc = %d", rc);
+                exit(2);
+            }
+            printf("Word Count: %d\n", rc);
+            break;
+        // TODO:  #5 Implement the other cases for 'r' and 'w' by extending
+        // the case statement options
+        case 'r':
+            reverse_string(buff, BUFFER_SZ, user_str_len);
+            break;
+
+        case 'w':
+            word_print(buff, BUFFER_SZ, user_str_len);
+            break;
+
+        case 'x':
+            if (argc < 5){
+                printf("Need 3 arguments: sample string and 2 other strings\n");
+                exit(1);
+            } else {
+                // buff= (char*)malloc(BUFFER_SZ);
+                // old_string = argv[3];
+                // old_str_len = setup_buff()
+                // new_string = argv[4];
+                // new_str_len = setup_buff(buff, new_string, BUFFER_SZ);
+                printf("Not Implemented\n");
+                break;   
+            }
+
+        default:
+            usage(argv[0]);
+            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
+
+// 
+
+// We need the pointer to access and modify the values in the address. 
+// Providing the length is a good practice since we sometimes need to
+// use the length (of the buffer and the user string) to make sure that
+// there is no buffer overflow or similiar errors appear in our function.
\ No newline at end of file
diff --git a/Hw2/test.sh b/Hw2/test.sh
new file mode 100644
index 0000000000000000000000000000000000000000..f2b431b8bdf429bc90753656d0f73ef64cd3b2cc
--- /dev/null
+++ b/Hw2/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!" ]
+}