Π§ΠΈΡ‚Π°ΠΉΡ‚Π΅ ΠΊΠ½ΠΈΠ³ΠΈ ΠΎΠ½Π»Π°ΠΉΠ½ Π½Π° Bookidrom.ru! БСсплатныС ΠΊΠ½ΠΈΠ³ΠΈ Π² ΠΎΠ΄Π½ΠΎΠΌ ΠΊΠ»ΠΈΠΊΠ΅

Π§ΠΈΡ‚Π°Ρ‚ΡŒ ΠΎΠ½Π»Π°ΠΉΠ½ Β«Π―Π·Ρ‹ΠΊ программирования C++. ΠŸΡΡ‚ΠΎΠ΅ ΠΈΠ·Π΄Π°Π½ΠΈΠ΅Β». Π‘Ρ‚Ρ€Π°Π½ΠΈΡ†Π° 258

Автор Π‘Ρ‚Π΅Π½Π»ΠΈ Π›ΠΈΠΏΠΏΠΌΠ°Π½

Π’ΠΏΠΎΠ»Π½Π΅ Π»ΠΎΠ³ΠΈΡ‡Π½ΠΎ, Ρ‡Ρ‚ΠΎ для класса istream, Π° Ρ‚Π°ΠΊΠΆΠ΅ ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ΄Π½Ρ‹Ρ… ΠΎΡ‚ Π½Π΅Π³ΠΎ классов ifstream ΠΈ istringstream (см. Ρ€Π°Π·Π΄Π΅Π» 8.1) ΠΌΠΎΠΆΠ½ΠΎ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ вСрсии g, Π° для классов ostream ΠΈ классов ofstream ΠΈ ostringstream, ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ΄Π½Ρ‹Ρ… ΠΎΡ‚ Π½Π΅Π³ΠΎ, ΠΌΠΎΠΆΠ½ΠΎ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ вСрсии p. ΠšΠ»Π°ΡΡΡ‹ iostream, fstream ΠΈ stringstream способны Ρ‡ΠΈΡ‚Π°Ρ‚ΡŒ ΠΈ Π·Π°ΠΏΠΈΡΡ‹Π²Π°Ρ‚ΡŒ Π΄Π°Π½Π½Ρ‹Π΅ Π² ΠΏΠΎΡ‚ΠΎΠΊ, поэтому для Π½ΠΈΡ… ΠΌΠΎΠΆΠ½ΠΎ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ ΠΎΠ±Π΅ вСрсии, g ΠΈ p.

БущСствуСт Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ΠΎΠ΄ΠΈΠ½ ΠΌΠ°Ρ€ΠΊΠ΅Ρ€

Π’ΠΎΡ‚ Ρ„Π°ΠΊΡ‚, Ρ‡Ρ‚ΠΎ Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠ° Ρ€Π°Π·Π»ΠΈΡ‡Π°Π΅Ρ‚ вСрсии Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΉ seek() ΠΈ tell() для чтСния ΠΈ записи, ΠΌΠΎΠΆΠ΅Ρ‚ ввСсти Π² Π·Π°Π±Π»ΡƒΠΆΠ΄Π΅Π½ΠΈΠ΅. Π₯отя Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠ° ΠΈ Ρ€Π°Π·Π»ΠΈΡ‡Π°Π΅Ρ‚ эти Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ, Π² Ρ„Π°ΠΉΠ»Π΅ сущСствуСт Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ΠΎΠ΄ΠΈΠ½ ΠΌΠ°Ρ€ΠΊΠ΅Ρ€, Ρ‚.Π΅. Π½Π΅Ρ‚ Ρ€Π°Π·Π½Ρ‹Ρ… ΠΌΠ°Ρ€ΠΊΠ΅Ρ€ΠΎΠ² для чтСния ΠΈ записи.

Когда Ρ€Π΅Ρ‡ΡŒ ΠΈΠ΄Π΅Ρ‚ ΠΎ ΠΏΠΎΡ‚ΠΎΠΊΠ΅ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Π²Π²ΠΎΠ΄Π° ΠΈΠ»ΠΈ Π²Ρ‹Π²ΠΎΠ΄Π°, Ρ€Π°Π·Π»ΠΈΡ‡ΠΈΠ΅ Π½Π΅ ΡΡ‚ΠΎΠ»ΡŒ ΠΎΡ‡Π΅Π²ΠΈΠ΄Π½ΠΎ. Π’ Ρ‚Π°ΠΊΠΈΡ… ΠΏΠΎΡ‚ΠΎΠΊΠ°Ρ… ΠΌΠΎΠΆΠ½ΠΎ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ вСрсии Ρ‚ΠΎΠ»ΡŒΠΊΠΎ g ΠΈΠ»ΠΈ p. Если ΠΏΠΎΠΏΡ‹Ρ‚Π°Ρ‚ΡŒΡΡ Π²Ρ‹Π·Π²Π°Ρ‚ΡŒ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ tellp() для ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π° класса ifstream, компилятор сообщит ΠΎΠ± ошибкС. Аналогично ΠΎΠ½ поступит ΠΏΡ€ΠΈ ΠΏΠΎΠΏΡ‹Ρ‚ΠΊΠ΅ Π²Ρ‹Π·Π²Π°Ρ‚ΡŒ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ seekg() для ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π° класса ostringstream.

