c

exercises

exercises.c🔧
/**
 * String Functions - Exercises
 * 
 * Practice problems for standard library string functions.
 * Each exercise includes the problem statement and solution.
 * 
 * Compile: gcc exercises.c -o exercises
 * Run: ./exercises
 */

#include <stdio.h>
#include <string.h>
#include <ctype.h>

/* ============================================================
 * EXERCISE 1: Implement strcat
 * 
 * Write a function that concatenates src to the end of dest.
 * Return pointer to dest.
 * ============================================================ */

char* exercise1_my_strcat(char *dest, const char *src) {
    // YOUR CODE HERE
    // Hints:
    // - Find end of dest
    // - Copy src characters there
    // - Add null terminator
    
    return dest;
}

// Solution
char* solution1_my_strcat(char *dest, const char *src) {
    char *ptr = dest;
    
    // Find end of dest
    while (*ptr) {
        ptr++;
    }
    
    // Copy src
    while (*src) {
        *ptr++ = *src++;
    }
    *ptr = '\0';
    
    return dest;
}

void test_exercise1(void) {
    printf("=== Exercise 1: Implement strcat ===\n\n");
    
    char str1[30] = "Hello";
    char str2[30] = "Hi";
    
    solution1_my_strcat(str1, " World");
    solution1_my_strcat(str2, "");
    
    printf("Testing solution1_my_strcat:\n");
    printf("  \"Hello\" + \" World\" = \"%s\"\n", str1);
    printf("  \"Hi\" + \"\" = \"%s\"\n", str2);
    printf("\n");
}


/* ============================================================
 * EXERCISE 2: Implement strstr
 * 
 * Write a function that finds the first occurrence of needle
 * in haystack. Return pointer to match or NULL.
 * ============================================================ */

char* exercise2_my_strstr(const char *haystack, const char *needle) {
    // YOUR CODE HERE
    // Hints:
    // - Handle empty needle (return haystack)
    // - For each position, try to match needle
    
    return NULL;
}

// Solution
char* solution2_my_strstr(const char *haystack, const char *needle) {
    if (*needle == '\0') {
        return (char *)haystack;
    }
    
    while (*haystack) {
        const char *h = haystack;
        const char *n = needle;
        
        // Try to match needle at current position
        while (*h && *n && *h == *n) {
            h++;
            n++;
        }
        
        // Found complete match
        if (*n == '\0') {
            return (char *)haystack;
        }
        
        haystack++;
    }
    
    return NULL;
}

void test_exercise2(void) {
    printf("=== Exercise 2: Implement strstr ===\n\n");
    
    const char *text = "Hello World";
    
    printf("String: \"%s\"\n\n", text);
    printf("Testing solution2_my_strstr:\n");
    
    char *result = solution2_my_strstr(text, "World");
    printf("  Find \"World\": %s\n", result ? result : "NULL");
    
    result = solution2_my_strstr(text, "lo");
    printf("  Find \"lo\": %s\n", result ? result : "NULL");
    
    result = solution2_my_strstr(text, "xyz");
    printf("  Find \"xyz\": %s\n", result ? result : "NULL");
    
    result = solution2_my_strstr(text, "");
    printf("  Find \"\": %s\n", result ? result : "NULL");
    printf("\n");
}


/* ============================================================
 * EXERCISE 3: Count Substring Occurrences
 * 
 * Write a function that counts how many times a substring
 * appears in a string.
 * ============================================================ */

int exercise3_count_substring(const char *str, const char *sub) {
    // YOUR CODE HERE
    // Hints:
    // - Use strstr repeatedly
    // - Move past each match to find next
    
    return 0;
}

// Solution
int solution3_count_substring(const char *str, const char *sub) {
    if (sub[0] == '\0') return 0;
    
    int count = 0;
    const char *ptr = str;
    
    while ((ptr = strstr(ptr, sub)) != NULL) {
        count++;
        ptr++;  // Move past this match
    }
    
    return count;
}

void test_exercise3(void) {
    printf("=== Exercise 3: Count Substring ===\n\n");
    
    printf("Testing solution3_count_substring:\n");
    printf("  \"abababab\" contains \"ab\": %d times\n", 
           solution3_count_substring("abababab", "ab"));
    printf("  \"hello\" contains \"l\": %d times\n", 
           solution3_count_substring("hello", "l"));
    printf("  \"aaa\" contains \"aa\": %d times (overlapping)\n", 
           solution3_count_substring("aaa", "aa"));
    printf("  \"hello\" contains \"xyz\": %d times\n", 
           solution3_count_substring("hello", "xyz"));
    printf("\n");
}


/* ============================================================
 * EXERCISE 4: Replace Character
 * 
 * Write a function that replaces all occurrences of a character
 * with another character (in place).
 * ============================================================ */

