1. Trang chủ
  2. » Công Nghệ Thông Tin

A Complete Guide to Programming in C++ part 42 doc

10 292 0
Tài liệu đã được kiểm tra trùng lặp

Đang tải... (xem toàn văn)

THÔNG TIN TÀI LIỆU

Thông tin cơ bản

Tiêu đề Closing Files
Trường học Standard University
Chuyên ngành Computer Science
Thể loại Học phần
Năm xuất bản 2023
Thành phố City Name
Định dạng
Số trang 10
Dung lượng 188,62 KB

Các công cụ chuyển đổi và chỉnh sửa cho tài liệu này

Nội dung

䊐 MotivationAfter you have completed file manipulation, the file should always be closed for the fol-lowing reasons: ■ data may be lost, if for some reason the program is not terminated

Trang 1

䊐 Motivation

After you have completed file manipulation, the file should always be closed for the fol-lowing reasons:

■ data may be lost, if for some reason the program is not terminated correctly

■ there is a limit to the number of files that a program can open simultaneously

A program that terminates correctly will automatically close any open files before exit-ing A file stream destructor will also close a file referenced by a stream However, if the file is no longer in use before this point, you should close the file explicitly

Each of the file stream classes contains a definition of a void type method called

close(), which is used to close the file belonging to the stream

Example: myfile.close();

However, the file stream continues to exist It is therefore possible to use the stream

to open and manipulate another file

If you are not sure whether a file stream is currently accessing a file, you can always perform a test using the is_open()method In the case of the myfilefile stream, the test is as follows:

Example: if( myfile.is_open() )

{ /* */ } // File is open

Open files are also closed when you call the global function exit() The actual reason for using this function is to terminate a program in an orderly manner and return an error code to the calling process

Prototype: void exit( int status );

The calling process, to which the status error code is passed for evaluation, will often be the command interpreter—a Unix shell, for example Successful program execu-tion normally produces the error code 0 The statement return n;is thus equivalent

to the statement exit(n);when used in the main()function

The program on the opposite page copies a file stated in the command line If the user forgets to state a second (target) file, the source file is copied to standard output In this case, the source file will need to be a text file

Trang 2

390 C H A P T E R 1 8 F U N D A M E N T A L S O F F I L E I N P U T A N D O U T P U T

// Pizza_W.cpp // Demonstrating output of records block by block

//

-#include <iostream>

#include <fstream>

using namespace std;

char header[] =

" * * * P I Z Z A P R O N T O * * *\n\n";

// Record structure:

struct Pizza { char name[32]; float price; };

const int MAXCNT = 10;

Pizza pizzaMenu[MAXCNT] = {

{ "Pepperoni", 9.90F }, { "White Pizza", 15.90F }, { "Ham Pizza", 12.50F }, { "Calzone", 14.90F } }; int cnt = 4;

char pizzaFile[256] = "pizza.fle";

int main() // To write records {

cout << header << endl;

// To write data into the file:

int exitCode = 0;

ofstream outFile( pizzaFile, ios::out|ios::binary );

if( !outFile) {

cerr << "Error opening the file!" << endl;

exitCode = 1;

} else { for( int i = 0; i < cnt; ++i) if( !outFile.write( (char*)&pizzaMenu[i],

sizeof(Pizza)) ) { cerr << "Error writing!" << endl;

exitCode = 2;

} } if( exitCode == 0) cout << "\nData has been added to file "

<< pizzaFile << "\n" << endl;

return exitCode;

}

READING AND WRITING BLOCKS

Sample program

Trang 3

The file stream classes can use all the public operations defined in their base classes This means you can write formatted or unformatted data to a file or read that data from the file block by block or character by character

䊐 Formatted and Unformatted Input and Output

The previous sample programs illustrated how to use the methods get(),getline(), andput()to read or write data from or to text files Formatted input and output of numerical values, for example, requires the >> and << operators and appropriate manip-ulators or formatting methods

Example: double price = 12.34;

ofstream textFile("Test.txt");

textFile << "Price: " << price << "Dollar" << endl;

The file Test.txtwill contain a line of text, such as "Price " that exactly matches the screen output

Converting binary data to legible text is not practicable if you are dealing with large amounts of data It makes sense to write the data for a series of measurements to a binary file in the order in which they occur in the program To do so, you simply open the file