Π’ΠΈΠΏΡ‹ fstream ΠΈ stringstream Π΄ΠΎΠΏΡƒΡΠΊΠ°ΡŽΡ‚ Ρ‡Ρ‚Π΅Π½ΠΈΠ΅ ΠΈ запись Π² Ρ‚ΠΎΡ‚ ΠΆΠ΅ ΠΏΠΎΡ‚ΠΎΠΊ. Π£ Π½ΠΈΡ… Π΅ΡΡ‚ΡŒ ΠΎΠ΄ΠΈΠ½ Π±ΡƒΡ„Π΅Ρ€ для хранСния ΠΏΠΎΠ΄Π»Π΅ΠΆΠ°Ρ‰ΠΈΡ… Ρ‡Ρ‚Π΅Π½ΠΈΡŽ ΠΈ записи Π΄Π°Π½Π½Ρ‹Ρ…, Π° Ρ‚Π°ΠΊΠΆΠ΅ ΠΎΠ΄ΠΈΠ½ ΠΌΠ°Ρ€ΠΊΠ΅Ρ€, ΠΎΠ±ΠΎΠ·Π½Π°Ρ‡Π°ΡŽΡ‰ΠΈΠΉ Ρ‚Π΅ΠΊΡƒΡ‰ΡƒΡŽ ΠΏΠΎΠ·ΠΈΡ†ΠΈΡŽ Π² Π±ΡƒΡ„Π΅Ρ€Π΅. Π‘ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅Ρ‡Π½Ρ‹Π΅ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ вСрсий g ΠΈ p ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡŽΡ‚ Ρ‚ΠΎΡ‚ ΠΆΠ΅ ΠΌΠ°Ρ€ΠΊΠ΅Ρ€ ΠΏΠΎΠ·ΠΈΡ†ΠΈΠΈ.

ΠŸΠΎΡΠΊΠΎΠ»ΡŒΠΊΡƒ сущСствуСт Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ΠΎΠ΄ΠΈΠ½ ΠΌΠ°Ρ€ΠΊΠ΅Ρ€, для пСрСустановки ΠΌΠ°Ρ€ΠΊΠ΅Ρ€Π° ΠΏΡ€ΠΈ ΠΊΠ°ΠΆΠ΄ΠΎΠΌ ΠΏΠ΅Ρ€Π΅ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠΈ ΠΌΠ΅ΠΆΠ΄Ρƒ Ρ‡Ρ‚Π΅Π½ΠΈΠ΅ΠΌ ΠΈ записью слСдуСт ΠΏΡ€ΠΈΠΌΠ΅Π½ΡΡ‚ΡŒ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ seek().

ΠŸΠ΅Ρ€Π΅ΠΌΠ΅Ρ‰Π΅Π½ΠΈΠ΅ ΠΌΠ°Ρ€ΠΊΠ΅Ρ€Π°

Π˜ΠΌΠ΅ΡŽΡ‚ΡΡ Π΄Π²Π΅ вСрсии Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ установки ΠΏΠΎΠ·ΠΈΡ†ΠΈΠΈ: ΠΎΠ΄Π½Π° обСспСчиваСт ΠΏΠ΅Ρ€Π΅Ρ…ΠΎΠ΄ ΠΊ ΡƒΠΊΠ°Π·Π°Π½Π½ΠΎΠΉ ΠΏΠΎΠ·ΠΈΡ†ΠΈΠΈ Π² Ρ„Π°ΠΉΠ»Π΅, Π° другая осущСствляСт смСщСниС ΠΎΡ‚ Ρ‚Π΅ΠΊΡƒΡ‰Π΅ΠΉ ΠΏΠΎΠ·ΠΈΡ†ΠΈΠΈ.

// установка ΠΌΠ°Ρ€ΠΊΠ΅Ρ€Π° Π² Π·Π°Π΄Π°Π½Π½ΡƒΡŽ ΠΏΠΎΠ·ΠΈΡ†ΠΈΡŽ

seekg(new_position); // ΡƒΡΡ‚Π°Π½ΠΎΠ²ΠΈΡ‚ΡŒ ΠΌΠ°Ρ€ΠΊΠ΅Ρ€ чтСния Π² ΠΏΠΎΠ·ΠΈΡ†ΠΈΡŽ pos_type