void exercise4_replace_char(char *str, char old, char new) {
    // YOUR CODE HERE
}

// Solution
void solution4_replace_char(char *str, char old_char, char new_char) {
    while (*str) {
        if (*str == old_char) {
            *str = new_char;
        }
        str++;
    }
}

void test_exercise4(void) {
    printf("=== Exercise 4: Replace Character ===\n\n");
    
    char str1[] = "hello world";
    char str2[] = "mississippi";
    
    solution4_replace_char(str1, ' ', '_');
    solution4_replace_char(str2, 'i', 'o');
    
    printf("Testing solution4_replace_char:\n");
    printf("  \"hello world\" (' ' -> '_'): \"%s\"\n", str1);
    printf("  \"mississippi\" ('i' -> 'o'): \"%s\"\n", str2);
    printf("\n");
}


/* ============================================================
 * EXERCISE 5: Trim Whitespace
 * 
 * Write a function that removes leading and trailing whitespace
 * from a string (in place). Return pointer to trimmed string.
 * ============================================================ */

char* exercise5_trim(char *str) {
    // YOUR CODE HERE
    // Hints:
    // - Use strspn to skip leading spaces
    // - Find last non-space character
    // - Use memmove if needed
    
    return str;
}

// Solution
char* solution5_trim(char *str) {
    // Skip leading whitespace
    char *start = str;
    while (isspace(*start)) {
        start++;
    }
    
    // All spaces?
    if (*start == '\0') {
        *str = '\0';
        return str;
    }
    
    // Find end of string
    char *end = start + strlen(start) - 1;
    
    // Skip trailing whitespace
    while (end > start && isspace(*end)) {
        end--;
    }
    
    // Null terminate
    *(end + 1) = '\0';
    
    // Move to beginning if needed
    if (start != str) {
        memmove(str, start, end - start + 2);
    }
    
    return str;
}

void test_exercise5(void) {
    printf("=== Exercise 5: Trim Whitespace ===\n\n");
    
    char str1[] = "  Hello World  ";
    char str2[] = "   ";
    char str3[] = "NoSpaces";
    char str4[] = "  Leading";
    
    printf("Testing solution5_trim:\n");
    printf("  \"  Hello World  \" -> \"%s\"\n", solution5_trim(str1));
    printf("  \"   \" -> \"%s\"\n", solution5_trim(str2));
    printf("  \"NoSpaces\" -> \"%s\"\n", solution5_trim(str3));
    printf("  \"  Leading\" -> \"%s\"\n", solution5_trim(str4));
    printf("\n");
}


/* ============================================================
 * EXERCISE 6: Split String into Words
 * 
 * Write a function that counts words and prints each one.
 * Use strtok.
 * ============================================================ */

int exercise6_split_words(char *str) {
    // YOUR CODE HERE
    // Hints:
    // - Use strtok with " \t\n" delimiters
    // - Print each token and count
    
    return 0;
}

// Solution
int solution6_split_words(char *str) {
    int count = 0;
    char *token = strtok(str, " \t\n");
    
    while (token != NULL) {
        count++;
        printf("    Word %d: \"%s\"\n", count, token);
        token = strtok(NULL, " \t\n");
    }
    
    return count;
}

void test_exercise6(void) {
    printf("=== Exercise 6: Split into Words ===\n\n");
    
    char str1[] = "Hello World How Are You";
    char str2[] = "  Multiple   Spaces  ";
    
    printf("String: \"Hello World How Are You\"\n");
    int count1 = solution6_split_words(str1);
    printf("  Total words: %d\n\n", count1);
    
    printf("String: \"  Multiple   Spaces  \"\n");
    int count2 = solution6_split_words(str2);
    printf("  Total words: %d\n\n", count2);
}


/* ============================================================
 * EXERCISE 7: Parse CSV Line
 * 
 * Write a function that parses a CSV line into fields.
 * Print each field.
 * ============================================================ */

int exercise7_parse_csv(char *line) {
    // YOUR CODE HERE
    // Hint: Use strtok with "," delimiter
    
    return 0;
}

// Solution
int solution7_parse_csv(char *line) {
    int field = 0;
    char *token = strtok(line, ",");
    
    while (token != NULL) {
        field++;
        
        // Trim leading spaces
        while (*token == ' ') token++;
        
        printf("    Field %d: \"%s\"\n", field, token);
        token = strtok(NULL, ",");
    }
    
    return field;
}

void test_exercise7(void) {
    printf("=== Exercise 7: Parse CSV ===\n\n");
    
    char csv1[] = "John,25,Engineer,NYC";
    char csv2[] = "Alice, 30, Designer, LA";
    
    printf("CSV: \"John,25,Engineer,NYC\"\n");
    int count1 = solution7_parse_csv(csv1);
    printf("  Total fields: %d\n\n", count1);
    
    printf("CSV: \"Alice, 30, Designer, LA\"\n");
    int count2 = solution7_parse_csv(csv2);
    printf("  Total fields: %d\n\n", count2);
}


