Technology Sharing

C Series - String (IV) Preliminary simulation implementation of String

2024-07-12

한어Русский языкEnglishFrançaisIndonesianSanskrit日本語DeutschPortuguêsΕλληνικάespañolItalianoSuomalainenLatina

🌈个人主页:Classmate Yuchen 

💫个人格言:“成为自己未来的主人~”   

The following are the functions of String that we will implement in this article:

  1. #pragma once
  2. #include<iostream>
  3. #include<assert.h>
  4. using namespace std;
  5. namespace bit
  6. {
  7. class string
  8. {
  9. public:
  10. typedef char* iterator;
  11. iterator begin();
  12. iterator end();
  13. string(const char* str = "");
  14. ~string();
  15. const char* c_str() const;
  16. size_t size() const;
  17. char& operator[](size_t pos);
  18. private:
  19. char* _str;
  20. size_t size;
  21. size_t _capacity;
  22. };
  23. }

Among these features

string(const char* str = "");

The purpose of writing this way is mainly to take into account empty strings. A default value is added. If the passed string is empty, it will be automatically copied to "0"

  1. const char* c_str() const;
  2. size_t size() const;

In these two lines of code, const is added mainly to ensure that these two functions can be called regardless of whether the passed size string is modifiable.

We put the above codes into the header file.

In the .cpp file, we use it to implement these functions.

#include"String.h"

At the beginning of the .cpp file, we introduce the header file. Some students may wonder whether it will conflict with the String.h file in the C++ library, but the result is no, because the compiler will search in the current directory, and this file already exists in the current directory.

  1. #define _CRT_SECURE_NO_WARNINGS
  2. #include"String.h"
  3. namespace bit
  4. {
  5. string::iterator string::begin()
  6. {
  7. return _str;
  8. }
  9. string::iterator string::end()
  10. {
  11. return _str + _size;
  12. }
  13. string::string(const char* str)
  14. :_size(strlen(str))
  15. {
  16. _str = new char[_size + 1];
  17. _capacity = _size;
  18. strcpy(_str, str);
  19. }
  20. string::~string()
  21. {
  22. delete[] _str;
  23. _str = nullptr;
  24. _size = _capacity = 0;
  25. }
  26. const char* string::c_str() const
  27. {
  28. return _str;
  29. }
  30. size_t string::size() const
  31. {
  32. return _size;
  33. }
  34. char& string::operator[](size_t pos)
  35. {
  36. assert(pos < _size);
  37. return _str[pos];
  38. }
  39. }

This is the basic String code implementation.

Below is the test file for this String

  1. #define _CRT_SECURE_NO_WARNINGS
  2. #include<iostream>
  3. #include"String.h"
  4. namespace bit
  5. {
  6. void test_string1()
  7. {
  8. bit::string s1("hello world");
  9. cout << s1.c_str() << endl;
  10. for (size_t i = 0; i < s1.size(); i++)
  11. {
  12. s1[i]++;
  13. }
  14. for (size_t i = 0; i < s1.size(); i++)
  15. {
  16. cout << s1[i] << " ";
  17. }
  18. cout << endl;
  19. string::iterator it1 = s1.begin();
  20. while (it1 != s1.end())
  21. {
  22. cout << *it1 << " ";
  23. ++it1;
  24. }
  25. cout << endl;
  26. for (auto e : s1)
  27. {
  28. cout << e << " ";
  29. }
  30. cout << endl;
  31. bit::string s2;
  32. cout << s2.c_str() << endl;
  33. }
  34. }
  35. int main()
  36. {
  37. bit::test_string1();
  38. return 0;
  39. }

In fact, for the range for, its underlying layer is the iterator, and the iterator is mainly a package. The different underlying types are renamed with iterator to build a unified superstructure.

So, as long as the basic iterator is built, range for can be used.