seekp(new_position); // ΡƒΡΡ‚Π°Π½ΠΎΠ²ΠΈΡ‚ΡŒ ΠΌΠ°Ρ€ΠΊΠ΅Ρ€ записи Π² ΠΏΠΎΠ·ΠΈΡ†ΠΈΡŽ pos_type


// смСщСниС ΠΏΠΎΠ·ΠΈΡ†ΠΈΠΈ Π½Π° ΡƒΠΊΠ°Π·Π°Π½Π½ΡƒΡŽ Π΄ΠΈΡΡ‚Π°Π½Ρ†ΠΈΡŽ ΠΎΡ‚ Ρ‚Π΅ΠΊΡƒΡ‰Π΅ΠΉ

seekg(offset, from); // ΡƒΡΡ‚Π°Π½ΠΎΠ²ΠΈΡ‚ΡŒ Π΄ΠΈΡΡ‚Π°Π½Ρ†ΠΈΡŽ смСщСния ΠΌΠ°Ρ€ΠΊΠ΅Ρ€Π° чтСния

seekp(offset, from); // ΠΎΡ‚ from; offset ΠΈΠΌΠ΅Π΅Ρ‚ Ρ‚ΠΈΠΏ off_type

Π’ΠΎΠ·ΠΌΠΎΠΆΠ½Ρ‹Π΅ значСния ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Π° from пСрСчислСны Π² Ρ‚Π°Π±Π». 17.21.

АргумСнты new_position ΠΈ offset этих Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΉ ΠΈΠΌΠ΅ΡŽΡ‚ машинно-зависимыС Ρ‚ΠΈΠΏΡ‹ pos_type ΠΈ off_type соотвСтствСнно. Они ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½Ρ‹ Π² классах istream ΠΈ ostream. Π’ΠΈΠΏ pos_type прСдставляСт ΠΏΠΎΠ·ΠΈΡ†ΠΈΡŽ Ρ„Π°ΠΉΠ»Π°, Π° Ρ‚ΠΈΠΏ off_type β€” смСщСниС ΠΎΡ‚ этой ΠΏΠΎΠ·ΠΈΡ†ΠΈΠΈ. Π—Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ Ρ‚ΠΈΠΏΠ° off_type ΠΌΠΎΠΆΠ΅Ρ‚ Π±Ρ‹Ρ‚ΡŒ ΠΏΠΎΠ»ΠΎΠΆΠΈΡ‚Π΅Π»ΡŒΠ½Ρ‹ΠΌ ΠΈΠ»ΠΈ ΠΎΡ‚Ρ€ΠΈΡ†Π°Ρ‚Π΅Π»ΡŒΠ½Ρ‹ΠΌ, Ρ‡Ρ‚ΠΎ соотвСтствуСт ΡΠΌΠ΅Ρ‰Π΅Π½ΠΈΡŽ Π²ΠΏΠ΅Ρ€Π΅Π΄ ΠΈΠ»ΠΈ Π½Π°Π·Π°Π΄.

Доступ ΠΊ ΠΌΠ°Ρ€ΠΊΠ΅Ρ€Ρƒ

Π€ΡƒΠ½ΠΊΡ†ΠΈΠΈ tellg() ΠΈ tellp() Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°ΡŽΡ‚ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ Ρ‚ΠΈΠΏΠ° pos_type, ΠΎΠ±ΠΎΠ·Π½Π°Ρ‡Π°ΡŽΡ‰Π΅Π΅ Ρ‚Π΅ΠΊΡƒΡ‰ΡƒΡŽ ΠΏΠΎΠ·ΠΈΡ†ΠΈΡŽ Π² ΠΏΠΎΡ‚ΠΎΠΊΠ΅. Π­Ρ‚ΠΈ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ ΠΎΠ±Ρ‹Ρ‡Π½ΠΎ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡŽΡ‚ΡΡ для Ρ‚ΠΎΠ³ΠΎ, Ρ‡Ρ‚ΠΎΠ±Ρ‹ Π·Π°ΠΏΠΎΠΌΠ½ΠΈΡ‚ΡŒ ΠΏΠΎΠ·ΠΈΡ†ΠΈΡŽ ΠΈ впослСдствии Π²Π΅Ρ€Π½ΡƒΡ‚ΡŒΡΡ ΠΊ Π½Π΅ΠΉ:

// Π·Π°ΠΏΠΎΠΌΠ½ΠΈΡ‚ΡŒ Ρ‚Π΅ΠΊΡƒΡ‰ΡƒΡŽ ΠΏΠΎΠ·ΠΈΡ†ΠΈΡŽ записи Π² ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½ΡƒΡŽ mark

ostringstream writeStr; // ΠΏΠΎΡ‚ΠΎΠΊ Π²Ρ‹Π²ΠΎΠ΄Π° Π² строку

