Trang 1 trên tổng số 2 12 Cuối cùngCuối cùng
Từ 1 tới 10 trên tổng số 15 kết quả

Đề tài: Transaction simulation trong lập trình C++

  1. #1
    Ngày gia nhập
    12 2007
    Bài viết
    48

    Arrow Transaction simulation trong lập trình C++

    1) Bài này em làm nửa năm nay rồi. mỗi lần gặp 1 problem, em đều tự giải quyết nhưng đến problem này thì em không tìm ra cách giải quyết vì nó vừa liên quan đến hệ thống vừa liên quan đến STL.
    2) Trước hết tạo file tên là "in.txt" trong cùng thư mục, chạy code, ví dụ khi nhập:
    Enter file name: in.txt
    Enter choice: 1
    Enter account to add: 1
    Enter name: John
    Enter balance: 111
    Enter choice: 4

    Kết quả là trong cùng thư mục sẽ tạo ra file "out.txt" có dạng như sau:
    1 John 111

    Làm tiếp với:
    Enter choice: 1
    Enter account to add: 2
    Enter name: abcdefghijklmnop (16 ký tự - vượt quá 2 byte)
    Enter balance: 222
    Enter choice: 4

    Thì 1 bảng thông báo lỗi violation gì đó hiện ra.

    3) Em nghĩ là phải đặt chỗ cho thành phần name của lớp Client lớn ra, nhưng không biết cách T.T
    Em cũng nghĩ là thay kiểu của thành phần name là char* hoặc char[] nhưng phức tạp quá.
    Hay là hệ điều hành giới hạn mỗi thành phần của record chỉ dc dưới 2 byte?
    Lỡ tên khách hàng nào 16 ký tự thì sao +.=

    4) Giúp em với, thanks nhiều T.T

    C++ Code:
    1. // header files //
    2. #include <iostream>
    3. using std::cout;
    4. using std::cin;
    5. using std::endl;
    6. using std::ios;
    7. using std::ostream;
    8. using std::cerr;
    9. #include <iomanip>
    10. using std::setw;
    11. #include <fstream>
    12. using std::fstream;
    13. using std::ifstream;
    14. using std::ofstream;
    15. #include <string>
    16. using std::string;
    17. #include <stdexcept>
    18. using std::logic_error;
    19. using std::exception;
    20.  
    21. // class ClientData //
    22. class ClientData
    23. {
    24.     public:
    25.         ClientData(int acc = 0, string n = "NONAME", double bal = 0);
    26.         ClientData(const ClientData &right);
    27.         void setClientData(int acc, string n, double bal);
    28.         void setAccount(int acc);
    29.         void setName(string n);
    30.         void setBalance(double bal);
    31.         int getAccount() const {    return account; }
    32.         double getBalance() const { return balance; }
    33.         string getName() const {    return name;    }
    34.     private:
    35.         int account;
    36.         string name;       
    37.         double balance;    
    38. };
    39.  
    40. ClientData::ClientData(int acc, string n, double bal)
    41. {   setClientData(acc, n, bal); }
    42.  
    43. ClientData::ClientData(const ClientData &right)
    44. {   setClientData(right.account, right.name, right.balance);    }
    45.  
    46. void ClientData::setClientData(int acc, string n, double bal)
    47. {
    48.     setAccount(acc);
    49.     setName(n);
    50.     setBalance(bal);
    51. }
    52.  
    53. void ClientData::setAccount(int acc)
    54. {   account = acc;  }
    55.  
    56. void ClientData::setName(string n)
    57. {   name = n;   }
    58.  
    59. void ClientData::setBalance(double bal)
    60. {   balance = bal;  }
    61.  
    62.  
    63. class Process
    64. {
    65.     public:
    66.         Process(const string &fileName);
    67.         ~Process() { storeFile.close(); }
    68.         void switchAction();
    69.         void instruction() const;
    70.     private:
    71.         fstream storeFile;     
    72.         void addAccount();
    73.         void createFile();
    74.         int getAccount(const string &prompt);
    75. };
    76.  
    77. Process::Process(const string &fileName)
    78. {
    79.     storeFile.open(fileName.c_str());
    80.     if(!storeFile)
    81.         throw logic_error("COULDN'T OPEN FILE\n");
    82. }
    83.  
    84. void Process::addAccount()
    85. {
    86.     int acc; ClientData client;
    87.     acc = getAccount("Enter account to add: ");    
    88.  
    89.     storeFile.seekg((acc - 1) * sizeof(ClientData));   
    90.     storeFile.read(reinterpret_cast<char *>(&client), sizeof(ClientData));
    91.     storeFile.seekg(0);
    92.     storeFile.clear();
    93.  
    94.     // If the account at that position is zero, the program writes information into the file
    95.     //    as records.
    96.     // If it is not zero, the program prints "Couldn't" because that position had information //
    97.     if(client.getAccount() == 0)
    98.     {
    99.         string name; double balance;
    100.         client.setAccount(acc);
    101.  
    102.         cout << "Enter name: ";
    103.         getline(cin, name);
    104.         client.setName(name);      
    105.  
    106.         cout << "Enter balance: ";
    107.         cin >> balance;
    108.         client.setBalance(balance);
    109.  
    110.         storeFile.seekp((acc - 1) * sizeof(ClientData));
    111.         storeFile.write(reinterpret_cast<const char *>(&client), sizeof(ClientData));
    112.     }
    113.     else
    114.     {       cout << "COULDN'T ADD" << endl;     }
    115. }
    116.  
    117. void Process::createFile()
    118. {
    119.     ofstream printFile;
    120.     printFile.open("out.txt");
    121.     if(!printFile)
    122.         throw logic_error("COULDN'T OPEN FILE\n");
    123.  
    124.     ClientData client;
    125.     storeFile.read(reinterpret_cast<char *>(&client), sizeof(ClientData));
    126.     while(!storeFile.eof())
    127.     {
    128.         if(client.getAccount() != 0)
    129.         {
    130.             printFile << client.getAccount() << " ";   
    131.             printFile << client.getName() << " ";          
    132.             printFile << client.getBalance() << endl;
    133.         }      
    134.         storeFile.read(reinterpret_cast<char *>(&client), sizeof(ClientData));
    135.     }
    136.     storeFile.seekg(0);
    137.     storeFile.clear();
    138.     printFile.close();
    139. }
    140.  
    141. void Process::switchAction()
    142. {
    143.     int choice = 0;
    144.     do
    145.     {
    146.         cout << "Enter choice: ";
    147.         cin >> choice;
    148.         switch(choice)
    149.         {
    150.             case 1:
    151.                 addAccount(); break;
    152.             case 2:
    153.                 //removeAccount(); break;
    154.             case 3:
    155.                 //updateAccount(); break;
    156.             case 4:
    157.                 createFile(); break;
    158.             case 5:
    159.                 exit(0);
    160.             default:
    161.                 cout << "Invalid" << endl; break;
    162.         }      
    163.         storeFile.seekg(0);
    164.         storeFile.seekp(0);
    165.         storeFile.clear();
    166.     }
    167.     while(choice != 5);
    168. }
    169.  
    170. void Process::instruction() const
    171. {
    172.     cout << "1. Add new account" << endl;
    173.     cout << "4. Create text file" << endl;
    174.     cout << "5. Exit           " << endl;
    175. }
    176.  
    177. int Process::getAccount(const string &prompt)
    178. {
    179.     int account;
    180.     do
    181.     {
    182.         cout << prompt;
    183.         cin >> account;
    184.     }
    185.     while(account < 0 || account > 10);
    186.     cin.ignore();
    187.     return account;
    188. }
    189.  
    190. void main()
    191. {  
    192.     string fileName;
    193.     cout << "Enter file name: ";
    194.     getline(cin, fileName);
    195.     Process a(fileName);
    196.     a.instruction();
    197.     a.switchAction();
    198. }
    Đã được chỉnh sửa lần cuối bởi rox_rook : 04-12-2008 lúc 04:49 AM.

  2. #2
    Ngày gia nhập
    12 2006
    Nơi ở
    US
    Bài viết
    1,917

    - Trong C++ có overloading operator, dùng read() và write() làm code thì như em thấy đó, code trở nên phức tạp rất nhiều.
    - Để thêm dữ liệu em dùng ios::app khỏi move cursor làm gì cho mệt. Chỗ ghi 1 số integer ra binary file anh dùng "Little-endian", em không biết nó là cái gì thì đọc link này :http://en.wikipedia.org/wiki/Endianness#Little-endian. Em mở cái file output ra coi là sẽ hiểu.
    - Code em thì anh mới bỏ vào VC++ ở trường enter cái file-name thì nó đã crash rồi.
    C++ Code:
    1. #include <iostream>
    2. #include <limits>
    3. #include <string>
    4. #include <vector>
    5. #include <fstream>
    6. #include <algorithm>
    7.  
    8. using namespace std;
    9.  
    10. static const char* file_name = "c++.bin";
    11. const string user_messages   = "Show records from file";
    12.  
    13. const int BYTE_OF_INT        = sizeof( int );
    14. const int BYTE_OF_DOUBLE     = sizeof( double );
    15. const int BYTE_OF_FLOAT      = sizeof( float );
    16. const int BYTE_OF_CHAR       = sizeof( char );
    17. const unsigned BIT_PER_BYTE  = 8;
    18.  
    19.  
    20. struct Record {
    21.     int    x;
    22.     string str;
    23. public :
    24.     Record( int x = 0, const string& str = "" )
    25.         :x( x ), str( str )
    26.     {   }
    27.  
    28.     void show( ostream& o ) const {
    29.         o << endl << x << " " << str;
    30.     }
    31. };
    32.  
    33. inline
    34. ostream& operator <<( ostream& ouf, const Record& rec ) {
    35.     for( int cursor = 0, i = rec.x; cursor < BYTE_OF_INT; ++cursor, i >>= BIT_PER_BYTE )
    36.         ouf.put( i & 0xFF );
    37.  
    38.     ouf << rec.str << '\0';
    39.     return ouf;
    40. }
    41.  
    42. inline
    43. istream& operator >>( istream& inf, Record& rec ) {
    44.     rec.x = 0;
    45.     for( int i = 0; i < BYTE_OF_INT; ++i )
    46.         rec.x += ( inf.get() << ( BIT_PER_BYTE * i ) );
    47.  
    48.     getline( inf, rec.str, '\0' );
    49.     return inf;
    50. }
    51.  
    52. void write_some_records( const vector< Record* >& con, const char* file_name )  {
    53.     ofstream bin_out_file( file_name, ios::binary | ios::trunc );
    54.     for( vector< Record* >::const_iterator b = con.begin(), e = con.end(); b != e; ++b ) {
    55.         bin_out_file << *( *b );
    56.     }
    57.     bin_out_file.close();
    58. }
    59.  
    60. struct DeleteObject {
    61.     template< typename T >
    62.     void operator()( const T* ptr ) const {
    63.         delete ptr;
    64.     }
    65. };
    66.  
    67. void show_records( const char* file_name ) {
    68.     ifstream bin_in_file( file_name, ios::binary );
    69.     auto_ptr< Record > rec( new Record() );
    70.     cout << endl << endl << user_messages;
    71.     while( bin_in_file >> *rec ) {
    72.         rec->show( cout );
    73.     }
    74.  
    75.     bin_in_file.close();
    76. }
    77.  
    78. void append_new_record( const char* file_name, const Record& rec ) {
    79.     ofstream bin_out_file( file_name, ios::binary | ios::app );
    80.     bin_out_file << rec;
    81. }
    82.  
    83. int main()
    84. {
    85.     vector< Record* > records;
    86.     records.push_back( new Record( 1, "Windows"   ) );
    87.     records.push_back( new Record( 2, "Linux"     ) );
    88.     records.push_back( new Record( 3, "Macintosh" ) );
    89.     records.push_back( new Record( 4, "This is a long long long long a long record ever !!!!" ) );
    90.    
    91.     write_some_records( records, file_name );
    92.  
    93.     for_each( records.begin(), records.end(), DeleteObject() );
    94.  
    95.     show_records( file_name );
    96.    
    97.     Record append_rec( 5, "Let's do it" );
    98.    
    99.     append_new_record( file_name, append_rec );
    100.    
    101.     show_records( file_name );
    102.  
    103.     return 0;
    104. }
    Đã được chỉnh sửa lần cuối bởi rox_rook : 04-12-2008 lúc 11:35 AM.

  3. #3
    Ngày gia nhập
    12 2007
    Bài viết
    48

    1) Bài của em phải tạo file "in.txt" trước, trong cùng thư mục.
    Chạy code anh gõ vào "in.txt" (phải có extension, ko có là nó hiện window form ^^).
    Em chạy ổn mà, anh thử lại xem. (Chạy xong anh sẽ hiểu mục đích bài đó làm gì T.T)

    2) Bài của em là random access: đưa con trỏ đến đúng record thứ n trên file rồi ghi, xóa, update record chứ không phải là sequential access (dùng ios::app)

    3) File "in.txt" khi mở bằng notepad sẽ thấy toàn ký tự lạ vì nó nằm theo từng record có kiểu là Client.

    4) Cái em muốn hỏi là: Hình như khi ghi record có thành phần string (dạng autimatically grow) thì nó sẽ ko biết đặt chỗ cho record trên file text là bao nhiêu, thế nên khi xuất ra nó báo lỗi. Gõ name là 15 ký tự thì ko sao, gõ 16 ký tự thì báo lỗi.

    Em xài 2008.

  4. #4
    Ngày gia nhập
    12 2006
    Nơi ở
    US
    Bài viết
    1,917

    Do code không có comment nên anh có lẽ hiểu nhầm, thôi có gì anh về nhà anh sẽ coi lại.
    2) Bài của em là random access: đưa con trỏ đến đúng record thứ n trên file rồi ghi, xóa, update record chứ không phải là sequential access (dùng ios::app)
    Cái này hình như bắt buộc overrite, để anh suy nghĩ lại sau, giờ thì phải về nhà ăn cơm đã !

  5. #5
    Ngày gia nhập
    12 2007
    Bài viết
    48

    1) Em chuyển kiểu của name thành char * thì mọi thứ đã được giải quyết. Nhưng không hiểu tại sao T.T

    2) Em vẫn muốn xài string (vì nó pro) T.T .

    C++ Code:
    1. #include "Utility.h"
    2.  
    3. const int A = 100;
    4. // class ClientData //
    5. class ClientData
    6. {
    7.     public:
    8.         ClientData(int acc = 0, char *n = "NONAME", double bal = 0);
    9.         ClientData(const ClientData &right);
    10.         void setClientData(int acc, char *n, double bal);
    11.         void setAccount(int acc);
    12.         void setName(char *n); 
    13.         void setBalance(double bal);
    14.         int getAccount() const {    return account; }
    15.         double getBalance() const { return balance; }
    16.         char *getName() const { return name;    }
    17.     private:
    18.         int account;
    19.         char *name;    
    20.         double balance;    
    21. };
    22.  
    23. ClientData::ClientData(int acc, char *n, double bal)
    24. {   setClientData(acc, n, bal); }
    25.  
    26. ClientData::ClientData(const ClientData &right)
    27. {   setClientData(right.account, right.name, right.balance);    }
    28.  
    29. void ClientData::setClientData(int acc, char *n, double bal)
    30. {
    31.     setAccount(acc);
    32.     setName(n);
    33.     setBalance(bal);
    34. }
    35.  
    36. void ClientData::setAccount(int acc)
    37. {   account = acc;  }
    38.  
    39. void ClientData::setName(char *n)
    40. {  
    41.     name = new char[strlen(n) + 1];
    42.     if(n != 0)
    43.         strcpy(name, n);
    44.     else
    45.         name[0] = NULL;
    46. }
    47.  
    48. void ClientData::setBalance(double bal)
    49. {   balance = bal;  }
    50.  
    51.  
    52. class Process
    53. {
    54.     public:
    55.         Process(const char *fileName);
    56.         ~Process() { storeFile.close(); }
    57.         void switchAction();
    58.         void instruction() const;
    59.     private:
    60.         fstream storeFile;     
    61.         void addAccount();
    62.         void removeAccount();
    63.         void updateAccount();
    64.         void createFile();
    65.         int getAccount(const char *prompt);
    66. };
    67.  
    68. Process::Process(const char *fileName)
    69. {
    70.     storeFile.open(fileName);
    71.     if(!storeFile)
    72.         throw logic_error("COULDN'T OPEN FILE\n");
    73. }
    74.  
    75. void Process::addAccount()
    76. {
    77.     int acc; ClientData client;
    78.     acc = getAccount("Enter account to add: ");    
    79.  
    80.     storeFile.seekg((acc - 1) * sizeof(ClientData));   
    81.     storeFile.read(reinterpret_cast<char *>(&client), sizeof(ClientData));
    82.     storeFile.seekg(0);
    83.     storeFile.clear();
    84.  
    85.     // If the account at that position is zero, the program writes information into the file
    86.     //    as records.
    87.     // If it is not zero, the program prints "Couldn't" because that position had information //
    88.     if(client.getAccount() == 0)
    89.     {
    90.         char *name = new char[A + 1]; double balance;
    91.         client.setAccount(acc);
    92.  
    93.         cout << "Enter name: ";
    94.         cin.getline(name, A);
    95.         client.setName(name);      
    96.  
    97.         cout << "Enter balance: ";
    98.         cin >> balance;
    99.         client.setBalance(balance);
    100.  
    101.         storeFile.seekp((acc - 1) * sizeof(ClientData));
    102.         storeFile.write(reinterpret_cast<const char *>(&client), sizeof(ClientData));
    103.     }
    104.     else
    105.     {       cout << "COULDN'T ADD" << endl;     }
    106. }
    107.  
    108. void Process::removeAccount()
    109. {
    110.     int acc; ClientData client;
    111.     acc = getAccount("Enter account to remove: ");
    112.     storeFile.seekg((acc - 1) * sizeof(ClientData));
    113.     storeFile.read(reinterpret_cast<char *>(&client), sizeof(ClientData));
    114.     if(client.getAccount() != 0)
    115.     {
    116.         ClientData blankClient;
    117.         storeFile.seekp((acc - 1) * sizeof(ClientData));
    118.         storeFile.write(reinterpret_cast<const char *>(&blankClient), sizeof(ClientData));
    119.         cout << "Account " << acc << " was removed" << endl;
    120.     }
    121.     else
    122.         cerr << "Account " << acc << " is empty" << endl;
    123. }
    124.  
    125. void Process::updateAccount()
    126. {
    127.     int acc; char *name = new char[A + 1]; double balance; ClientData client;
    128.     acc = getAccount("Enter account to update: "); 
    129.     //client.setAccount(acc);
    130.  
    131.     // remove the old record //
    132.     storeFile.seekg((acc - 1) * sizeof(ClientData));
    133.     storeFile.read(reinterpret_cast<char *>(&client), sizeof(ClientData));
    134.     storeFile.seekg(0);
    135.     storeFile.clear();
    136.  
    137.     // Add new record //
    138.     if(client.getAccount() != 0)
    139.     {  
    140.         client.setAccount(acc);
    141.         cout << "Enter name: ";
    142.         cin.getline(name, A);
    143.         client.setName(name);
    144.  
    145.         cout << "Enter balance: ";
    146.         cin >> balance;
    147.         client.setBalance(balance);
    148.    
    149.         storeFile.seekp((acc - 1) * sizeof(ClientData));
    150.         storeFile.write(reinterpret_cast<const char *>(&client), sizeof(ClientData));
    151.     }
    152.     else
    153.         cerr << "Account " << acc << " is empty" << endl;
    154. }
    155.  
    156. void Process::createFile()
    157. {
    158.     ofstream printFile;
    159.     printFile.open("out.txt");
    160.     if(!printFile)
    161.         throw logic_error("COULDN'T OPEN FILE\n");
    162.  
    163.     ClientData client;
    164.     storeFile.read(reinterpret_cast<char *>(&client), sizeof(ClientData));
    165.     while(!storeFile.eof())
    166.     {
    167.         if(client.getAccount() != 0)
    168.         {
    169.             printFile << client.getAccount() << " ";   
    170.             printFile << client.getName() << " ";          
    171.             printFile << client.getBalance() << endl;
    172.         }      
    173.         storeFile.read(reinterpret_cast<char *>(&client), sizeof(ClientData));
    174.     }/*
    175.     storeFile.seekg(0);
    176.     storeFile.clear();*/
    177. }
    178.  
    179. void Process::switchAction()
    180. {
    181.     int choice = 0;
    182.     do
    183.     {
    184.         cout << "Enter choice: ";
    185.         cin >> choice;
    186.         switch(choice)
    187.         {
    188.             case 1:
    189.                 addAccount(); break;
    190.             case 2:
    191.                 removeAccount(); break;
    192.             case 3:
    193.                 updateAccount(); break;
    194.             case 4:
    195.                 createFile(); break;
    196.             case 5:
    197.                 exit(0);
    198.             default:
    199.                 cout << "Invalid" << endl; break;
    200.         }      
    201.         storeFile.seekg(0);
    202.         storeFile.seekp(0);
    203.         storeFile.clear();
    204.     }
    205.     while(choice != 5);
    206. }
    207.  
    208. void Process::instruction() const
    209. {
    210.     cout << "1. Add new account" << endl;
    211.     cout << "2. Remove account " << endl;
    212.     cout << "3. Update account " << endl;
    213.     cout << "4. Create text file" << endl;
    214.     cout << "5. Exit           " << endl;
    215. }
    216.  
    217. int Process::getAccount(const char *prompt)
    218. {
    219.     int account;
    220.     do
    221.     {
    222.         cout << prompt;
    223.         cin >> account;
    224.     }
    225.     while(account < 0 || account > 10);
    226.     cin.ignore();
    227.     return account;
    228. }
    229.  
    230. void main()
    231. {  
    232.     char *fileName = new char[A + 1];
    233.     cout << "Enter file name: ";
    234.     cin.getline(fileName, A);
    235.     Process a(fileName);
    236.     a.instruction();
    237.     a.switchAction();
    238. }

  6. #6
    Ngày gia nhập
    12 2006
    Nơi ở
    US
    Bài viết
    1,917

    Mặc định Transaction simulation trong lập trình C++

    - Code này trong sách How to program C++, anh đã coi qua rồi, lý do là em không thể dùng write() và read() với std::string, đơn giản vì string không phải POD( POD có đặc tính các dữ liệu các bytes nằm kế nhau ), em nên nhớ std::string là typedef của basic_string< charT, trait, allocator< charT < );, và nó không thỏa mãn POD( phải lục 1 đống sách + google mới hiểu tại sao nó sai ).
    - Nhưng anh nghĩ random-access-data file có thể dùng ở dạng text chứ không cần phải binary, vì binary tuy tiết kiệm bộ nhớ nhưng system-dependence. Anh sẽ thử dạng text truy xuất xem sao. Wait me ok !

  7. #7
    Ngày gia nhập
    12 2007
    Bài viết
    48

    Code trong "How to program" viết không chạy được, ko biết có độc giả nào phát hiện ko, em đã test nhiều lần và kết luận sách viết thiếu, còn thiếu chỗ nào thì em quên rồi ^^. Phiên bản này em viết lại đến nay mới hết lỗi.

  8. #8
    Ngày gia nhập
    12 2006
    Nơi ở
    US
    Bài viết
    1,917

    - Em chép từ sách à ? Có lẽ do typing nhầm chăng ? Em thử đoạn code này xem có sai không nhé :
    C++ Code:
    1. // Fig. 17.10: ClientData.h
    2.  
    3. // Class ClientData definition used in Fig. 17.12-Fig. 17.15.
    4.  
    5. #ifndef CLIENTDATA_H
    6.  
    7. #define CLIENTDATA_H
    8.  
    9.  
    10.  
    11. #include <string>
    12.  
    13. using std::string;
    14.  
    15.  
    16.  
    17. class ClientData
    18.  
    19. {
    20.  
    21. public:
    22.  
    23.    // default ClientData constructor
    24.  
    25.    ClientData( int = 0, string = "", string = "", double = 0.0 );
    26.  
    27.  
    28.  
    29.    // accessor functions for accountNumber
    30.  
    31.    void setAccountNumber( int );
    32.  
    33.    int getAccountNumber() const;
    34.  
    35.  
    36.  
    37.    // accessor functions for lastName
    38.  
    39.    void setLastName( string );
    40.  
    41.    string getLastName() const;
    42.  
    43.  
    44.  
    45.    // accessor functions for firstName
    46.  
    47.    void setFirstName( string );
    48.  
    49.    string getFirstName() const;
    50.  
    51.  
    52.  
    53.    // accessor functions for balance
    54.  
    55.    void setBalance( double );
    56.  
    57.    double getBalance() const;
    58.  
    59. private:
    60.  
    61.    int accountNumber;
    62.  
    63.    char lastName[ 15 ];
    64.  
    65.    char firstName[ 10 ];
    66.  
    67.    double balance;
    68.  
    69. }; // end class ClientData
    70.  
    71.  
    72.  
    73. #endif
    74.  
    75.  
    76.  
    77. /**************************************************************************
    78.  
    79.  * (C) Copyright 1992-2005 by Deitel & Associates, Inc. and               *
    80.  
    81.  * Pearson Education, Inc. All Rights Reserved.                           *
    82.  
    83.  *                                                                        *
    84.  
    85.  * DISCLAIMER: The authors and publisher of this book have used their     *
    86.  
    87.  * best efforts in preparing the book. These efforts include the          *
    88.  
    89.  * development, research, and testing of the theories and programs        *
    90.  
    91.  * to determine their effectiveness. The authors and publisher make       *
    92.  
    93.  * no warranty of any kind, expressed or implied, with regard to these    *
    94.  
    95.  * programs or to the documentation contained in these books. The authors *
    96.  
    97.  * and publisher shall not be liable in any event for incidental or       *
    98.  
    99.  * consequential damages in connection with, or arising out of, the       *
    100.  
    101.  * furnishing, performance, or use of these programs.                     *
    102.  
    103.  **************************************************************************/

    C++ Code:
    1. // Fig. 17.11: ClientData.cpp
    2. // Class ClientData stores customer's credit information.
    3. #include <string>
    4. using std::string;
    5.  
    6. #include "ClientData.h"
    7.  
    8. // default ClientData constructor
    9. ClientData::ClientData( int accountNumberValue,
    10.    string lastNameValue, string firstNameValue, double balanceValue )
    11. {
    12.    setAccountNumber( accountNumberValue );
    13.    setLastName( lastNameValue );
    14.    setFirstName( firstNameValue );
    15.    setBalance( balanceValue );
    16. } // end ClientData constructor
    17.  
    18. // get account-number value
    19. int ClientData::getAccountNumber() const
    20. {
    21.    return accountNumber;
    22. } // end function getAccountNumber
    23.  
    24. // set account-number value
    25. void ClientData::setAccountNumber( int accountNumberValue )
    26. {
    27.    accountNumber = accountNumberValue; // should validate
    28. } // end function setAccountNumber
    29.  
    30. // get last-name value
    31. string ClientData::getLastName() const
    32. {
    33.    return lastName;
    34. } // end function getLastName
    35.  
    36. // set last-name value
    37. void ClientData::setLastName( string lastNameString )
    38. {
    39.    // copy at most 15 characters from string to lastName
    40.    const char *lastNameValue = lastNameString.data();
    41.    int length = lastNameString.size();
    42.    length = ( length < 15 ? length : 14 );
    43.    strncpy( lastName, lastNameValue, length );
    44.    lastName[ length ] = '\0'; // append null character to lastName
    45. } // end function setLastName
    46.  
    47. // get first-name value
    48. string ClientData::getFirstName() const
    49. {
    50.    return firstName;
    51. } // end function getFirstName
    52.  
    53. // set first-name value
    54. void ClientData::setFirstName( string firstNameString )
    55. {
    56.    // copy at most 10 characters from string to firstName
    57.    const char *firstNameValue = firstNameString.data();
    58.    int length = firstNameString.size();
    59.    length = ( length < 10 ? length : 9 );
    60.    strncpy( firstName, firstNameValue, length );
    61.    firstName[ length ] = '\0'; // append null character to firstName
    62. } // end function setFirstName
    63.  
    64. // get balance value
    65. double ClientData::getBalance() const
    66. {
    67.    return balance;
    68. } // end function getBalance
    69.  
    70. // set balance value
    71. void ClientData::setBalance( double balanceValue )
    72. {
    73.    balance = balanceValue;
    74. } // end function setBalance
    75.  
    76. /**************************************************************************
    77.  * (C) Copyright 1992-2005 by Deitel & Associates, Inc. and               *
    78.  * Pearson Education, Inc. All Rights Reserved.                           *
    79.  *                                                                        *
    80.  * DISCLAIMER: The authors and publisher of this book have used their     *
    81.  * best efforts in preparing the book. These efforts include the          *
    82.  * development, research, and testing of the theories and programs        *
    83.  * to determine their effectiveness. The authors and publisher make       *
    84.  * no warranty of any kind, expressed or implied, with regard to these    *
    85.  * programs or to the documentation contained in these books. The authors *
    86.  * and publisher shall not be liable in any event for incidental or       *
    87.  * consequential damages in connection with, or arising out of, the       *
    88.  * furnishing, performance, or use of these programs.                     *
    89.  **************************************************************************/

  9. #9
    Ngày gia nhập
    12 2006
    Nơi ở
    US
    Bài viết
    1,917

    C++ Code:
    1. // Fig. 17.15: Fig17_15.cpp
    2. // This program reads a random access file sequentially, updates
    3. // data previously written to the file, creates data to be placed
    4. // in the file, and deletes data previously in the file.
    5. #include <iostream>
    6. using std::cerr;
    7. using std::cin;
    8. using std::cout;
    9. using std::endl;
    10. using std::fixed;
    11. using std::ios;
    12. using std::left;
    13. using std::right;
    14. using std::showpoint;
    15.  
    16. #include <fstream>
    17. using std::ofstream;
    18. using std::ostream;
    19. using std::fstream;
    20.  
    21. #include <iomanip>
    22. using std::setw;
    23. using std::setprecision;
    24.  
    25. #include <cstdlib>
    26. using std::exit; // exit function prototype
    27.  
    28. #include "ClientData.h" // ClientData class definition
    29.  
    30. int enterChoice();
    31. void createTextFile( fstream& );
    32. void updateRecord( fstream& );
    33. void newRecord( fstream& );
    34. void deleteRecord( fstream& );
    35. void outputLine( ostream&, const ClientData & );
    36. int getAccount( const char * const );
    37.  
    38. enum Choices { PRINT = 1, UPDATE, NEW, DELETE, END };
    39.  
    40. int main()
    41. {
    42.    // open file for reading and writing
    43.    fstream inOutCredit( "credit.dat", ios::in | ios::out );
    44.  
    45.    // exit program if fstream cannot open file
    46.    if ( !inOutCredit )
    47.    {
    48.       cerr << "File could not be opened." << endl;
    49.       exit ( 1 );
    50.    } // end if
    51.    
    52.    int choice; // store user choice
    53.  
    54.    // enable user to specify action
    55.    while ( ( choice = enterChoice() ) != END )
    56.    {
    57.       switch ( choice )
    58.       {
    59.          case PRINT: // create text file from record file
    60.             createTextFile( inOutCredit );
    61.             break;
    62.          case UPDATE: // update record
    63.             updateRecord( inOutCredit );
    64.             break;
    65.          case NEW: // create record
    66.             newRecord( inOutCredit );
    67.             break;
    68.          case DELETE: // delete existing record
    69.             deleteRecord( inOutCredit );
    70.             break;
    71.          default: // display error if user does not select valid choice
    72.             cerr << "Incorrect choice" << endl;
    73.             break;
    74.       } // end switch
    75.  
    76.       inOutCredit.clear(); // reset end-of-file indicator
    77.    } // end while
    78.  
    79.    return 0;
    80. } // end main
    81.  
    82. // enable user to input menu choice
    83. int enterChoice()
    84. {
    85.    // display available options
    86.    cout << "\nEnter your choice" << endl
    87.       << "1 - store a formatted text file of accounts" << endl
    88.       << "    called \"print.txt\" for printing" << endl
    89.       << "2 - update an account" << endl
    90.       << "3 - add a new account" << endl
    91.       << "4 - delete an account" << endl
    92.       << "5 - end program\n? ";
    93.  
    94.    int menuChoice;
    95.    cin >> menuChoice; // input menu selection from user
    96.    return menuChoice;
    97. } // end function enterChoice
    98.  
    99. // create formatted text file for printing
    100. void createTextFile( fstream &readFromFile )
    101. {
    102.    // create text file
    103.    ofstream outPrintFile( "print.txt", ios::out );
    104.  
    105.    // exit program if ofstream cannot create file
    106.    if ( !outPrintFile )
    107.    {
    108.       cerr << "File could not be created." << endl;
    109.       exit( 1 );
    110.    } // end if
    111.  
    112.    outPrintFile << left << setw( 10 ) << "Account" << setw( 16 )
    113.       << "Last Name" << setw( 11 ) << "First Name" << right
    114.       << setw( 10 ) << "Balance" << endl;
    115.  
    116.    // set file-position pointer to beginning of readFromFile
    117.    readFromFile.seekg( 0 );
    118.  
    119.    // read first record from record file
    120.    ClientData client;
    121.    readFromFile.read( reinterpret_cast< char * >( &client ),
    122.       sizeof( ClientData ) );
    123.  
    124.    // copy all records from record file into text file
    125.    while ( !readFromFile.eof() )
    126.    {
    127.       // write single record to text file
    128.       if ( client.getAccountNumber() != 0 ) // skip empty records
    129.          outputLine( outPrintFile, client );
    130.  
    131.       // read next record from record file
    132.       readFromFile.read( reinterpret_cast< char * >( &client ),
    133.          sizeof( ClientData ) );
    134.    } // end while
    135. } // end function createTextFile
    136.  
    137. // update balance in record
    138. void updateRecord( fstream &updateFile )
    139. {
    140.    // obtain number of account to update
    141.    int accountNumber = getAccount( "Enter account to update" );
    142.  
    143.    // move file-position pointer to correct record in file
    144.    updateFile.seekg( ( accountNumber - 1 ) * sizeof( ClientData ) );
    145.  
    146.    // read first record from file
    147.    ClientData client;
    148.    updateFile.read( reinterpret_cast< char * >( &client ),
    149.       sizeof( ClientData ) );
    150.  
    151.    // update record
    152.    if ( client.getAccountNumber() != 0 )
    153.    {
    154.       outputLine( cout, client ); // display the record
    155.  
    156.       // request user to specify transaction
    157.       cout << "\nEnter charge (+) or payment (-): ";
    158.       double transaction; // charge or payment
    159.       cin >> transaction;
    160.  
    161.       // update record balance
    162.       double oldBalance = client.getBalance();
    163.       client.setBalance( oldBalance + transaction );
    164.       outputLine( cout, client ); // display the record
    165.  
    166.       // move file-position pointer to correct record in file
    167.       updateFile.seekp( ( accountNumber - 1 ) * sizeof( ClientData ) );
    168.  
    169.       // write updated record over old record in file
    170.       updateFile.write( reinterpret_cast< const char * >( &client ),
    171.          sizeof( ClientData ) );
    172.    } // end if
    173.    else // display error if account does not exist
    174.       cerr << "Account #" << accountNumber
    175.          << " has no information." << endl;
    176. } // end function updateRecord
    177.  
    178. // create and insert record
    179. void newRecord( fstream &insertInFile )
    180. {
    181.    // obtain number of account to create
    182.    int accountNumber = getAccount( "Enter new account number" );
    183.  
    184.    // move file-position pointer to correct record in file
    185.    insertInFile.seekg( ( accountNumber - 1 ) * sizeof( ClientData ) );
    186.  
    187.    // read record from file
    188.    ClientData client;
    189.    insertInFile.read( reinterpret_cast< char * >( &client ),
    190.       sizeof( ClientData ) );
    191.  
    192.    // create record, if record does not previously exist
    193.    if ( client.getAccountNumber() == 0 )
    194.    {
    195.       char lastName[ 15 ];
    196.       char firstName[ 10 ];
    197.       double balance;
    198.  
    199.       // user enters last name, first name and balance
    200.       cout << "Enter lastname, firstname, balance\n? ";
    201.       cin >> setw( 15 ) >> lastName;
    202.       cin >> setw( 10 ) >> firstName;
    203.       cin >> balance;
    204.  
    205.       // use values to populate account values
    206.       client.setLastName( lastName );
    207.       client.setFirstName( firstName );
    208.       client.setBalance( balance );
    209.       client.setAccountNumber( accountNumber );
    210.  
    211.       // move file-position pointer to correct record in file
    212.       insertInFile.seekp( ( accountNumber - 1 ) * sizeof( ClientData ) );
    213.  
    214.       // insert record in file                      
    215.       insertInFile.write( reinterpret_cast< const char * >( &client ),
    216.          sizeof( ClientData ) );                    
    217.    } // end if
    218.    else // display error if account already exists
    219.       cerr << "Account #" << accountNumber
    220.          << " already contains information." << endl;
    221. } // end function newRecord
    222.  
    223. // delete an existing record
    224. void deleteRecord( fstream &deleteFromFile )
    225. {
    226.    // obtain number of account to delete
    227.    int accountNumber = getAccount( "Enter account to delete" );
    228.  
    229.    // move file-position pointer to correct record in file
    230.    deleteFromFile.seekg( ( accountNumber - 1 ) * sizeof( ClientData ) );
    231.  
    232.    // read record from file
    233.    ClientData client;
    234.    deleteFromFile.read( reinterpret_cast< char * >( &client ),
    235.       sizeof( ClientData ) );
    236.  
    237.    // delete record, if record exists in file
    238.    if ( client.getAccountNumber() != 0 )
    239.    {
    240.       ClientData blankClient; // create blank record
    241.  
    242.       // move file-position pointer to correct record in file
    243.       deleteFromFile.seekp( ( accountNumber - 1 ) *
    244.          sizeof( ClientData ) );
    245.  
    246.       // replace existing record with blank record
    247.       deleteFromFile.write(
    248.          reinterpret_cast< const char * >( &blankClient ),
    249.          sizeof( ClientData ) );
    250.  
    251.       cout << "Account #" << accountNumber << " deleted.\n";
    252.    } // end if
    253.    else // display error if record does not exist
    254.       cerr << "Account #" << accountNumber << " is empty.\n";
    255. } // end deleteRecord
    256.  
    257. // display single record
    258. void outputLine( ostream &output, const ClientData &record )
    259. {
    260.    output << left << setw( 10 ) << record.getAccountNumber()
    261.       << setw( 16 ) << record.getLastName()
    262.       << setw( 11 ) << record.getFirstName()
    263.       << setw( 10 ) << setprecision( 2 ) << right << fixed
    264.       << showpoint << record.getBalance() << endl;
    265. } // end function outputLine
    266.  
    267. // obtain account-number value from user
    268. int getAccount( const char * const prompt )
    269. {
    270.    int accountNumber;
    271.  
    272.    // obtain account-number value
    273.    do
    274.    {
    275.       cout << prompt << " (1 - 100): ";
    276.       cin >> accountNumber;
    277.    } while ( accountNumber < 1 || accountNumber > 100 );
    278.  
    279.    return accountNumber;
    280. } // end function getAccount
    281.  
    282. /**************************************************************************
    283.  * (C) Copyright 1992-2005 by Deitel & Associates, Inc. and               *
    284.  * Pearson Education, Inc. All Rights Reserved.                           *
    285.  *                                                                        *
    286.  * DISCLAIMER: The authors and publisher of this book have used their     *
    287.  * best efforts in preparing the book. These efforts include the          *
    288.  * development, research, and testing of the theories and programs        *
    289.  * to determine their effectiveness. The authors and publisher make       *
    290.  * no warranty of any kind, expressed or implied, with regard to these    *
    291.  * programs or to the documentation contained in these books. The authors *
    292.  * and publisher shall not be liable in any event for incidental or       *
    293.  * consequential damages in connection with, or arising out of, the       *
    294.  * furnishing, performance, or use of these programs.                     *
    295.  **************************************************************************/

  10. #10
    Ngày gia nhập
    12 2006
    Nơi ở
    US
    Bài viết
    1,917

    - Thua, pó tay thật rồi, ghi, đọc tại bất kì vị trí nào cũng ok tuy nhiên ghi đè thì bắt buộc phải override nếu dùng std::string. Chẳng có cách nào nhận biết senti Chắc chỉ có cách dùng pure char[] của C thôi. Boost::file_system cũng chẳng thấy đề cập gì. Để đọc thêm cái filebuf nữa xem sao !