in binary mode and write the data to the file, or read it from the file, block by block

䊐 Transferring Data Blocks

Theostreammethodwrite()transfers given number of bytes from main memory to a file

Prototype: ostream& write( const char *buf, int n);

Sincewrite()returns a reference to the stream, you can check to ensure that the write operation was successful

Example: if( ! fileStream.write("An example ", 2) )

cerr << "Error in writing!" << endl;

A warning is issued if an error occurs while writing the characters "An" You can use the

read() method to read data blocks from the file The method transfers a data block from a file to a program buffer

Prototype: istream& read( char *buf, int n);

The methods read()andwrite()are often used for files with fixed length records The block that needs to be transferred can contain one or more records The buffer in main memory is either a structure variable or an array with elements belonging to the structure type You need to cast the address of this memory area to (char *)as shown

in the example opposite

Trang 4

392 C H A P T E R 1 8 F U N D A M E N T A L S O F F I L E I N P U T A N D O U T P U T

// Class Account with methods read() and write() //

-class Account

{

private:

string name; // Account holder unsigned long nr; // Account number double balance; // Balance of account

public:

// Constructors, destructor,

// access methods,

ostream& Account::write(ostream& os) const;

istream& Account::read(istream& is)

};

// write() outputs an account into the given stream os // Returns: The given stream

ostream& Account::write(ostream& os) const

{

os << name << '\0'; // To write a string os.write((char*)&nr, sizeof(nr) );

os.write((char*)&balance, sizeof(balance) );

return os;

}

// read() is the opposite function of write()

// read() inputs an account from the stream is // and writes it into the members of the current object

istream& Account::read(istream& is)

{ getline( is, name, '\0'); // Read a string is.read( (char*)&nr, sizeof(nr) );

is.read( (char*)&balance, sizeof(balance));

return is;

}

OBJECT PERSISTENCE

Class Account

Implementing methods read() and write()

Trang 5

䊐 Storing Objects

Objects are created during program runtime and cleaned up before the program

termi-nates To avoid this volatility, you can make an object persistent, that is, you can store

the object in a file However, you must ensure that the object can be reconstructed, as it was, when read This means dealing with the following issues:

■ Objects can contain other objects You will generally not know how to store a member object

■ Objects can contain references to other objects However, it does not make sense

to store pointer values in a file, as the memory addresses will change each time you re-launch the program

For example, the class Account on the opposite page contains the member object

name, which is a string type As string type objects are used to handle variable length strings, the object just contains a reference to the string It therefore makes no sense to save the memory content of size sizeof(name)occupied by the object name

in a file Instead, you should write the string itself to a file

One possible solution to this issue is to store the data to allow them to be passed to a constructor for the class when read Another solution involves providing methods to allow the objects to write their own data members to files or read them from files This technique is normally preferable since the class can now handle data storage itself, allow-ing it to write internal status data while simultaneously preventallow-ing external access to that data

䊐 Storing Account Class Objects

The opposite page shows the Accountclass, with which you are already familiar File input and output methods have been added to the class A file stream that references a file opened in binary mode is passed as an argument to the methods read() and

write() The return value is the stream in both cases, so the status can be queried when the function is called

Example: if( ! anAccount.write( outFile) )

cerr << "Error in writing!" << endl;

When you read an account, you can simultaneously create an empty object that the

read()method can access

Example: if( ! anAccount.read( inFile) )

cerr << "Error in reading!" << endl;

The member object nameis saved as a C string, that is, as a string terminated by the null character,'\0' The << operator and the function getline()are available for this task

Trang 6

394 C H A P T E R 1 8 F U N D A M E N T A L S O F F I L E I N P U T A N D O U T P U T

fcopy file1 file2

A file,file1, is copied to file2 If file2already exists, it is overwritten fcopy file1

A file,file1, is copied to standard output, that is, to the screen if standard output has not been redirected

fcopy For calls without arguments, the source and destination files are entered

in a user dialog

Ifisis a file stream that references a file opened for reading, the following call

Example: char buf[1024];

is.read(buf, 1024);

transfers the next 1024 bytes from file to the buffer buf Provided that no error occurs, no less than 1024 bytes will be copied unless end-of-file is reached In this case the failandeofbits are set.The last block of bytes

to be read also has to be written to the destination file.The method

gcount()returns the number of bytes transferred by the last read operation