ostringstream::pos_type mark = writeStr.tellp();

// ...

if (cancelEntry)

 // Π²ΠΎΠ·Π²Ρ€Π°Ρ‚ ΠΊ ΠΎΡ‚ΠΌΠ΅Ρ‡Π΅Π½Π½ΠΎΠΉ ΠΏΠΎΠ·ΠΈΡ†ΠΈΠΈ

 writeStr.seekp(mark);

Π§Ρ‚Π΅Π½ΠΈΠ΅ ΠΈ запись Π² Ρ‚ΠΎΡ‚ ΠΆΠ΅ Ρ„Π°ΠΉΠ»

Рассмотрим ΠΏΡ€ΠΈΠΌΠ΅Ρ€ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹, которая Ρ‡ΠΈΡ‚Π°Π΅Ρ‚ Ρ„Π°ΠΉΠ» ΠΈ записываСт Π² Π΅Π³ΠΎ ΠΊΠΎΠ½Π΅Ρ† Π½ΠΎΠ²ΡƒΡŽ строку, ΡΠΎΠ΄Π΅Ρ€ΠΆΠ°Ρ‰ΡƒΡŽ ΠΎΡ‚Π½ΠΎΡΠΈΡ‚Π΅Π»ΡŒΠ½ΡƒΡŽ ΠΏΠΎΠ·ΠΈΡ†ΠΈΡŽ Π½Π°Ρ‡Π°Π»Π° ΠΊΠ°ΠΆΠ΄ΠΎΠΉ строки. ΠŸΡ€Π΅Π΄ΠΏΠΎΠ»ΠΎΠΆΠΈΠΌ, Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, Ρ‡Ρ‚ΠΎ Ρ€Π°Π±ΠΎΡ‚Π°Ρ‚ΡŒ придСтся со ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠΌ Ρ„Π°ΠΉΠ»ΠΎΠΌ.

Abcd

efg

hi

j

ΠœΠΎΠ΄ΠΈΡ„ΠΈΡ†ΠΈΡ€ΠΎΠ²Π°Π½Π½Ρ‹ΠΉ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠΎΠΉ Ρ„Π°ΠΉΠ» Π΄ΠΎΠ»ΠΆΠ΅Π½ Π²Ρ‹Π³Π»ΡΠ΄Π΅Ρ‚ΡŒ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠΌ ΠΎΠ±Ρ€Π°Π·ΠΎΠΌ.

Abcd

efg

hi

j

5 9 12 14

ΠžΠ±Ρ€Π°Ρ‚ΠΈΡ‚Π΅ Π²Π½ΠΈΠΌΠ°Π½ΠΈΠ΅: ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ° Π½Π΅ записываСт смСщСниС для ΠΏΠ΅Ρ€Π²ΠΎΠΉ строки, ΠΎΠ½Π° всСгда начинаСтся с ΠΏΠΎΠ·ΠΈΡ†ΠΈΠΈ 0. ΠžΠ±Ρ€Π°Ρ‚ΠΈΡ‚Π΅ Ρ‚Π°ΠΊΠΆΠ΅ Π²Π½ΠΈΠΌΠ°Π½ΠΈΠ΅ Π½Π° Ρ‚ΠΎ, Ρ‡Ρ‚ΠΎ смСщСния Π΄ΠΎΠ»ΠΆΠ½Ρ‹ Ρ‚Π°ΠΊΠΆΠ΅ ΡƒΡ‡ΠΈΡ‚Ρ‹Π²Π°Ρ‚ΡŒ Π½Π΅Π²ΠΈΠ΄ΠΈΠΌΡ‹ΠΉ символ Π½ΠΎΠ²ΠΎΠΉ строки, Π·Π°Π²Π΅Ρ€ΡˆΠ°ΡŽΡ‰ΠΈΠΉ ΠΊΠ°ΠΆΠ΄ΡƒΡŽ строку. И Π½Π°ΠΊΠΎΠ½Π΅Ρ†, послСднСС число Π² Π²Ρ‹Π²ΠΎΠ΄Π΅ β€” смСщСниС для строки, с ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΉ начинаСтся Π²Ρ‹Π²ΠΎΠ΄. ΠŸΡ€ΠΈ Π²ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠΈ этого смСщСния Π² Π²Ρ‹Π²ΠΎΠ΄ ΠΌΠΎΠΆΠ½ΠΎ ΠΎΡ‚Π»ΠΈΡ‡ΠΈΡ‚ΡŒ свой Π²Ρ‹Π²ΠΎΠ΄ ΠΎΡ‚ ΠΏΠ΅Ρ€Π²ΠΎΠ½Π°Ρ‡Π°Π»ΡŒΠ½ΠΎΠ³ΠΎ содСрТимого Ρ„Π°ΠΉΠ»Π°. МоТно ΠΏΡ€ΠΎΡ‡ΠΈΡ‚Π°Ρ‚ΡŒ послСднСС число Π² ΠΏΠΎΠ»ΡƒΡ‡Π΅Π½Π½ΠΎΠΌ Ρ„Π°ΠΉΠ»Π΅ ΠΈ ΡƒΡΡ‚Π°Π½ΠΎΠ²ΠΈΡ‚ΡŒ смСщСниС Ρ‚Π°ΠΊ, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΏΠΎΠ»ΡƒΡ‡ΠΈΡ‚ΡŒ ΠΏΠΎΠ·ΠΈΡ†ΠΈΡŽ Π½Π°Ρ‡Π°Π»Π° Π²Ρ‹Π²ΠΎΠ΄Π°.

