cpp

strings

01_strings.cpp⚙️
/**
 * ============================================================
 * C++ STRINGS (std::string)
 * ============================================================
 * 
 * This file covers:
 * - String creation and initialization
 * - String operations
 * - String manipulation
 * - Searching and replacing
 * - String conversion
 * - String streams
 * 
 * Compile: g++ -std=c++17 -Wall 01_strings.cpp -o strings
 * Run: ./strings
 * 
 * ============================================================
 */

#include <iostream>
#include <string>
#include <sstream>    // For string streams
#include <algorithm>  // For transform, etc.
#include <cctype>     // For toupper, tolower, isalpha, etc.
#include <iomanip>

using namespace std;

int main() {
    cout << "============================================" << endl;
    cout << "     C++ STRINGS" << endl;
    cout << "============================================" << endl << endl;

    // ========================================================
    // PART 1: STRING CREATION AND INITIALIZATION
    // ========================================================
    
    cout << "--- PART 1: CREATION & INITIALIZATION ---" << endl << endl;
    
    // Empty string
    string empty;
    
    // From C-string literal
    string hello = "Hello, World!";
    
    // Using constructor
    string filled(10, '*');  // "**********"
    
    // Copy constructor
    string copy = hello;
    
    // Substring constructor
    string sub(hello, 0, 5);  // "Hello"
    
    // From char array
    char arr[] = "Array String";
    string fromArr(arr);
    
    // From iterators
    string fromIter(hello.begin(), hello.begin() + 5);
    
    // Using assignment
    string assigned;
    assigned = "Assigned value";
    
    cout << "empty: \"" << empty << "\" (length: " << empty.length() << ")" << endl;
    cout << "hello: \"" << hello << "\"" << endl;
    cout << "filled: \"" << filled << "\"" << endl;
    cout << "sub: \"" << sub << "\"" << endl;
    cout << "fromArr: \"" << fromArr << "\"" << endl;
    
    cout << endl;

    // ========================================================
    // PART 2: ACCESSING CHARACTERS
    // ========================================================
    
    cout << "--- PART 2: ACCESSING CHARACTERS ---" << endl << endl;
    
    string str = "Hello";
    
    // Using [] (no bounds checking)
    cout << "str[0] = '" << str[0] << "'" << endl;
    cout << "str[4] = '" << str[4] << "'" << endl;
    
    // Using at() (with bounds checking)
    cout << "str.at(1) = '" << str.at(1) << "'" << endl;
    
    // Front and back
    cout << "str.front() = '" << str.front() << "'" << endl;
    cout << "str.back() = '" << str.back() << "'" << endl;
    
    // Modify characters
    str[0] = 'J';
    cout << "After str[0] = 'J': \"" << str << "\"" << endl;
    
    // Iterate over characters
    str = "Hello";
    cout << "Characters: ";
    for (char c : str) {
        cout << c << " ";
    }
    cout << endl;
    
    // With index
    cout << "With index: ";
    for (size_t i = 0; i < str.length(); i++) {
        cout << "[" << i << "]=" << str[i] << " ";
    }
    cout << endl;
    
    cout << endl;

    // ========================================================
    // PART 3: STRING SIZE AND CAPACITY
    // ========================================================
    
    cout << "--- PART 3: SIZE AND CAPACITY ---" << endl << endl;
    
    string text = "Hello, World!";
    
    cout << "String: \"" << text << "\"" << endl;
    cout << "length(): " << text.length() << endl;
    cout << "size(): " << text.size() << endl;  // Same as length()
    cout << "capacity(): " << text.capacity() << endl;
    cout << "max_size(): " << text.max_size() << endl;
    cout << "empty(): " << boolalpha << text.empty() << endl;
    
    // Reserve capacity
    text.reserve(100);
    cout << "After reserve(100), capacity: " << text.capacity() << endl;
    
    // Resize
    text.resize(5);
    cout << "After resize(5): \"" << text << "\"" << endl;
    
    text.resize(10, '!');
    cout << "After resize(10, '!'): \"" << text << "\"" << endl;
    
    // Clear
    string toClear = "Some text";
    toClear.clear();
    cout << "After clear(), empty: " << toClear.empty() << noboolalpha << endl;
    
    cout << endl;

    // ========================================================
    // PART 4: STRING CONCATENATION
    // ========================================================
    
    cout << "--- PART 4: CONCATENATION ---" << endl << endl;
    
    string first = "Hello";
    string second = "World";
    
    // Using + operator
    string combined = first + " " + second;
    cout << "first + \" \" + second = \"" << combined << "\"" << endl;
    
    // Using += operator
    string result = "Start";
    result += " Middle";
    result += " End";
    cout << "Using +=: \"" << result << "\"" << endl;
    
    // Using append()
    string appended = "Hello";
    appended.append(" World");
    appended.append(3, '!');  // Append 3 exclamation marks
    cout << "Using append(): \"" << appended << "\"" << endl;
    
    // Append substring
    string source = "ABCDEFGH";
    string target = "123";
    target.append(source, 2, 4);  // Append "CDEF"
    cout << "Append substring: \"" << target << "\"" << endl;
    
    // push_back for single character
    string pushed = "ABC";
    pushed.push_back('D');
    pushed.push_back('E');
    cout << "After push_back: \"" << pushed << "\"" << endl;
    
    cout << endl;

    // ========================================================
    // PART 5: STRING COMPARISON
    // ========================================================
    
    cout << "--- PART 5: COMPARISON ---" << endl << endl;
    
    string s1 = "apple";
    string s2 = "banana";
    string s3 = "apple";
    
    cout << boolalpha;
    
    // Using comparison operators
    cout << "\"apple\" == \"apple\": " << (s1 == s3) << endl;
    cout << "\"apple\" == \"banana\": " << (s1 == s2) << endl;
    cout << "\"apple\" < \"banana\": " << (s1 < s2) << endl;
    cout << "\"apple\" > \"banana\": " << (s1 > s2) << endl;
    
    // Using compare()
    int cmp = s1.compare(s2);
    cout << "\ns1.compare(s2) = " << cmp;
    if (cmp < 0) cout << " (s1 < s2)";
    else if (cmp > 0) cout << " (s1 > s2)";
    else cout << " (s1 == s2)";
    cout << endl;
    
    // Compare substrings
    string str1 = "Hello World";
    string str2 = "World";
    cmp = str1.compare(6, 5, str2);  // Compare "World" with "World"
    cout << "Substring compare: " << cmp << endl;
    
    // Case-insensitive comparison (manual)
    string upper = "HELLO";
    string lower = "hello";
    string upper_copy = upper;
    string lower_copy = lower;
    transform(upper_copy.begin(), upper_copy.end(), upper_copy.begin(), ::tolower);
    transform(lower_copy.begin(), lower_copy.end(), lower_copy.begin(), ::tolower);
    cout << "Case-insensitive compare: " << (upper_copy == lower_copy) << endl;
    
    cout << noboolalpha << endl;

    // ========================================================
    // PART 6: SEARCHING
    // ========================================================
    
    cout << "--- PART 6: SEARCHING ---" << endl << endl;
    
    string sentence = "The quick brown fox jumps over the lazy dog";
    
    cout << "String: \"" << sentence << "\"" << endl << endl;
    
    // find() - find first occurrence
    size_t pos = sentence.find("fox");
    cout << "find(\"fox\"): " << pos << endl;
    
    pos = sentence.find("cat");
    cout << "find(\"cat\"): " << pos;
    if (pos == string::npos) cout << " (string::npos - not found)";
    cout << endl;
    
    // find() with start position
    pos = sentence.find("the", 5);  // Start searching from index 5
    cout << "find(\"the\", 5): " << pos << endl;
    
    // rfind() - find last occurrence
    pos = sentence.rfind("the");
    cout << "rfind(\"the\"): " << pos << endl;
    
    // find_first_of() - find first of any characters
    pos = sentence.find_first_of("aeiou");
    cout << "find_first_of(\"aeiou\"): " << pos << " ('" << sentence[pos] << "')" << endl;
    
    // find_last_of()
    pos = sentence.find_last_of("aeiou");
    cout << "find_last_of(\"aeiou\"): " << pos << " ('" << sentence[pos] << "')" << endl;
    
    // find_first_not_of()
    string numbers = "12345abc6789";
    pos = numbers.find_first_not_of("0123456789");
    cout << "find_first_not_of digits: " << pos << " ('" << numbers[pos] << "')" << endl;
    
    // Count occurrences
    string countStr = "banana";
    int count = 0;
    pos = 0;
    while ((pos = countStr.find("a", pos)) != string::npos) {
        count++;
        pos++;
    }
    cout << "Count of 'a' in \"banana\": " << count << endl;
    
    cout << endl;

    // ========================================================
    // PART 7: MODIFYING STRINGS
    // ========================================================
    
    cout << "--- PART 7: MODIFYING STRINGS ---" << endl << endl;
    
    string modStr = "Hello World";
    cout << "Original: \"" << modStr << "\"" << endl;
    
    // insert()
    modStr.insert(5, " Beautiful");
    cout << "After insert: \"" << modStr << "\"" << endl;
    
    // erase()
    modStr.erase(5, 10);  // Remove " Beautiful"
    cout << "After erase: \"" << modStr << "\"" << endl;
    
    // replace()
    modStr.replace(6, 5, "C++");
    cout << "After replace: \"" << modStr << "\"" << endl;
    
    // Substring
    string original = "Hello World";
    string substr = original.substr(6, 5);  // "World"
    cout << "Substring(6, 5): \"" << substr << "\"" << endl;
    
    // Swap
    string a = "First";
    string b = "Second";
    cout << "\nBefore swap: a=\"" << a << "\", b=\"" << b << "\"" << endl;
    a.swap(b);
    cout << "After swap: a=\"" << a << "\", b=\"" << b << "\"" << endl;
    
    // pop_back()
    string popStr = "Hello!";
    popStr.pop_back();
    cout << "\nAfter pop_back: \"" << popStr << "\"" << endl;
    
    cout << endl;

    // ========================================================
    // PART 8: CASE CONVERSION
    // ========================================================
    
    cout << "--- PART 8: CASE CONVERSION ---" << endl << endl;
    
    string mixedCase = "HeLLo WoRLD";
    cout << "Original: \"" << mixedCase << "\"" << endl;
    
    // To uppercase
    string upper = mixedCase;
    transform(upper.begin(), upper.end(), upper.begin(), ::toupper);
    cout << "Uppercase: \"" << upper << "\"" << endl;
    
    // To lowercase
    string lower = mixedCase;
    transform(lower.begin(), lower.end(), lower.begin(), ::tolower);
    cout << "Lowercase: \"" << lower << "\"" << endl;
    
    // Capitalize first letter
    string capitalize = "hello world";
    if (!capitalize.empty()) {
        capitalize[0] = toupper(capitalize[0]);
    }
    cout << "Capitalized: \"" << capitalize << "\"" << endl;
    
    // Title case
    string titleCase = "hello world";
    bool newWord = true;
    for (char& c : titleCase) {
        if (newWord && isalpha(c)) {
            c = toupper(c);
            newWord = false;
        } else if (isspace(c)) {
            newWord = true;
        }
    }
    cout << "Title case: \"" << titleCase << "\"" << endl;
    
    cout << endl;

    // ========================================================
    // PART 9: STRING CONVERSION
    // ========================================================
    
    cout << "--- PART 9: TYPE CONVERSION ---" << endl << endl;
    
    // String to numbers
    string intStr = "42";
    string floatStr = "3.14159";
    
    int intVal = stoi(intStr);
    long longVal = stol(intStr);
    float floatVal = stof(floatStr);
    double doubleVal = stod(floatStr);
    
    cout << "stoi(\"42\") = " << intVal << endl;
    cout << "stol(\"42\") = " << longVal << endl;
    cout << "stof(\"3.14159\") = " << floatVal << endl;
    cout << "stod(\"3.14159\") = " << doubleVal << endl;
    
    // Numbers to string
    int num = 123;
    double pi = 3.14159;
    
    string numStr = to_string(num);
    string piStr = to_string(pi);
    
    cout << "\nto_string(123) = \"" << numStr << "\"" << endl;
    cout << "to_string(3.14159) = \"" << piStr << "\"" << endl;
    
    // String to C-string
    string cppStr = "Hello";
    const char* cStr = cppStr.c_str();
    cout << "\nc_str(): \"" << cStr << "\"" << endl;
    
    // Parse with position
    string mixed = "  42 is the answer";
    size_t idx;
    int value = stoi(mixed, &idx);
    cout << "\nstoi(\"  42 is the answer\") = " << value 
         << " (next index: " << idx << ")" << endl;
    
    // Different bases
    string hexStr = "1A";
    string binStr = "1010";
    int fromHex = stoi(hexStr, nullptr, 16);
    int fromBin = stoi(binStr, nullptr, 2);
    cout << "stoi(\"1A\", 16) = " << fromHex << endl;
    cout << "stoi(\"1010\", 2) = " << fromBin << endl;
    
    cout << endl;

    // ========================================================
    // PART 10: STRING STREAMS
    // ========================================================
    
    cout << "--- PART 10: STRING STREAMS ---" << endl << endl;
    
    // Output string stream
    ostringstream oss;
    oss << "Name: " << "John" << ", Age: " << 25;
    string formatted = oss.str();
    cout << "ostringstream: \"" << formatted << "\"" << endl;
    
    // Input string stream
    string data = "100 200 300";
    istringstream iss(data);
    int val1, val2, val3;
    iss >> val1 >> val2 >> val3;
    cout << "istringstream parsed: " << val1 << ", " << val2 << ", " << val3 << endl;
    
    // Parse CSV-like data
    string csvLine = "apple,banana,cherry,date";
    stringstream ss(csvLine);
    string token;
    cout << "Parsed tokens: ";
    while (getline(ss, token, ',')) {
        cout << "[" << token << "] ";
    }
    cout << endl;
    
    // Split by space
    string words = "The quick brown fox";
    stringstream wordStream(words);
    string word;
    cout << "Words: ";
    while (wordStream >> word) {
        cout << "[" << word << "] ";
    }
    cout << endl;
    
    cout << endl;

    // ========================================================
    // PART 11: USEFUL STRING FUNCTIONS
    // ========================================================
    
    cout << "--- PART 11: UTILITY FUNCTIONS ---" << endl << endl;
    
    // Trim whitespace (no built-in function)
    string toTrim = "   Hello World   ";
    cout << "Before trim: \"" << toTrim << "\"" << endl;
    
    // Left trim
    toTrim.erase(0, toTrim.find_first_not_of(" \t\n\r"));
    cout << "After left trim: \"" << toTrim << "\"" << endl;
    
    // Right trim
    toTrim.erase(toTrim.find_last_not_of(" \t\n\r") + 1);
    cout << "After right trim: \"" << toTrim << "\"" << endl;
    
    // Check if string starts/ends with (C++20 has starts_with/ends_with)
    string testStr = "Hello World";
    string prefix = "Hello";
    string suffix = "World";
    
    bool startsWith = testStr.substr(0, prefix.size()) == prefix;
    bool endsWith = testStr.size() >= suffix.size() && 
                    testStr.substr(testStr.size() - suffix.size()) == suffix;
    
    cout << boolalpha;
    cout << "\n\"Hello World\" starts with \"Hello\": " << startsWith << endl;
    cout << "\"Hello World\" ends with \"World\": " << endsWith << endl;
    
    // Reverse string
    string toReverse = "Hello";
    reverse(toReverse.begin(), toReverse.end());
    cout << "\nReversed \"Hello\": \"" << toReverse << "\"" << endl;
    
    // Check if palindrome
    string palindrome = "racecar";
    string reversed = palindrome;
    reverse(reversed.begin(), reversed.end());
    bool isPalindrome = palindrome == reversed;
    cout << "\"racecar\" is palindrome: " << isPalindrome << endl;
    
    cout << noboolalpha << endl;

    cout << "============================================" << endl;
    cout << "STRING SUMMARY:" << endl;
    cout << "============================================" << endl;
    cout << "• Use std::string over C-strings" << endl;
    cout << "• Rich API for manipulation" << endl;
    cout << "• Safe and easy to use" << endl;
    cout << "• Automatic memory management" << endl;
    cout << "• Works with STL algorithms" << endl;
    cout << "============================================" << endl;

    return 0;
}

// ============================================================
// EXERCISES:
// ============================================================
/*
 * 1. Write a function to check if two strings are anagrams
 * 
 * 2. Implement a function to count words in a sentence
 * 
 * 3. Create a function that removes all vowels from a string
 * 
 * 4. Write a function to find the longest word in a sentence
 * 
 * 5. Implement a simple string encryption (Caesar cipher)
 */
Strings - C++ Tutorial | DeepML