Читаем Thinking In C++. Volume 2: Practical Programming полностью

The rdbuf( ) function returns a pointer, so it must be dereferenced to satisfy the function’s need to see an object. Stream buffers are not meant to be copied (they have no copy constructor), so we define sb as a reference to cout’s stream buffer. We need the calls to fail( ) and clear( ) in case the input file has a blank line (this one does). When this particular overloaded version of get( ) sees two newlines in a row (evidence of a blank line), it sets the input stream’s fail bit, so we must call clear( ) to reset it so that the stream can continue to be read. The second call to get( ) extracts and echoes each newline delimiter. (Remember, the get( ) function doesn’t extract its delimiter like getline( ) does.).

You probably won’t need to use a technique like this often, but it’s nice to know it exists.[43]

<p>Seeking in iostreams</p>

Each type of iostream has a concept of where its "next" character will come from (if it’s an istream) or go (if it’s an ostream). In some situations, you might want to move this stream position. You can do so using two models: one uses an absolute location in the stream called the streampos; the second works like the Standard C library functions fseek( ) for a file and moves a given number of bytes from the beginning, end, or current position in the file.

The streampos approach requires that you first call a "tell" function: tellp( ) for an ostream or tellg( ) for an istream. (The "p" refers to the "put pointer," and the "g" refers to the "get pointer.") This function returns a streampos you can later use in calls to seekp( ) for an ostream or seekg( ) for an istream, when you want to return to that position in the stream.

The second approach is a relative seek and uses overloaded versions of seekp( ) and seekg( ). The first argument is the number of characters to move: it can be positive or negative. The second argument is the seek direction:.

ios::begFrom beginning of stream
ios::curCurrent position in stream
ios::endFrom end of stream

Here’s an example that shows the movement through a file, but remember, you’re not limited to seeking within files, as you are with C and cstdio. With C++, you can seek in any type of iostream (although the standard stream objects, such as cin and cout, explicitly disallow it):.

//: C04:Seeking.cpp

// Seeking in iostreams

#include

#include

#include

#include

#include "../require.h"

using namespace std;

int main() {

  const int STR_NUM = 5, STR_LEN = 30;

  char origData[STR_NUM][STR_LEN] = {

    "Hickory dickory dus. . .",

    "Are you tired of C++?",

    "Well, if you have,",

    "That's just too bad,",

    "There's plenty more for us!"

  };

  char readData[STR_NUM][STR_LEN] = { 0 };

  ofstream out("Poem.bin", ios::out | ios::binary);

  assure(out, "Poem.bin");

  for(size_t i = 0; i < STR_NUM; i++)

    out.write(origData[i], STR_LEN);

  out.close();

  ifstream in("Poem.bin", ios::in | ios::binary);

  assure(in, "Poem.bin");

  in.read(readData[0], STR_LEN);

  assert(strcmp(readData[0], "Hickory dickory dus. . .")

    == 0);

  // Seek -STR_LEN bytes from the end of file

  in.seekg(-STR_LEN, ios::end);

  in.read(readData[1], STR_LEN);

  assert(strcmp(readData[1], "There's plenty more for us!")

    == 0);

  // Absolute seek (like using operator[] with a file)

  in.seekg(3 * STR_LEN);

  in.read(readData[2], STR_LEN);

  assert(strcmp(readData[2], "That's just too bad,") == 0);

  // Seek backwards from current position

  in.seekg(-STR_LEN * 2, ios::cur);

  in.read(readData[3], STR_LEN);

  assert(strcmp(readData[3], "Well, if you have,") == 0);

  // Seek from the begining of the file

  in.seekg(1 * STR_LEN, ios::beg);

  in.read(readData[4], STR_LEN);

  assert(strcmp(readData[4], "Are you tired of C++?")

    == 0);

} ///:~

This program writes a (very clever?) poem to a file using a binary output stream. Since we reopen it as an ifstream, we use seekg( ) to position the "get pointer." As you can see, you can seek from the beginning or end of the file or from the current file position. Obviously, you must provide a positive number to move from the beginning of the file and a negative number to move back from the end.

Now that you know about the streambuf and how to seek, you can understand an alternative method (besides using an fstream object) for creating a stream object that will both read and write a file. The following code first creates an ifstream with flags that say it’s both an input and an output file. You can’t write to an ifstream, of course, so you need to create an ostream with the underlying stream buffer:.

ifstream in("filename", ios::in | ios::out);

ostream out(in.rdbuf());

You might wonder what happens when you write to one of these objects. Here’s an example:.

//: C04:Iofile.cpp

// Reading & writing one file

#include

#include

#include "../require.h"

using namespace std;

Перейти на страницу:

Похожие книги

1С: Бухгалтерия 8 с нуля
1С: Бухгалтерия 8 с нуля

Книга содержит полное описание приемов и методов работы с программой 1С:Бухгалтерия 8. Рассматривается автоматизация всех основных участков бухгалтерии: учет наличных и безналичных денежных средств, основных средств и НМА, прихода и расхода товарно-материальных ценностей, зарплаты, производства. Описано, как вводить исходные данные, заполнять справочники и каталоги, работать с первичными документами, проводить их по учету, формировать разнообразные отчеты, выводить данные на печать, настраивать программу и использовать ее сервисные функции. Каждый урок содержит подробное описание рассматриваемой темы с детальным разбором и иллюстрированием всех этапов.Для широкого круга пользователей.

Алексей Анатольевич Гладкий

Программирование, программы, базы данных / Программное обеспечение / Бухучет и аудит / Финансы и бизнес / Книги по IT / Словари и Энциклопедии
1С: Управление торговлей 8.2
1С: Управление торговлей 8.2

Современные торговые предприятия предлагают своим клиентам широчайший ассортимент товаров, который исчисляется тысячами и десятками тысяч наименований. Причем многие позиции могут реализовываться на разных условиях: предоплата, отсрочка платежи, скидка, наценка, объем партии, и т.д. Клиенты зачастую делятся на категории – VIP-клиент, обычный клиент, постоянный клиент, мелкооптовый клиент, и т.д. Товарные позиции могут комплектоваться и разукомплектовываться, многие товары подлежат обязательной сертификации и гигиеническим исследованиям, некондиционные позиции необходимо списывать, на складах периодически должна проводиться инвентаризация, каждая компания должна иметь свою маркетинговую политику и т.д., вообщем – современное торговое предприятие представляет живой организм, находящийся в постоянном движении.Очевидно, что вся эта кипучая деятельность требует автоматизации. Для решения этой задачи существуют специальные программные средства, и в этой книге мы познакомим вам с самым популярным продуктом, предназначенным для автоматизации деятельности торгового предприятия – «1С Управление торговлей», которое реализовано на новейшей технологической платформе версии 1С 8.2.

Алексей Анатольевич Гладкий

Финансы / Программирование, программы, базы данных