Наша ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ° Π±ΡƒΠ΄Π΅Ρ‚ Ρ‡ΠΈΡ‚Π°Ρ‚ΡŒ Ρ„Π°ΠΉΠ» построчно. Для ΠΊΠ°ΠΆΠ΄ΠΎΠΉ строки Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ счСтчика Π±ΡƒΠ΄Π΅Ρ‚ ΡƒΠ²Π΅Π»ΠΈΡ‡ΠΈΠ²Π°Ρ‚ΡŒΡΡ Π½Π° Ρ€Π°Π·ΠΌΠ΅Ρ€ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Ρ‡Ρ‚ΠΎ ΠΏΡ€ΠΎΡ‡ΠΈΡ‚Π°Π½Π½ΠΎΠΉ строки. Π­Ρ‚ΠΎΡ‚ счСтчик содСрТит смСщСниС, с ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ³ΠΎ начинаСтся ΡΠ»Π΅Π΄ΡƒΡŽΡ‰Π°Ρ строка:

int main() {

 // ΠΎΡ‚ΠΊΡ€Ρ‹Ρ‚ΡŒ Ρ„Π°ΠΉΠ» для Π²Π²ΠΎΠ΄Π° ΠΈ Π²Ρ‹Π²ΠΎΠ΄Π°, Π° Π·Π°Ρ‚Π΅ΠΌ ΠΏΠ΅Ρ€Π΅ΠΉΡ‚ΠΈ Π² Π΅Π³ΠΎ ΠΊΠΎΠ½Π΅Ρ†

 // Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚Ρ‹ Ρ€Π΅ΠΆΠΈΠΌΠ° Ρ„Π°ΠΉΠ»Π° ΠΏΡ€ΠΈΠ²Π΅Π΄Π΅Π½Ρ‹ Π² Ρ‚Π°Π±Π». 8.4

 fstream inOut("copyOut",

  fstream::ate | fstream::in | fstream::out);

 if (!inOut) {

  cerr << "Unable to open file!" << endl;

  return EXIT_FAILURE; // EXIT_FAILURE см. p. 6.3.2

 }

 // inOut ΠΎΡ‚ΠΊΡ€Ρ‹Ρ‚ Π² Ρ€Π΅ΠΆΠΈΠΌΠ΅ ate, поэтому исходной ΠΏΠΎΠ·ΠΈΡ†ΠΈΠ΅ΠΉ Ρ„Π°ΠΉΠ»Π° Π±ΡƒΠ΄Π΅Ρ‚

 // Π΅Π³ΠΎ ΠΊΠΎΠ½Π΅Ρ†

 auto end_mark = inOut.tellg(); // Π·Π°ΠΏΠΎΠΌΠ½ΠΈΡ‚ΡŒ ΠΏΠΎΠ·ΠΈΡ†ΠΈΡŽ ΠΏΠ΅Ρ€Π²ΠΎΠ½Π°Ρ‡Π°Π»ΡŒΠ½ΠΎΠ³ΠΎ

                                // ΠΊΠΎΠ½Ρ†Π° Ρ„Π°ΠΉΠ»Π°

 inOut.seekg(0, fstream::beg);  // ΠΏΠ΅Ρ€Π΅ΠΉΡ‚ΠΈ ΠΊ Π½Π°Ρ‡Π°Π»Ρƒ Ρ„Π°ΠΉΠ»Π°

 size_t cnt = 0;                // счСтчик количСства Π±Π°ΠΉΡ‚ΠΎΠ²

 string line;                   // содСрТит ΠΊΠ°ΠΆΠ΄ΡƒΡŽ строку Π²Π²ΠΎΠ΄Π°

 // ΠΏΠΎΠΊΠ° Π½Π΅Ρ‚ ошибки ΠΈ исходныС Π΄Π°Π½Π½Ρ‹Π΅ Ρ‡ΠΈΡ‚Π°ΡŽΡ‚ΡΡ

 while (inOut && inOut.tellg() != end_mark

        && getline(inOut, line)) { // ΠΈ ΠΌΠΎΠΆΠ½ΠΎ ΠΏΠΎΠ»ΡƒΡ‡ΠΈΡ‚ΡŒ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΡƒΡŽ строку

  cnt += line.size() + 1;          // Π΄ΠΎΠ±Π°Π²ΠΈΡ‚ΡŒ 1 для Π½ΠΎΠ²ΠΎΠΉ строки

  auto mark = inOut.tellg();       // Π·Π°ΠΏΠΎΠΌΠ½ΠΈΡ‚ΡŒ ΠΏΠΎΠ·ΠΈΡ†ΠΈΡŽ чтСния

  inOut.seekp(0, fstream::end);    // ΡƒΡΡ‚Π°Π½ΠΎΠ²ΠΈΡ‚ΡŒ ΠΌΠ°Ρ€ΠΊΠ΅Ρ€ записи Π² ΠΊΠΎΠ½Π΅Ρ†

  inOut << cnt;                    // Π·Π°ΠΏΠΈΡΠ°Ρ‚ΡŒ ΠΎΠ±Ρ‰ΡƒΡŽ Π΄Π»ΠΈΠ½Ρƒ

  // вывСсти Ρ€Π°Π·Π΄Π΅Π»ΠΈΡ‚Π΅Π»ΡŒ, Ссли это Π½Π΅ послСдняя строка

  if (mark != end_mark) inOut << " ";

  inOut.seekg(mark); // Π²ΠΎΡΡΡ‚Π°Π½ΠΎΠ²ΠΈΡ‚ΡŒ ΠΏΠΎΠ·ΠΈΡ†ΠΈΡŽ чтСния

 }

 inOut.seekp(0, fstream::end); // ΠΏΠ΅Ρ€Π΅ΠΉΡ‚ΠΈ ΠΊ ΠΊΠΎΠ½Ρ†Ρƒ

 inOut << "\n"; // вывСсти символ Π½ΠΎΠ²ΠΎΠΉ строки Π² ΠΊΠΎΠ½Ρ†Π΅ Ρ„Π°ΠΉΠ»Π°

 return 0;

}