Các đề tài tương tự

  1. Xử lý transaction trong mô hình 3 lớp
    Gửi bởi blinkinkin trong diễn đàn Nhập môn lập trình C#, ASP.NET
    Trả lời: 10
    Bài viết cuối: 30-07-2015, 10:26 AM
  2. Hướng dẫn quản lý Transaction(giao tác) trong C#
    Gửi bởi sonhn trong diễn đàn Tutorials và Thủ thuật lập trình C#, ASP.NET
    Trả lời: 10
    Bài viết cuối: 30-07-2015, 10:24 AM
  3. Cách sử dụng transaction trong asp.net MVC 4?
    Gửi bởi Keither trong diễn đàn Thắc mắc lập trình ASP.NET
    Trả lời: 0
    Bài viết cuối: 18-07-2013, 03:08 PM
  4. Check point trong transaction là gì
    Gửi bởi langtu0401 trong diễn đàn Thắc mắc Microsoft SQL Server & Microsoft Access
    Trả lời: 0
    Bài viết cuối: 23-01-2013, 11:05 AM
  5. Distributed transaction của .Net trong CSDL phân tán ?
    Gửi bởi trần trân trong diễn đàn Thắc mắc lập trình C#
    Trả lời: 0
    Bài viết cuối: 17-11-2010, 01:38 AM

Quyền hạn của bạn

  • Bạn không thể gửi đề tài mới
  • Bạn không thể gửi bài trả lời
  • Bạn không thể gửi các đính kèm
  • Bạn không thể chỉnh sửa bài viết của bạn