|
14 | 14 | * [Difference between char * and char[]](#difference-between-char---and-char--)
|
15 | 15 | * [size of string](#size-of-string)
|
16 | 16 | * [strdup](#strdup)
|
| 17 | + * [strstr](#strstr) |
17 | 18 | * [String copying](#string-copying)
|
18 | 19 | - [C++ String](#c---string)
|
19 | 20 | * [warning iso c++ forbids converting a string constant to ‘char*’ -wwrite-strings](#warning-iso-c---forbids-converting-a-string-constant-to--char----wwrite-strings)
|
@@ -346,23 +347,87 @@ std::cout<<"size of string is: "<<strlen( my_str )<<" bytes and string is: "<< m
|
346 | 347 | 3. `str.size()` also return the size of c++ strings.
|
347 | 348 |
|
348 | 349 | ## strdup
|
349 |
| -String Duplicate, |
350 | 350 |
|
| 351 | +In C++, the `strdup` function (from C) is used to duplicate a string by allocating memory and copying the content of an existing string to that new memory. You would need to use `strdup` when you want to create a copy of a string that you plan to manage manually (for instance, when working with raw pointers and dynamic memory allocation). |
351 | 352 |
|
352 |
| -Each call to `strdup` creates a new `char *` of the size matching the length of the string. You should bind it to a raw pointer `char*` and remove it at some point. |
| 353 | +Here is an example of when you might use `strdup`: |
353 | 354 |
|
| 355 | +### Example: |
354 | 356 | ```cpp
|
355 |
| -char* temp = strdup("foo"); |
| 357 | +#include <iostream> |
| 358 | +#include <cstring> // for strdup and free |
356 | 359 |
|
357 |
| -if(temp) |
358 |
| -{ |
359 |
| - free(temp); |
| 360 | +int main() { |
| 361 | + // Original string |
| 362 | + const char* original = "Hello, World!"; |
| 363 | + |
| 364 | + // Duplicate the string using strdup |
| 365 | + char* duplicate = strdup(original); |
| 366 | + |
| 367 | + // Print both strings |
| 368 | + std::cout << "Original: " << original << std::endl; |
| 369 | + std::cout << "Duplicate: " << duplicate << std::endl; |
| 370 | + |
| 371 | + // Free the memory allocated by strdup |
| 372 | + free(duplicate); |
| 373 | + |
| 374 | + return 0; |
| 375 | +} |
| 376 | +``` |
| 377 | + |
| 378 | +When to use `strdup`: |
| 379 | + |
| 380 | +- **C-style strings**: If you're working with raw C-style strings (`char*`) and need to make a copy of the string that requires its own memory management. |
| 381 | +- **Manual memory management**: When the duplicated string will be used independently and may need to be freed later. |
| 382 | + |
| 383 | +Important notes: |
| 384 | + |
| 385 | +1. `strdup` allocates memory using `malloc`, so you must free it with `free` when you're done using the duplicated string. |
| 386 | +2. In C++, you generally don't need to use `strdup` if you are working with `std::string`, which manages memory automatically. Instead, use `std::string`'s copy constructor or assignment operator, which is safer and more idiomatic. |
| 387 | + |
| 388 | +C++ alternative using `std::string`: |
| 389 | + |
| 390 | +```cpp |
| 391 | +#include <iostream> |
| 392 | +#include <string> |
| 393 | + |
| 394 | +int main() { |
| 395 | + // Original string |
| 396 | + std::string original = "Hello, World!"; |
| 397 | + |
| 398 | + // Duplicate the string using std::string |
| 399 | + std::string duplicate = original; |
| 400 | + |
| 401 | + // Print both strings |
| 402 | + std::cout << "Original: " << original << std::endl; |
| 403 | + std::cout << "Duplicate: " << duplicate << std::endl; |
| 404 | + |
| 405 | + // No need to free memory, std::string handles it automatically |
| 406 | + return 0; |
360 | 407 | }
|
361 | 408 | ```
|
362 | 409 |
|
363 |
| - It allocates a copy of a `char*` on the heap. |
| 410 | +In modern C++ code, using `std::string` is preferable to avoid manual memory management. |
| 411 | + |
364 | 412 |
|
365 | 413 |
|
| 414 | +## strstr |
| 415 | + |
| 416 | +A standard C-style API for searching a substring within a string can be implemented using the `strstr` function, which is part of the C standard library (<string.h>). The `strstr` function searches for the first occurrence of a substring in a string and returns a pointer to the beginning of the substring if found. Otherwise, it returns `NULL`. |
| 417 | + |
| 418 | +```cpp |
| 419 | + char haystack[] = "Hello, World!"; // Now this is modifiable |
| 420 | + const char *needle = "World"; |
| 421 | + |
| 422 | + // Use strstr to find the first occurrence of the needle in the haystack |
| 423 | + char *result = strstr(haystack, needle); |
| 424 | + |
| 425 | + if (result) { |
| 426 | + printf("Found substring: %s\n", result); |
| 427 | + } else { |
| 428 | + printf("Substring not found.\n"); |
| 429 | + } |
| 430 | +``` |
366 | 431 |
|
367 | 432 | ## String copying
|
368 | 433 |
|
@@ -496,19 +561,72 @@ while ((pos = s.find(delimiter)) != std::string::npos)
|
496 | 561 | s.erase(0, pos + delimiter.length());
|
497 | 562 | }
|
498 | 563 | ```
|
499 |
| -## std::string to lower/ upper case |
| 564 | +## std::tolower, std::toupper |
| 565 | + |
| 566 | + |
| 567 | +`std::tolower()` returns an integer, not a `std::string`, and you cannot directly cast the result to a `std::string`. Instead, you should convert the result of `std::tolower()` to a `char`, and then construct a `std::string` from that character. |
| 568 | +```cpp |
| 569 | + unsigned char c = 'A'; |
| 570 | + char lower_c = static_cast<char>(std::tolower(c)); |
| 571 | + |
| 572 | + std::string a(1, lower_c); // Create a string with one character |
| 573 | +``` |
| 574 | +
|
| 575 | +
|
| 576 | +To correctly use `std::tolower` on a std::string, you need to iterate over each character of the string and apply `std::tolower` to it. Since `std::tolower` works on single characters (and returns an int), you should also cast the result back to char. Here's how you can do this: |
| 577 | +
|
| 578 | +
|
| 579 | +```cpp |
| 580 | + std::string input = "Hello, World!"; |
| 581 | + std::string result; |
| 582 | +
|
| 583 | + // Use std::transform to apply std::tolower to each character |
| 584 | + std::transform(input.begin(), input.end(), std::back_inserter(result), |
| 585 | + [](unsigned char c){ return std::tolower(c); }); |
| 586 | +
|
| 587 | + std::cout << "Original: " << input << std::endl; |
| 588 | + std::cout << "Lowercase: " << result << std::endl; |
500 | 589 | ```
|
501 |
| -#include <algorithm> |
502 |
| -#include <cctype> |
503 |
| -#include <string> |
504 | 590 |
|
505 |
| -std::string my_str = "Foo"; |
506 |
| -std::transform(my_str.begin(), my_str.end(), my_str.begin(), |
507 |
| - [](unsigned char c){ return std::tolower(c); }); |
508 |
| -``` |
509 |
| -# string_view |
| 591 | +- `std::transform` is used to apply the transformation (lowercasing in this case) to each character. |
| 592 | +- `std::tolower` is applied to each character of the string. It takes an `unsigned char` as input, so we cast each character to `unsigned char` to avoid undefined behavior with non-ASCII characters. |
| 593 | +- The result is accumulated in the `result` string using `std::back_inserter`. |
| 594 | + |
| 595 | +This will output: |
| 596 | +``` |
| 597 | +Original: Hello, World! |
| 598 | +Lowercase: hello, world! |
| 599 | +``` |
| 600 | + |
| 601 | + |
| 602 | +## std::isalnum |
| 603 | + |
| 604 | +The function `std::isalnum` in C++ checks whether a given character is either an alphanumeric character, i.e., a letter (A-Z, a-z) or a digit (0-9). |
| 605 | + |
| 606 | +- digits (0123456789) |
| 607 | +- uppercase letters (ABCDEFGHIJKLMNOPQRSTUVWXYZ) |
| 608 | +- lowercase letters (abcdefghijklmnopqrstuvwxyz) |
| 609 | + |
| 610 | + |
| 611 | +Return Value: |
| 612 | +- It returns a **non-zero value** (typically `true`) if the character is alphanumeric. |
| 613 | +- It returns **0** (typically `false`) if the character is not alphanumeric. |
510 | 614 |
|
511 | 615 |
|
| 616 | +```cpp |
| 617 | + char c = 'A'; |
| 618 | + if (std::isalnum(c)) { |
| 619 | + std::cout << c << " is alphanumeric." << std::endl; |
| 620 | + } else { |
| 621 | + std::cout << c << " is not alphanumeric." << std::endl; |
| 622 | + } |
| 623 | +``` |
| 624 | +
|
| 625 | +In this case, if `c` is 'A' (an alphanumeric character), `std::isalnum(c)` will return a non-zero value, and the output will be: |
| 626 | +
|
| 627 | +``` |
| 628 | +A is alphanumeric. |
| 629 | +``` |
512 | 630 |
|
513 | 631 | # Find String Case Insensitive
|
514 | 632 | ```cpp
|
|
0 commit comments