Π­Ρ‚Π° ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ° ΠΎΡ‚ΠΊΡ€Ρ‹Π²Π°Π΅Ρ‚ ΠΏΠΎΡ‚ΠΎΠΊ fstream Π² Ρ€Π΅ΠΆΠΈΠΌΠ°Ρ… in, out ΠΈ ate (см. Ρ‚Π°Π±Π». 8.4). ΠŸΠ΅Ρ€Π²Ρ‹Π΅ Π΄Π²Π° Ρ€Π΅ΠΆΠΈΠΌΠ° ΠΎΠ·Π½Π°Ρ‡Π°ΡŽΡ‚, Ρ‡Ρ‚ΠΎ прСдполагаСтся Ρ‡Ρ‚Π΅Π½ΠΈΠ΅ ΠΈ запись Π² Ρ‚ΠΎΡ‚ ΠΆΠ΅ Ρ„Π°ΠΉΠ». Π Π΅ΠΆΠΈΠΌ ate ΠΎΠ·Π½Π°Ρ‡Π°Π΅Ρ‚, Ρ‡Ρ‚ΠΎ Π½Π°Ρ‡Π°Π»ΡŒΠ½ΠΎΠΉ ΠΏΠΎΠ·ΠΈΡ†ΠΈΠ΅ΠΉ ΠΎΡ‚ΠΊΡ€Ρ‹Ρ‚ΠΎΠ³ΠΎ Ρ„Π°ΠΉΠ»Π° Π±ΡƒΠ΄Π΅Ρ‚ Π΅Π³ΠΎ ΠΊΠΎΠ½Π΅Ρ†. Как ΠΎΠ±Ρ‹Ρ‡Π½ΠΎ, Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎ ΡƒΠ΄ΠΎΡΡ‚ΠΎΠ²Π΅Ρ€ΠΈΡ‚ΡŒΡΡ, Ρ‡Ρ‚ΠΎ Ρ„Π°ΠΉΠ» ΠΎΡ‚ΠΊΡ€Ρ‹Ρ‚ ΠΊΠΎΡ€Ρ€Π΅ΠΊΡ‚Π½ΠΎ, Ссли это Π½Π΅ Ρ‚Π°ΠΊ, слСдуСт Π²Ρ‹ΠΉΡ‚ΠΈ ΠΈΠ· ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹ (см. Ρ€Π°Π·Π΄Π΅Π» 6.3.2).