Example: int nread = is.gcount(); // Number of bytes

// in last read op

EXERCISES

For exercise 1 Possible calls to the program fcopy :

More details on the istream class method read()

Trang 7

Exercise 1

The sample program fcopy1, which copies a file to the screen or to a second file, was introduced in this chapter.Write a program named fcopyto enhance

fcopy1as follows:

■ If the program is launched without any arguments, it does not issue an error message and terminate but requests user input for the names of the source and target files If an empty string is given as the name of the tar-get file, that is, the Return key is pressed, the source file is displayed on screen

■ If the command line or the user dialog contains valid source and target

file names, a binary copy operation is performed.

■ Copy the data block by block with the read()andwrite()methods The default block size is 1024 bytes

■ Thecopy()function returns falseif an error occurs while copying and

truein all other cases

Also refer to the notes on the opposite page

Exercise 2

a Modify the sample program Pizza_w.cppin this chapter to allow the user to add new pizza records to the four standard pizzas and store these records on file

b Then write a program called Pizza_r.cpp, which displays the pizza menu, that is, outputs the contents of the pizza file

Exercise 3

Test the methods read()andwrite()in the Accountclass.To do so, write a program called Account_rw.cppthat

■ initializes an array with account objects and stores the array in a file

■ reads the contents of the file to a second array and displays the accounts

in that array to allow you to check them

Use binary mode for read or write access to the file

Trang 8

396 C H A P T E R 1 8 F U N D A M E N T A L S O F F I L E I N P U T A N D O U T P U T

New data members:

string filename; // File name bool dirty; // true, if data is not

// stored yet

New methods:

const string& getFilename() const;

bool setFilename( const string& fn);

bool isDirty() const;

bool load(); // Read data from the file bool save(); // Save data

bool saveAs(); // Save data as

* * * * * Telephone List * * * * *

S = Show all entries

F = Find a telephone number

A = Append an entry

D = Delete an entry

-O = -Open a file

W = Save in the file

U = Save as

-Q = -Quit the program

Your choice:

For Exercise 4 New members of class TelList

Extended menu of the application program

Trang 9

Exercise 4

The program TelList, which was written as an exercise for Chapter 16, needs

to be modified to allow telephone lists to be saved in a file

To allow this, first add the data members and methods detailed on the

opposite page to TelList.The string filenameis used to store the name of the file in use.The dirty flag is raised to indicate that the phone list has been changed but not saved.You will need to modify the existing methods append()

anderase()to provide this functionality

The strings in the phone list must be saved as C strings in a binary file,

allowing for entries that contain several lines

Add the following items to the application program menu:

O = Open a file

Read a phone list previously stored in a file

W = Save

Save the current phone list in a file

U = Save as

Save the current phone list in a new file

Choosing one of these menu items calls one of the following methods as applicable:load(), save()orsaveAs().These methods return truefor a successful action and false otherwise.The user must be able to supply a file name for the save()method, as the list may not have been read from a file previously

If the phone list has been modified but not saved, the user should be

prompted to save the current phone list before opening another file or

terminating the program

Trang 10

398 C H A P T E R 1 8 F U N D A M E N T A L S O F F I L E I N P U T A N D O U T P U T

SOLUTIONS Exercise 1

// -// fcopy.cpp

// Copy files // Call: fcopy [ source [ destination ] ] //

-#include <iostream>

#include <fstream>

using namespace std;

char usage[] = "Call: fcopy [source [destination]}";

inline void openerror( const char *file) {

cerr << "Error opening the file " << file << endl;

exit(1);

}

bool copy( istream& is, ostream& os), // Prototype,

ok = true; // ok flag

int main(int argc, char *argv[]) {

char source[256] = "", dest[256] = "";

switch( argc ) {

case 1: // No file declared

// ==> input file name cout << "Copying source file to "

"destination file!\n"

"Source file: ";

cin.getline( source, 256);

if( strlen(source) == 0) { cerr << "No source file declared!" << endl;

return 1;

} cin.sync(); // No previous input cout << "Destination file: ";

cin.getline( dest, 256);

break;

case 2: // One file is declared strcpy( source, argv[1]);

break;

case 3: // Source and destination files are declared strcpy( source, argv[1]);

strcpy( dest, argv[2]);

break;

Ngày đăng: 06/07/2014, 17:21

TỪ KHÓA LIÊN QUAN