I have a simple string class that uses a vector to hold the characters.
Code:
#include <algorithm>
#include <cctype>
#include <cstring>
#include <iostream>
#include <iterator>
#include <vector>
using std::istream;
using std::ostream;
using std::isspace;
using std::copy;
class String
{
public:
friend istream& operator>>(istream& is, String& s);
friend ostream& operator<<(ostream& os, const String& s);
// include trailing 0 for c_str()
String(const char* s = ""): str(s, s + (std::strlen(s) + 1)) {}
char& operator[](int index) { return str[index]; }
const char& operator[](int index) const { return str[index]; }
String& operator+=(const String& s);
// exclude trailing 0 in size
int size() const { return str.size() - 1; }
const char* c_str() const { return static_cast<const char*>(&str[0]); }
private:
std::vector<char> str;
};
istream& operator>>(istream& is, String& s)
{
// empty the existing string
s.str.clear();
char c;
// read and discard leading whitespace
while (is.get(c) && isspace(c))
{
// nothing to do
}
if (is)
{
do
{
s.str.push_back(c);
}
while (is.get(c) && !isspace(c));
s.str.push_back(0);
// if we read whitespace, put it back on the stream
if (is)
{
is.unget();
}
}
return is;
}
ostream& operator<<(ostream& os, const String& s)
{
// exclude trailing 0 in drawing
copy(s.str.begin(), s.str.end() - 1, std::ostream_iterator<const char>(os));
return os;
}
String& String::operator+=(const String& s)
{
str.pop_back(); // replace trailing 0
copy(s.str.begin(), s.str.end(), std::back_inserter(str));
return *this;
}
String operator+(const String& s, const String& t)
{
String r = s;
r += t;
return r;
}
It works great when I try it out, but I'm not sure if the way I do c_str() is right. Can I assume that a vector can be used like an array if I cast the first character into a pointer?
Code:
const char* c_str() const { return static_cast<const char*>(&str[0]); }