ΠŸΠΎΡΠΊΠΎΠ»ΡŒΠΊΡƒ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ° ΠΏΠΈΡˆΠ΅Ρ‚ Π² свой исходный Ρ„Π°ΠΉΠ», нСльзя ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ ΠΊΠΎΠ½Π΅Ρ† Ρ„Π°ΠΉΠ»Π° ΠΊΠ°ΠΊ ΠΏΡ€ΠΈΠ·Π½Π°ΠΊ прСкращСния чтСния. Π¦ΠΈΠΊΠ» Π΄ΠΎΠ»ΠΆΠ΅Π½ Π·Π°ΠΊΠΎΠ½Ρ‡ΠΈΡ‚ΡŒΡΡ ΠΏΠΎ достиТСнии ΠΊΠΎΠ½Ρ†Π° ΠΏΠ΅Ρ€Π²ΠΎΠ½Π°Ρ‡Π°Π»ΡŒΠ½ΠΎΠ³ΠΎ Π²Π²ΠΎΠ΄Π°. Π’ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚Π΅ сначала слСдуСт Π·Π°ΠΏΠΎΠΌΠ½ΠΈΡ‚ΡŒ ΠΏΠ΅Ρ€Π²ΠΎΠ½Π°Ρ‡Π°Π»ΡŒΠ½ΡƒΡŽ ΠΏΠΎΠ·ΠΈΡ†ΠΈΡŽ ΠΊΠΎΠ½Ρ†Π° Ρ„Π°ΠΉΠ»Π°. Π’Π°ΠΊ ΠΊΠ°ΠΊ Ρ„Π°ΠΉΠ» ΠΎΡ‚ΠΊΡ€Ρ‹Ρ‚ Π² Ρ€Π΅ΠΆΠΈΠΌΠ΅ ate, ΠΏΠΎΡ‚ΠΎΠΊ inOut ΡƒΠΆΠ΅ установлСн Π² ΠΊΠΎΠ½Π΅Ρ†. Π‘ΠΎΡ…Ρ€Π°Π½ΠΈΠΌ Ρ‚Π΅ΠΊΡƒΡ‰ΡƒΡŽ (Ρ‚.Π΅. ΠΏΠ΅Ρ€Π²ΠΎΠ½Π°Ρ‡Π°Π»ΡŒΠ½ΡƒΡŽ) ΠΏΠΎΠ·ΠΈΡ†ΠΈΡŽ ΠΊΠΎΠ½Ρ†Π° Ρ„Π°ΠΉΠ»Π° Π² ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎΠΉ end_mark. Π—Π°ΠΏΠΎΠΌΠ½ΠΈΠ² ΠΊΠΎΠ½Π΅Ρ‡Π½ΡƒΡŽ ΠΏΠΎΠ·ΠΈΡ†ΠΈΡŽ, ΠΌΠ°Ρ€ΠΊΠ΅Ρ€ чтСния слСдуСт ΡƒΡΡ‚Π°Π½ΠΎΠ²ΠΈΡ‚ΡŒ Π² Π½Π°Ρ‡Π°Π»ΠΎ Ρ„Π°ΠΉΠ»Π°, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΌΠΎΠΆΠ½ΠΎ Π±Ρ‹Π»ΠΎ ΠΏΡ€ΠΈΡΡ‚ΡƒΠΏΠΈΡ‚ΡŒ ΠΊ Ρ‡Ρ‚Π΅Π½ΠΈΡŽ Π΄Π°Π½Π½Ρ‹Ρ….

Π¦ΠΈΠΊΠ» while ΠΈΠΌΠ΅Π΅Ρ‚ Ρ‚Ρ€ΠΈ условия Π²Ρ‹Ρ…ΠΎΠ΄Π°: сначала провСряСтся Π΄ΠΎΠΏΡƒΡΡ‚ΠΈΠΌΠΎΡΡ‚ΡŒ ΠΏΠΎΡ‚ΠΎΠΊΠ°; Ссли это Ρ‚Π°ΠΊ, Ρ‚ΠΎ провСряСтся, Π½Π΅ достигнут Π»ΠΈ ΠΊΠΎΠ½Π΅Ρ† исходных Π΄Π°Π½Π½Ρ‹Ρ…. Для этого тСкущая позиция чтСния, возвращаСмая Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠ΅ΠΉ tellg(), сравниваСтся с ΠΏΠΎΠ·ΠΈΡ†ΠΈΠ΅ΠΉ, Π·Π°Ρ€Π°Π½Π΅Π΅ сохранСнной Π² ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎΠΉ end_mark. И Π½Π°ΠΊΠΎΠ½Π΅Ρ†, Ссли ΠΎΠ±Π΅ ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΠΈ ΠΏΡ€ΠΎΠΉΠ΄Π΅Π½Ρ‹ ΡƒΡΠΏΠ΅ΡˆΠ½ΠΎ, происходит Π²Ρ‹Π·ΠΎΠ² Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ getline(), которая Ρ‡ΠΈΡ‚Π°Π΅Ρ‚ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΡƒΡŽ строку ΠΈΠ· Ρ„Π°ΠΉΠ»Π°. Если Π²Ρ‹Π·ΠΎΠ² Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ getline() ΡƒΡΠΏΠ΅ΡˆΠ΅Π½, выполняСтся Ρ‚Π΅Π»ΠΎ Ρ†ΠΈΠΊΠ»Π°.