/* ============================================================
 * EXERCISE 8: Safe String Copy
 * 
 * Write a function that safely copies a string with size limit.
 * Always null-terminates. Returns 0 if truncated.
 * ============================================================ */

int exercise8_safe_strcpy(char *dest, size_t dest_size, const char *src) {
    // YOUR CODE HERE
    // Hints:
    // - Use strncpy
    // - Always null terminate
    // - Return 1 if complete, 0 if truncated
    
    return 1;
}

// Solution
int solution8_safe_strcpy(char *dest, size_t dest_size, const char *src) {
    if (dest_size == 0) return 0;
    
    size_t src_len = strlen(src);
    
    if (src_len < dest_size) {
        // Fits completely
        strcpy(dest, src);
        return 1;
    } else {
        // Truncated
        strncpy(dest, src, dest_size - 1);
        dest[dest_size - 1] = '\0';
        return 0;
    }
}

void test_exercise8(void) {
    printf("=== Exercise 8: Safe String Copy ===\n\n");
    
    char dest[10];
    int result;
    
    result = solution8_safe_strcpy(dest, sizeof(dest), "Hello");
    printf("Copy \"Hello\" to buffer[10]: \"%s\" (truncated: %s)\n", 
           dest, result ? "No" : "Yes");
    
    result = solution8_safe_strcpy(dest, sizeof(dest), "Hello World!!!");
    printf("Copy \"Hello World!!!\" to buffer[10]: \"%s\" (truncated: %s)\n", 
           dest, result ? "No" : "Yes");
    printf("\n");
}


/* ============================================================
 * EXERCISE 9: Find and Replace Substring
 * 
 * Write a function that replaces the first occurrence of a
 * substring with another string. Assume dest has enough space.
 * ============================================================ */

int exercise9_replace_first(char *str, size_t size, 
                            const char *old_sub, const char *new_sub) {
    // YOUR CODE HERE
    // Hints:
    // - Find old_sub with strstr
    // - Use memmove to make space/remove space
    // - Copy new_sub in place
    
    return 0;
}

// Solution
int solution9_replace_first(char *str, size_t size, 
                            const char *old_sub, const char *new_sub) {
    char *pos = strstr(str, old_sub);
    if (pos == NULL) return 0;
    
    size_t old_len = strlen(old_sub);
    size_t new_len = strlen(new_sub);
    size_t str_len = strlen(str);
    size_t tail_len = strlen(pos + old_len);
    
    // Check if result fits
    if (str_len - old_len + new_len >= size) {
        return 0;  // Won't fit
    }
    
    // Move the tail
    memmove(pos + new_len, pos + old_len, tail_len + 1);
    
    // Copy new substring
    memcpy(pos, new_sub, new_len);
    
    return 1;
}

void test_exercise9(void) {
    printf("=== Exercise 9: Replace Substring ===\n\n");
    
    char str1[50] = "Hello World";
    char str2[50] = "The quick brown fox";
    char str3[50] = "aaa bbb aaa";
    
    solution9_replace_first(str1, sizeof(str1), "World", "Everyone");
    solution9_replace_first(str2, sizeof(str2), "quick", "slow");
    solution9_replace_first(str3, sizeof(str3), "aaa", "XXX");
    
    printf("Testing solution9_replace_first:\n");
    printf("  \"Hello World\" -> \"Hello Everyone\": \"%s\"\n", str1);
    printf("  \"The quick brown fox\" -> \"The slow brown fox\": \"%s\"\n", str2);
    printf("  \"aaa bbb aaa\" (replace first aaa): \"%s\"\n", str3);
    printf("\n");
}


/* ============================================================
 * EXERCISE 10: Extract Filename from Path
 * 
 * Write a function that extracts the filename from a file path.
 * Example: "/home/user/file.txt" -> "file.txt"
 * ============================================================ */

const char* exercise10_get_filename(const char *path) {
    // YOUR CODE HERE
    // Hints:
    // - Use strrchr to find last '/' or '\\'
    // - Return pointer after the separator
    
    return path;
}

// Solution
const char* solution10_get_filename(const char *path) {
    // Check for Unix-style separator
    const char *slash = strrchr(path, '/');
    
    // Check for Windows-style separator
    const char *backslash = strrchr(path, '\\');
    
    // Use whichever comes last
    const char *last_sep = NULL;
    if (slash && backslash) {
        last_sep = (slash > backslash) ? slash : backslash;
    } else if (slash) {
        last_sep = slash;
    } else if (backslash) {
        last_sep = backslash;
    }
    
    if (last_sep) {
        return last_sep + 1;
    }
    
    return path;  // No separator found
}

