user12002570
user12002570

Reputation: 1

How to Write a Custom Read function for my Custom String Class

Hi i am trying to better understand how the standard string class works and so writing a very simple custom string class. The following are my class' members:

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();



};

There are many more member functions that i have and the class is working fine but now i am trying to implement a read() function that will read data(characters) from console into the String object. This is what i have tried so far:

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

    return is;
}

I also have a member function to dynamically check and allocate according to if the object is full and reallocate using std::move. But i don't think my read() function is working. It is a friend function. Also the program is working but not correctly that is when i type something on the console and hit enter the while loop doesn't break . How can i obtain the desired result. String class has elements of type char. How can i read characters from console until end-of-file or the user hit enter and then add them(using push_back()) to the String object? I am calling the read() function from my main.cpp files as read(std::cin, mystringobject);

screenshot1

The above screenshot shows what is printed on the console using std::cout<<ch<<std::endl; Any idea why this is printed?

Upvotes: 0

Views: 191

Answers (1)

Joseph Larson
Joseph Larson

Reputation: 9058

The code looks good, but I'd change it to be called operator>>() --

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

    return is;
}

That way you can just do:

cin >> obj;

Which is the normal way to do this.

I did find some issues after the comments below, so I wrote a complete test as follows. I'll add some info at the end:

#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;
}

See the first line of main() -- without it, the cin never reads the newline, and the loop inside the reader never complets. Here's a build and run:

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

Upvotes: 2

Related Questions