200 likes | 315 Views
Plab – Tirgul 8 I/O streams Example: string class. Output stream. C++ has a Stream I/O Library that supersedes C I/O functions. ostream is the type defined by the library for output streams. cout is an object of type ostream attached to stdout. Examples:. #include <iostream>
E N D
Output stream • C++ has a Stream I/O Library that supersedes C I/O functions. • ostream is the type defined by the library for output streams. • cout is an object of type ostream attached to stdout. • Examples: #include <iostream> cout << 7;cout << “Hello World\n”;
Output stream continued • The ostream overloads the << operator for each basic type (compare to toString() in Java). • The operator returns a reference to the output stream, which allows combined output: cout << “2 + 3 = “ << 2 + 3 << endl; • endl is an example of manipulator. endl sends a ‘\n’ character to the stream and flushes it. • In fact endl is a function:<< operator has a version that accepts a function pointer • cerr is similar to cout, it is attached to stderr.
Input stream • istream is the type defined by the library for input streams. • cin is an object of type istream attached to stdin. • Examples: #include <iostream> int i; char a[100]; cin >> i; // reads an intcin >> a; // reads till the 1st space character • Note that >> skips whitespaces.
Input stream continued • When an error occurs (typically because the input format is not what we expect) cin enters a failed state and evaluates to false. • istream overloads the ! opeator and the void* (conversion) operator • For example, to initialize an array we would write: int a[size]; for (int i = 0; i < size && cin >> a[i]; i++) ; • In failed state istream will produce no input. • Use clear() method to continue reading.
More I/O methods • Both ostream and istream have additional methods: • ostream& put(char ch) • ostream& write(char const *str, int length) • int get() // read one char • istream& get(char& ch) // read one char • getline(char *buffer, int size, int delimiter = '\n') • Examples: cout.put(‘a’); char ch1, ch2, str[256]; cin.get(ch1).get(ch2);cin.getline(str, 256);
File streams • To read from files we can use the ifstream, ofstream and fstream. • Example: ofstream outFile(“out.txt”);outFile << “Hello world” << endl; int i; ifstream inFile(“in.txt”);while (inFile >> i) { ... } • Learn the details by yourselves.
MyString .
MyString • We would like to have a string class which will replace the inconvenient char*. class MyString { public: MyString(const char* ); MyString(const MyString& ); ~MyString(); int length() const; bool operator==(const MyString& ); private: void init(const char* ); int m_length; char* m_string; }; copy c-tor
MyString.cpp MyString::init(const char* str) { m_string = new char[m_length]; for (int i = 0; i < m_length; i++) m_string[i] = str[i]; } MyString::MyString(const char* str){ m_length = strlen(str); init(str); } MyString::MyString(const MyString& str) { m_length = str.m_length; init(str.m_string); }
MyString.cpp continued int MyString::length() const { return m_length; } bool MyString::operator==(const MyString& str){ if (str.m_length != m_length) return false; int i; for (i = 0; m_string[i] == str.m_string[i] && i < m_length; i++) ; return (i == m_length);} MyString::~MyString() { if (m_string) delete [] m_string;}
Using our string • Examples of using the string class: MyString a = “12345”; MyString b = a; MyString c = “6879”; if (a == c) { ... } if (a == b) { ... } • But what about something like this? if (a == “123”) { ... } It also works, by constructing MyString object from “123”, and using the operator== already defined.
Adding == • But what about something like this? inside MyString.h • To be able to compare C-style string with MyString we have to define a friend function: if (“123” == a) { ... } It is still undefined (and won’t compile). friend bool operator==(const char*, MyString&); bool operator==(const char* s1, MyString& s2) { // compare s1 with s2.m_string // ...} inside MyString.cpp
= operator • Since up to now we haven’t defined = operator,the default assignment operator is used. It performs a shallow copy, which is obviously not what we want. • If we want our strings to be immutable we should define the = operator as private (in .h file): private: MyString& operator=(const MyString& ); • It would be implemented like this: MyString& MyString::operator=(const MyString& s) { assert(false);}
= operator continued • Otherwise the operator is public public: MyString& operator=(const MyString& ); • It would be implemented like this: MyString& MyString::operator=(const MyString& s) { // delete m_string, copy s.m_string to m_string // ... return *this;} • Returning a reference to the object itself is essential for statements like: s1 = s2 = s3;
Swapping objects • After we have a well defined operator= we can write a swap function for MyString. void swap(MyString& s1, MyString& s2) { MyString temp = s1; s1 = s2; s2 = temp; } • Compare to: (both in C++ and in Java) void swap(MyString s1, MyString s2) { MyString temp = s1; s1 = s2; s2 = temp; }
operator[] • We can use [] to access individual characters in the string. char& MyString::operator[](int i) { return m_string[i];} • Examples of use: MyString a = “12345”; if (a[2] == ‘3’) { ... }a[4] = ‘7’; • Unfortunately it also allows: It will result in segfault in a’s destructor (if not before). Why? delete [] &a[0];
Additional operators • Here are some additional operators we may want in our string class: • != • + (to concatenate strings) • += • < and <= • > and >= • etc... • In fact a string class is part of C++ standard library, it has all the features of MyString and much more…
I/O of MyString • One of the advantages of using streams is the ability to define I/O operators for our own types. friend ostream& operator<<(ostream&, const MyString&); ostream& operator<<(ostream& os, const MyString& str) { os.write(str.m_string[i], str.m_length); return os;} • Example: MyString a = "12345", b = "6789"; cout << a << “ “ << b << endl;
I/O of MyString continued friend istream& operator>>(istream&, MyString&); istream& operator>>(istream& is, MyString& str) { // read until whitespace, // extend str.m_string if required return is;} • Example: MyString a = “” , b = “”; cin >> a >> b;