【问题标题】:Why can't my loop detect \0 symbol in const string?为什么我的循环不能检测 const 字符串中的 \0 符号?
【发布时间】:2021-06-28 05:00:12
【问题描述】:
#include<iostream>
#include<string>
#include<sstream>
#include <typeinfo>
#include<cmath>
#include<vector>
#include <algorithm>

using namespace std;

class Mystring {
    char *arr;
public:
    Mystring(const char pointer[]) {
        int i = 0;
        while (pointer[i] != '\0') {
            i++;
            cout << pointer[i] << endl;
        }
        arr = new char[i];
        i = 0;
        while (pointer[i] != '\0') {
            arr[i] = pointer[i];
            i++;
        }
    }

    friend ostream& operator<<(ostream& out, Mystring& str) {
        int i = 0;
        while (str.arr[i] != '\0') {
            out << str.arr[i];
            i++;
        }
        return out;
    }
};

int main() {
    Mystring string("Hello, world!");
    cout << string << endl;
}

我正在尝试创建自己的字符串类。 “你好世界!”的长度是 13,但 arr 的长度原来是 17。由于某种我不明白的原因,它充满了一些奇怪的字符。当我尝试计算字符串时,它会返回:Hello, world!¤¤¤¤。

【问题讨论】:

  • 这一定不是你的问题,但请注意,除了using namespace std;之外,使用string作为变量名至少会造成混淆。
  • 请注意不要在str.arr[.]; 中添加\0
  • 我认为编译器会自动完成
  • 确实有帮助。非常感谢

标签: c++ arrays string pointers char


【解决方案1】:

您忘记在arr[] 末尾添加'\0'

此外,应增加大小或arr 以合并此\0,如@user7860670 的回答中所述。

此外,除了using namespace std;之外,使用string作为变量名至少是令人困惑的。

#include<iostream>
#include<string>
#include<sstream>
#include <typeinfo>
#include<cmath>
#include<vector>
#include <algorithm>

//using namespace std;

class Mystring {
    char *arr;
public:
    Mystring(const char pointer[]) {
        int i = 0;
        while (pointer[i] != '\0') {
            i++;
            std::cout << pointer[i] << std::endl;
        }
        arr = new char[i+1];
        i = 0;
        while (pointer[i] != '\0') {
            arr[i] = pointer[i];
            i++;
        }
        arr[i] = '\0';
    }

    friend std::ostream& operator<<(std::ostream& out, const Mystring& str) {
        int i = 0;
        while (str.arr[i] != '\0') {
            out << str.arr[i];
            i++;
        }
        return out;
    }
};

int main() {
    Mystring mstring("Hello, world!");
    std::cout << mstring << std::endl;
}

【讨论】:

    【解决方案2】:

    保存"Hello, world!"(包括终止空值)所需的缓冲区大小为 14,而您只为 13 个字符分配空间并完全忽略终止空值。因此,在operator&lt;&lt; 缓冲区内的迭代过程中,索引将超出范围,这是未定义的行为。

    您应该分配一个额外的字节并确保缓冲区以终止 null 结束

    arr = new char[i + 1];
    i = 0;
    while (pointer[i] != '\0')
    {
       arr[i] = pointer[i];
       ++i;
    }
    arr[i] = '\0';
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-03-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-06-10
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多