void test_exercise10(void) {
    printf("=== Exercise 10: Extract Filename ===\n\n");
    
    printf("Testing solution10_get_filename:\n");
    printf("  \"/home/user/file.txt\" -> \"%s\"\n", 
           solution10_get_filename("/home/user/file.txt"));
    printf("  \"C:\\\\Users\\\\file.txt\" -> \"%s\"\n", 
           solution10_get_filename("C:\\Users\\file.txt"));
    printf("  \"file.txt\" -> \"%s\"\n", 
           solution10_get_filename("file.txt"));
    printf("  \"/path/to/dir/\" -> \"%s\"\n", 
           solution10_get_filename("/path/to/dir/"));
    printf("\n");
}


/* ============================================================
 * ANSWER KEY SUMMARY
 * ============================================================ */

void print_answer_key(void) {
    printf("\n");
    printf("╔═══════════════════════════════════════════════════════════════╗\n");
    printf("║            STRING FUNCTIONS - ANSWER KEY                      ║\n");
    printf("╚═══════════════════════════════════════════════════════════════╝\n\n");
    
    printf("Exercise 1: Implement strcat\n");
    printf("─────────────────────────────────────────\n");
    printf("  Find end of dest, then copy src\n\n");
    
    printf("Exercise 2: Implement strstr\n");
    printf("─────────────────────────────────────────\n");
    printf("  For each position, try matching needle\n");
    printf("  Return position if complete match\n\n");
    
    printf("Exercise 3: Count Substring\n");
    printf("─────────────────────────────────────────\n");
    printf("  Use strstr repeatedly, move past each match\n\n");
    
    printf("Exercise 4: Replace Character\n");
    printf("─────────────────────────────────────────\n");
    printf("  Loop through, replace if match\n\n");
    
    printf("Exercise 5: Trim Whitespace\n");
    printf("─────────────────────────────────────────\n");
    printf("  Skip leading with isspace\n");
    printf("  Find last non-space, null terminate\n");
    printf("  memmove if start moved\n\n");
    
    printf("Exercise 6: Split into Words\n");
    printf("─────────────────────────────────────────\n");
    printf("  Use strtok with space delimiters\n");
    printf("  First call: pass string\n");
    printf("  Subsequent: pass NULL\n\n");
    
    printf("Exercise 7: Parse CSV\n");
    printf("─────────────────────────────────────────\n");
    printf("  Use strtok with comma delimiter\n");
    printf("  Trim leading spaces from each field\n\n");
    
    printf("Exercise 8: Safe String Copy\n");
    printf("─────────────────────────────────────────\n");
    printf("  Check if fits, use strncpy\n");
    printf("  Always null-terminate dest[size-1]\n\n");
    
    printf("Exercise 9: Replace Substring\n");
    printf("─────────────────────────────────────────\n");
    printf("  Find with strstr\n");
    printf("  memmove tail to make room\n");
    printf("  memcpy new substring\n\n");
    
    printf("Exercise 10: Extract Filename\n");
    printf("─────────────────────────────────────────\n");
    printf("  Use strrchr to find last / or \\\\\n");
    printf("  Return pointer after separator\n\n");
    
    printf("═══════════════════════════════════════════════════════════════\n");
    printf("KEY STRING FUNCTIONS:\n");
    printf("═══════════════════════════════════════════════════════════════\n");
    printf("• strlen(s)          - String length\n");
    printf("• strcpy(d,s)        - Copy string\n");
    printf("• strcat(d,s)        - Concatenate strings\n");
    printf("• strcmp(s1,s2)      - Compare strings\n");
    printf("• strchr(s,c)        - Find character\n");
    printf("• strrchr(s,c)       - Find last character\n");
    printf("• strstr(hay,needle) - Find substring\n");
    printf("• strtok(s,delim)    - Tokenize string\n");
    printf("• memcpy(d,s,n)      - Copy memory\n");
    printf("• memmove(d,s,n)     - Safe memory copy\n");
    printf("═══════════════════════════════════════════════════════════════\n");
}


/* ============================================================
 * MAIN FUNCTION
 * ============================================================ */

int main() {
    printf("╔═══════════════════════════════════════════════════════════════╗\n");
    printf("║            STRING FUNCTIONS - EXERCISES                       ║\n");
    printf("╚═══════════════════════════════════════════════════════════════╝\n\n");
    
    test_exercise1();
    test_exercise2();
    test_exercise3();
    test_exercise4();
    test_exercise5();
    test_exercise6();
    test_exercise7();
    test_exercise8();
    test_exercise9();
    test_exercise10();
    
    print_answer_key();
    
    return 0;
}
Exercises - C Programming Tutorial | DeepML