【问题标题】:How to Write a Custom Read function for my Custom String Class如何为我的自定义字符串类编写自定义读取函数
【发布时间】:2021-06-15 21:52:40
【问题描述】:

您好,我正在尝试更好地理解标准字符串类的工作原理,因此编写了一个非常简单的自定义字符串类。以下是我班的成员:

class String {
public:
   String() : first_elem(nullptr), first_free(nullptr), cap(nullptr) { }
   String(const String&);//copy constructor
   String(std::initializer_list<char>);
   
   
   void push_back(const char &ch){
check_and_allocate();
    alloc.construct(last_elem++,ch);
};
   void pop_back();



};

我还有更多的成员函数,并且该类工作正常,但现在我正在尝试实现一个 read() 函数,它将从控制台读取数据(字符)到 String 对象。这是我迄今为止尝试过的:

std::istream& read(std::istream &is, String& obj){
     char ch;
     while(is >> ch and ch!='\n'){
         obj.push_back(ch);
     }
    

    return is;
}

我还有一个成员函数,可以根据对象是否已满动态检查和分配,并使用 std::move 重新分配。但我不认为我的read() 功能有效。这是一个朋友功能。此外,当我在控制台上键入内容并点击进入时,程序正在运行但不正确,while 循环不会中断。我怎样才能获得想要的结果。 String 类具有 char 类型的元素。如何从控制台读取字符直到文件结束或用户按回车键,然后将它们(使用 push_back())添加到 String 对象?我将 main.cpp 文件中的 read() 函数调用为 read(std::cin, mystringobject);

上面的截图显示了使用std::cout&lt;&lt;ch&lt;&lt;std::endl;在控制台上打印的内容 知道为什么要打印这个吗?

【问题讨论】:

  • 我不认为void push_back(); 会有用。
  • 它的void push_back(const char &amp;ch);
  • 检查&gt;&gt;的优先顺序。
  • @JDługosz &gt;&gt; 的优先级高于 && 两者都具有左关联性。你能澄清一下这里发生了什么,为什么这些盒子和那些是什么!?谢谢
  • 我并没有去查看它是否真的错了;这只是需要注意的事情——&amp;&amp; 术语中使用了不寻常的运算符。

标签: c++ string c++11 c++14


【解决方案1】:

代码看起来不错,但我会将其更改为 operator>>() --

std::istream & operator>>(std::istream &is, String& obj){
     char ch;
     while(is >> ch and ch!='\n'){
         obj.push_back(ch);
     }

    return is;
}

这样你就可以做到:

cin >> obj;

这是正常的做法。

我在下面的cmets之后确实发现了一些问题,所以我写了一个完整的测试如下。我会在最后添加一些信息:

#include <iostream>
#include <string>
#include <vector>

using std::cin;
using std::cout;
using std::endl;
using std::string;

std::istream & operator>>(std::istream &istr, std::vector<char> & vec) {
    char ch;

    while (istr >> ch && ch != '\n') {
        vec.push_back(ch);
    }
    return istr;
}

int main(int, char **) {
    std::cin >> std::noskipws;
    std::vector<char> vec;

    cout << "Input: ";
    cout.flush();
    cin >> vec;
    cout << "Got the vec." << endl;
    string myStr(vec.begin(), vec.end());
    cout << "Length of vec: " << vec.size()
        << ". Convert to string: " << myStr
        << endl;
}

查看main() 的第一行——没有它,cin 永远不会读取换行符,并且阅读器内部的循环永远不会完成。这是一个构建和运行:

$ clear && g++ -std=c++17 Foo.cpp -o Foo && Foo
Input: Test
Got the vec.
Length of vec: 4. Convert to string: Test

【讨论】:

  • 是的,我知道我可以重载 >> 运算符。顺便说一句,我们的两个代码似乎都不起作用。例如,当 o wrte while(is &gt;&gt; ch &amp;&amp; ch!='\n'){obj.push_back(ch);std::cout&lt;&lt;ch;} 然后在控制台上出现一些带有 0 0 0 1 的方框。我在我的答案中附上了屏幕截图,检查一下。现在我也在使用一个不同的方案,它似乎有效:while(ch=std::cin.get()){if(ch!='\n'){obj.push_back();}}。这似乎可行,但以前的案例(屏幕截图)不起作用,知道为什么吗?
  • 查看我更新的代码,这是一个实际运行。
猜你喜欢
  • 1970-01-01
  • 2022-08-19
  • 2018-06-07
  • 2013-08-11
  • 2020-11-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-03-17
相关资源
最近更新 更多