Strings and iostreams - uni-luebeck.de+-Crash... · • Strings are a major component of any C...
Transcript of Strings and iostreams - uni-luebeck.de+-Crash... · • Strings are a major component of any C...
C++ Crash Kurs
Dr. Dennis Pfisterer
Institut für Telematik, Universität zu Lübeck
http://www.itm.uni-luebeck.de/people/pfisterer
Strings and iostreams
• Strings are a major component of any C program– Used a constants on the stack, e.g.: “Hello World”
• C Strings– Strings are represented as arrays of characters– A char* pointer points to the first character of a string
Introduction to strings
– A char* pointer points to the first character of a string– End of a string is indicated by the character ‘\0’– Libc functions for string manipulation (strlen, strcat, …)
• C Strings are also– a major source of errors– time-consuming to use
� C++ provides a superior, common string class
2
C++ strings• C++ strings hide the internal data representation from the user
– Automatic memory management, string termination, …– “Escaping” to c-strings possible
• Avoid the most common errors in C– Overwriting allocated char array bounds
3
– Overwriting allocated char array bounds– Accessing arrays through uninitialized pointers– Using pointers pointing to already free‘d memory regions
• The C++ standard defines a behavior, not an implementation– Different implementations but same behavior– E.g., class wrappers for C-strings, reference counting, copy-on-write, …
• Defined in the namespace std as string– #include <string>
C++ strings: Construction and Initialization• Strings are constructed like normal classes
• Strings may be initialized– as an empty string
– using a character constant
– using (part of) a c-string
– using (part of) another string
4
– using (part of) another string
• Example– #include <string>
using namespace std;int main(int argc, char** argv) {string empty_string;string hello_world(“Hello world");
string copy_of_hello_world(hello_world);string substring(hello_world, 0, 5); // will be hello
}
C++ strings: Find, insert & replace characters
• Find the position of a substring– int s.find(string needle, int start_pos = 0);– Returns 0-based index of the occurence– If needle is not found, string::npos is returned
• Insert characters/strings into existing strings
5
• Insert characters/strings into existing strings– s.insert(int start_pos, string insert_string);
• Replace characters/string in existing strings– s.replace(int start_pos, int replace_length, string replacement);
• Many overloaded versions available in std:string– find, find_first_of, find_last_of, find_first_not_of, find_last_not_of, rfind, …
C++ strings: Find, insert & replace characters
• Usage of find_first_of and find_first_not_of– const string numbers = "0123456789";
string s = "I was born in 1976";
int start = s.find_first_of(numbers);
6
int start = s.find_first_of(numbers);
if( start != string::npos ) {int end = s.find_first_not_of(numbers, start);cout << “First number: " << s.substr(start, end - start) << endl;
}elsecout << “No number found in string” << endl;
C++ strings: Comparison• C++ provides several methods for comparing strings
– Basic operators ==, !=,>, <, >=, <=
– Direct comparison with char* possible
• Also different overloaded compare(…) methods available– Compare two complete strings.
7
– Compare two complete strings.– Compare part of either string to a complete string– Compare (different) subsets of two strings
• Example– string s1("One"), s2("Two");char* tmp = “One”;
– if( s1 == s2 ) … ;– if( s1 != s2 ) … ;– if( s1 == tmp ) … ;– if( s1.compare(1, 7, s2, 22, 7) == 0 ) … ;
C++ strings: Revert to C-style strings• strings can be used with functions taking “traditional” char* arguments– Method string::c_str() provides a pointer to a const char* array– It is not allowed to use the string in a non-const way
• Example
8
• Example– string s1 = “Test”;const char* tmp = s1.c_str();
const char* tmp = s2.c_str();printf("This is a standard c-string: %s\n", tmp);
if( tmp == s2 )cout << "Yes, tmp and s2 are the same" << endl;
See Demo: strings.cpp
Why another I/O library• Libc offers a variety of functions to deal with I/O
– Basic I/O: open, read, write, close, creat, …– Console: printf, scanf, putc, getc, puts, gets, …– File: FILE*, fopen, fclose, fwrite, fseek, …
10
• Different functions for (nearly) the same problem– Many hard-to-guess parameters which should have default values
– No integrated support for i18n (internationalization)– No common interface to these similar problems
� C++ iostreams offer a common interface and superior functionality
iostreams: Fundamentals• The fundamental abstractions are streams
– A stream transports and formats characters of a fixed width – Implemented as objects– Divided into input (istream) and output (ostream) streams– Combination of input and output is called iostream– #include <iostream> provides the basic functionality
11
• Different implementations using the same interface are available such as for– Console: cout, cin– Files: ifstream, ofstream, and fstream– Strings: istringstream, ostringstream, and stringstream
• Two (overloaded) operators provide a common interface– operator<< is called inserter– operator>> is called extractor
iostreams: Extractors• Extractors parse information from a stream according to the destination type
– Overloaded operators available for each basic data type
• Predefined extractor object available for console interaction– Defined in #include <iostream>, called std::cin
• Example
12
• Example– int i;
cin >> i;
– float f;cin >> f;
– char c;cin >> c;
– string s;cin >> s;
iostreams: Inserters• Inserters write information to a stream according to the data type
– Overloaded operators available for each basic data type
• Predefined inserter object available for console interaction– Defined in #include <iostream>, called std::cout
• Example– cout << "i = ";
cout << i;
13
– cout << "i = "; cout << i;cout << "\n";
– cout << "f = ";cout << f;cout << "\n";
– cout << "c = ";cout << c;cout << "\n";
– cout << "buf = ";cout << buf;cout << "\n";
iostreams: Convenient use of inserters/extractors
• Standard operator<< methods returns an ostream&– Signature: ostream& operator<<(ostream& o, <type> t);
• Operator calls may be cascaded– Instead of:
14
– Instead of:• cout << "i = "; cout << i;cout << "\n";
– Cascaded operator call:• cout << "i = " << i << endl;
• Resolves to– operator<<( operator<<( operator<<(cout, “i = ") , i) , endl );
iostreams: Line based I/O• iostream offers three options for line-based I/O
– Member function get( ) and getline( ) operating on char*– Global function getline() defined in #include <string>
• get and getline may be dangerous
15
• get and getline may be dangerous– Use getline and string when possible
• Example– string s;getline(cin, s);
– cout << “You have entered: “ << s << endl;
iostreams: Formatting output• iostreams provides a number of methods to control formatting
• Example– width(int w) causes leading blanks to be added to any value fewer than 10 characters wide for the next output operation
– double values[] = { 1.23, 34.56, 678.9, 1234.56, 123456789.123 }; for( int i = 0; i < 4; i++ )
16
– double values[] = { 1.23, 34.56, 678.9, 1234.56, 123456789.123 }; for( int i = 0; i < 4; i++ ) {
cout.width(10); cout << values[i] << endl;
}
• Output– ______1.23 _____35.36 _____653.7 ___4358.24123456789.123
iostreams: Formatting output• Example
– fill(int char) uses another character than blank for padding
– double values[] = { 1.23, 34.56, 678.9, 1234.56, 123456789.123 }; for( int i = 0; i < 4; i++ ) { cout.width(10);
17
cout.width(10); cout.fill(‘*’);cout << values[i] << endl;
}
• Output– ******1.23 *****35.36 *****653.7 ***4358.24123456789.123
iostreams: Formatting output• Many other formatting options available using so-called flags
• Flags are controlled using set/unset methods– fmtflags ios::setf(fmtflags ored_flag);– fmtflags ios::unsetf(fmtflags clear_flag);
• Some flags are grouped to a field
18
• Some flags are grouped to a field– ios::dec, ios:hex and ios::oct belong to the group ios::basefield
– fmtflags ios::setf(fmtflags bits, fmtflags field); is used to override the current flags of a field with a new value
• Example (switch from decimal to hexadecimal output)– Variant 1: First, unset decimal flag, then set hex flag
• cout.unsetf(ios::dec); cout.setf(ios::hex);
– Variant 2: Override all flags of field ios::basefield• cout.setf(ios::hex, ios::basefield);
iostreams: Formatting output• Example: Decimal and Hex output
– #include <iostream>using namespace ios;using namespace std;
– int main(){int i = 12;
19
int i = 12;
cout.setf(hex, basefield);cout << "Hex: " << i;
cout.setf(dec, basefield);cout << ", decimal: " << i << endl;
}
• Output– Hex: c, decimal: 12
Demo: basic.cpp
iostreams: Formatting output using manipulators
• Using methods to change a streams’ status complicates its use– iostreams provides manipulators that modify a stream “inline”
– #include <iomanip>
• Example using member functions
20
• Example using member functions– cout.setf(ios::hex, ios::basefield);cout << "Hex: " << i;cout.setf(ios::dec, ios::basefield);cout << ", decimal: " << i << endl;
• Example using manipulators– cout << "Hex: " << ios::hex << i << ", decimal: " << ios::dec<< i << endl;
iostreams: Manipulators w/o argumentsManipulator Effect
dec Same as ostream::setf(ios::dec, ios::basefield)
oct Same as ostream::setf(ios::oct, ios::basefield)
21
hex Same as ostream::setf(ios::hex, ios::basefield)
flush Flushes buffered (if any) data to the outut
endl Ends the current line (i.e., ‘\n‘) and calls flush
ws Reads as many whitespace characters (such as ‘ ‘, ‘\n‘, ‘\t‘, …) from the
stream until a non-whitespace character is found
iostreams: Manipulators w/o arguments (1/2)
Manipulator Effect
showbase
noshowbaseShow numeric base (dec, oct, or hex) when printing basic data types
showpos
noshowposShow plus sign (+) for positive values
uppercase
22
uppercase
nouppercaseUse uppercase characters A-F for hexadecimal values and display E for scientific values
showpoint
noshowpointShow decimal point and trailing zeros for floating-point values
skipws
noskipwsSkip white space on input
left
right
internal
left-align, pad on right
Right-align, pad on left
Fill between leading sign or base indicator and value
scientific
fixed
Display preference for floating-point output (scientific notation vs. fixed-point decimal).
iostreams: Manipulators with arguments (2/2)
Manipulator Effect
setiosflags(fmtflags n)Equivalent to ostream::setf(n). Remains until the next change (e.g., ios::setf())
resetiosflags(fmtflags n)Clears only the format flags specified by n.
23
resetiosflags(fmtflags n)Clears only the format flags specified by n. Also in effect until the next change
setbase(base n)Changes base to n, where n is 10, 8, or 16 Prefer to use dec, oct, and hex
setfill(char n) Sets the fill character to n, such as ios::fill( )
setprecision(int n) Sets the precision to n, such as ios::precision( )
setw(int n) Sets the field width to n, such as ios::width( )
Demo: manipulators.cpp
iostreams: Implementing manipulators• Custom manipulators help to simplify repeating tasks on streams
• Definition of the endl manipulator– ostream& endl(ostream&);
• Example of a custom manipulator
24
• Example of a custom manipulator– ostream& ecust_cpp(ostream& os) {return os << “The following student participated in the C++ course:“;
}
– string names[] = { “John Doe”, “Stephen Miller”, “Jessica Smith” };for(int i = 0; i < 3; ++i)cout << ecust_cpp << names[i] << endl;
iostreams: Implementing custom inserters/extractors
• Custom inserter/extractors “flatten” objects to/from streams– Useful for persistence
• Create an operator<< and operator>> for your data type– First parameter is non-const stream reference
25
– First parameter is non-const stream reference
– Second parameter is (const) reference to your object
– Method returns the supplied stream reference for cascading
• Signatures– ostream& operator<<(ostream& o, const YourType& t);
– istream& operator>>(istream& o, YourType& t);
iostreams: Implementing custom inserters• Example
– class Point { public: Point(int x, int y) : x_(x), y_(y) {}int x_; int y_; …
};
26
– ostream& operator<<(ostream& o, const Point& p){return o << “(“ << p.x_ << “,“ << p.y_ << “)“;
}
– Point p(1,1);cout << “Point p = “ << p << endl;
• Output: – (1,1)
iostreams: Implementing custom extractors• Extractors are slightly more difficult since the input data may have an unexpected format– Extractors signal failure by setting flags on the istream– E.g., ios::failbit, ios:: eofbit, ios:: badbit, …– ios::goodbit signals that the stream is good
27
• Interact with flags using member functions– good(), bad(), eof(), fail()– setstate(ios::failbit); sets the fail flag– clear(); resets fail flags
• A stream can also be used in Boolean expressions– while( instream )
do_something(); //Run until !good()
iostreams: File I/O• #include <fstream> provides file I/O functionality
– ifstream for file input– ofstream for file output– Same interface as console I/O
• Different open modes available
29
• Different open modes available– ios::app, append to an existing file– ios::ate, seek to the end of a file (input or output)– ios::trunc, truncate an existing file– ios::binary, use binary, not text mode
• Example– ifstream in(“file.txt”);
– ofstream out(“outfile.txt”, ios::app | ios::binary);
iostreams: File I/O• Use like any other stream
• Examples– ofstream out(“outfile.txt”, ios::app | ios::binary);
out << “This is the file’s content” << endl;
30
out << “This is the file’s content” << endl;
out.close();
– ifstream in(“infile.txt”);
int i; in >> i;
in.close();
Demo: file-io.cpp
iostreams: String I/O• C++ strings may be used as source and target of stream operations
– std::istringstream and std::ostringstream provided by <sstream>
• Examples– #include <sstream>#include <string>#include <iostream>
31
#include <string>#include <iostream>using namespace std;
– istringstream ci("47 1.414 This is a test"); int i; float f; string s;ci >> i >> f >> s;
– ostringstream s;s << “This is a test ” << hex << 10 << dec << 10 << endl;string result = s.str();