Π’Π΅Π»ΠΎ Ρ†ΠΈΠΊΠ»Π° начинаСтся с запоминания Ρ‚Π΅ΠΊΡƒΡ‰Π΅ΠΉ ΠΏΠΎΠ·ΠΈΡ†ΠΈΠΈ Π² ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎΠΉ mark. Она сохраняСтся для возвращСния послС записи ΡΠ»Π΅Π΄ΡƒΡŽΡ‰Π΅Π³ΠΎ ΠΎΡ‚Π½ΠΎΡΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎΠ³ΠΎ смСщСния. Π’Ρ‹Π·ΠΎΠ² Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ seekp() ΠΏΠ΅Ρ€Π΅Π²ΠΎΠ΄ΠΈΡ‚ ΠΌΠ°Ρ€ΠΊΠ΅Ρ€ записи Π² ΠΊΠΎΠ½Π΅Ρ† Ρ„Π°ΠΉΠ»Π°. Выводится Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ счСтчика, Π° Π·Π°Ρ‚Π΅ΠΌ функция seekg() возвращаСтся ΠΊ ΠΏΠΎΠ·ΠΈΡ†ΠΈΠΈ, сохранСнной Π² ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎΠΉ mark. Восстановив ΠΏΠΎΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ ΠΌΠ°Ρ€ΠΊΠ΅Ρ€Π°, ΠΌΠΎΠΆΠ½ΠΎ снова ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΈΡ‚ΡŒ условиС Π²Ρ‹Ρ…ΠΎΠ΄Π° ΠΈΠ· Ρ†ΠΈΠΊΠ»Π° while.

КаТдая итСрация Ρ†ΠΈΠΊΠ»Π° Π²Ρ‹Π²ΠΎΠ΄ΠΈΡ‚ смСщСниС ΡΠ»Π΅Π΄ΡƒΡŽΡ‰Π΅ΠΉ строки. ΠŸΠΎΡΡ‚ΠΎΠΌΡƒ послСдняя итСрация Ρ†ΠΈΠΊΠ»Π° заботится ΠΎ записи смСщСния послСднСй строки. Однако Π² ΠΊΠΎΠ½Π΅Ρ† Ρ„Π°ΠΉΠ»Π° слСдуСт Π΅Ρ‰Π΅ Π·Π°ΠΏΠΈΡΠ°Ρ‚ΡŒ символ Π½ΠΎΠ²ΠΎΠΉ строки. Как ΠΈ Π² Π΄Ρ€ΡƒΠ³ΠΈΡ… случаях записи, для позиционирования Π² ΠΊΠΎΠ½Π΅Ρ† Ρ„Π°ΠΉΠ»Π° ΠΏΠ΅Ρ€Π΅Π΄ Π²Ρ‹Π²ΠΎΠ΄ΠΎΠΌ Π½ΠΎΠ²ΠΎΠΉ строки происходит Π²Ρ‹Π·ΠΎΠ² Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ seekp().

УпраТнСния Ρ€Π°Π·Π΄Π΅Π»Π° 17.5.3

Π£ΠΏΡ€Π°ΠΆΠ½Π΅Π½ΠΈΠ΅ 17.39. ΠΠ°ΠΏΠΈΡˆΠΈΡ‚Π΅ ΡΠΎΠ±ΡΡ‚Π²Π΅Π½Π½ΡƒΡŽ Π²Π΅Ρ€ΡΠΈΡŽ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹, прСдставлСнной Π² этом Ρ€Π°Π·Π΄Π΅Π»Π΅.

РСзюмС

Π’ этой Π³Π»Π°Π²Π΅ Ρ€Π°ΡΡΠΌΠ°Ρ‚Ρ€ΠΈΠ²Π°Π»ΠΈΡΡŒ Π΄ΠΎΠΏΠΎΠ»Π½ΠΈΡ‚Π΅Π»ΡŒΠ½Ρ‹Π΅ ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ Π²Π²ΠΎΠ΄Π°-Π²Ρ‹Π²ΠΎΠ΄Π° ΠΈ Ρ‡Π΅Ρ‚Ρ‹Ρ€Π΅ Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅Ρ‡Π½Ρ‹Ρ… Ρ‚ΠΈΠΏΠ°: ΠΊΠΎΡ€Ρ‚Π΅ΠΆ, Π½Π°Π±ΠΎΡ€ Π±ΠΈΡ‚ΠΎΠ², рСгулярныС выраТСния ΠΈ случайныС числа.