Reputation: 1
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);
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
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