strings and iostreams - uni-luebeck.de+-crash... · • strings are a major component of any c...

32
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

Upload: vanthien

Post on 22-Feb-2018

222 views

Category:

Documents


0 download

TRANSCRIPT

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

iostreamsiostreams

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: Implementing custom extractors

28Demo: customop.cpp

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

iostreams: Read a file into a string

• Example

– ifstream f(“infile.txt“); ostringstream os;string s;

32

– os << f.rdbuf(); //rdbuf() returns a streambuffer object s = os.str();