Is there no null character when storing a string in the c++ string class?

Asked 2 years ago, Updated 2 years ago, 41 views

#include <iostream>
#include <string>
#include <cctype>

using namespace std;

void ChangeStr(string &s);

int main()
{
 string str;


 while(1)
 {
  cout<<"Enter a string (q to end):";
  cin>>str;
  if(str[0] == 'q')
   break;
  ChangeStr(str);
  cout<<" Changed string: "<<str<<endl;"
  cin.get();
 }
 cout<<"End\n";

 return 0;
}

void ChangeStr(string &s)
{
 int i=0;
 while(i<s.length()) // s[i] != '\0'
 {
  s[i] = toupper(s[i]);
  i++;
 }
}

Hello, everyone I'm asking you a question to get a big help last time and get help today. I think it's definitely right while solving the problem, but there was a runtime error, so I was looking for a solution, and as a result, I solved the problem, but I'm asking because there are still some questions left

The above source is the source of the problem to create a function that takes a reference to a string object as a parameter and changes the content of the string to uppercase. Using the tupper function.

The part to ask is the conditional expression of the while statement in the ChangeStr function.

To know the length of the string from the current body source, s.Use the length() function But that's a modified sauce The source I originally wrote filled in the conditional expression of the while statement with s[i]!='\0' next to it.

I thought it was possible because string &s was declared reference type in the parameter and this refers to the memory space of the string that was passed as a factor. The string of s in the while statement is
null You proceed with the while statement until you meet the character. Write the conditional expression of the sentence like that When I compiled it, it became a compilation, but when I entered a string and the function was called
The error string subscription out of range appears.

I didn't know what the error was, so I searched and found that it was a message that was floated when referring to the empty elements of the array, but I don't understand it well at my level. The string object s is properly referencing the memory space of the string, so I thought it could be used as an array.

But the answer to this question is s.It was solved using length().Returns the length of the string to execute the while statement.And while I was trying to figure out why it didn' I saw somewhere that string class doesn't save your text, is it really true? Is that why the s[i] continues and you don't know the end of the string, so you're sending such an error message?

If the string class does not store null characters, how does the compiler notice the end of the string?

I'd appreciate it if you could answer me

c++ vs2010 string

2022-09-22 13:36

1 Answers

In traditional C languages, list characters and '\0' at the end to express the string.

In contrast, std::string expresses a string with list of characters and length. Therefore, you can see the end of the string without putting '\0' at the end.

For example, if you put "hello" in the std::string variable, the string length 5 and the characters (h, e, are saved. Therefore, if you attempt to access index 5 through operator[], the std:out_of_range exception is exceeded by the string. Note that the exception in operator[] may not occur because it is not standard.

However, actually std::string stores the string in memory, including '\0' for compatibility with the string ending in NULL('\0'). However, it does not allow access to '\0' through operator[]. The '0' stored at this time is only for compatibility and is not used to calculate the length of the string or for any other purpose.

Therefore, you do not need to check the '\0' to see the end of the string. This is because the length of the string is already stored and can be imported through length() or size().

#include <iostream>
#include <string>

int main() {
    std::string v = "hello";
    for (std::size_t i = 0; i < v.size(); ++i)
        std::cout << v[i];
    return 0;
}

As mentioned above, std::string has a member function called c_str() for compatibility. This function returns the char const* address, and since the length of the string is not known in this way, the '\0' check must determine the end of the string.

#include <iostream>
#include <string>

int main() {
    std::string v = "hello";
    char const* p = v.c_str();
    for (; *p != '\0'; ++p)
        std::cout << *p;
    return 0;
}

The summary is as follows.

std::string actually contains '\0' when storing a string in memory, but the concept does not allow access to \0. In addition, since it already has the length of the string, the '\0' navigation shows the end of the string without calculating the length.

The std::string that the debugger shows may not show that '\0' is stored. std::string Because you don't need to show the old paper.

In order to verify this directly, you can write the following code.

#include <iostream>
#include <string>

int main() {
    std::string v = "hello";

    char const* str1 = v.c_str();
    char const* str2 = &v[0];

    std::cout << "address of 'str1': " << static_cast<void const*>(str1) << std::endl;
    std::cout << "address of 'str2': " << static_cast<void const*>(str2) << std::endl;
    std::cout << std::endl;

    for (std::size_t i = 0, size = v.size() + 1; i < size; ++i) {
        std::cout << "str1[" << i << "]: " << str1[i] << " (" << static_cast<int>(str1[i]) << ")" << std::endl;
    }

    for (std::size_t i = 0, size = v.size() + 1; i < size; ++i) {
        std::cout << "str2[" << i << "]: " << str2[i] << " (" << static_cast<int>(str2[i]) << ")" << std::endl;
    }

    return 0;
}

Gets the string ending in NULL for v via char const* str1 = v.c_str();. This string naturally has '\0' at the end of the string.

char const* str2 = &v[0]; gets the address where the v first character is located. std::string stores characters in continuous memory space, so str2 can also read the characters after it.

And if str1 and str2 are the same address, str2 will also have '\0' at the end of the string.

If you run the code above, you can see the results below.

address of 'str1': 0x7fffe79ab658
address of 'str2': 0x7fffe79ab658

str1[0]: h (104)
str1[1]: e (101)
str1[2]: l (108)
str1[3]: l (108)
str1[4]: o (111)
str1[5]:  (0)
str2[0]: h (104)
str2[1]: e (101)
str2[2]: l (108)
str2[3]: l (108)
str2[4]: o (111)
str2[5]:  (0)

You can see that str1 and str2 are the same address. If you look at the output of the 0 to 5 indexes of each string, you can see that index 5 has '\0'.

This means that the address you get from c_str() is eventually the address of the space that stores the character directly from std::string.

You can see that std::string includes '\0' after the list of characters you have.


2022-09-22 13:36

If you have any answers or tips


© 2024 OneMinuteCode. All rights reserved.