Потоковый ввод-вывод в файлы

Язык C++ / Потоковый ввод-вывод в файлы

 

Работа с файлами с использованием конструкций языка Си была рассмотрена здесь.

Для программиста открытый файл представляется как последовательность считываемых или записываемых данных. При открытии файла с ним связывается поток ввода-вывода. Выводимая информация записывается в поток, вводимая информация считывается из потока.

Для работы с файлами необходимо подключить заголовочный файл <fstream>. В нем определены несколько классов и подключены заголовочные файлы

  • <ifstream> — файловый ввод ;
  • <ofstream> — файловый вывод.

Файловый ввод-вывод аналогичен стандартному вводу-выводу, единственное отличие – это то, что ввод-вывод выполнятся не на экран, а в файл.

Если ввод-вывод на стандартные устройства выполняется с помощью объектов cin и cout, то для организации файлового ввода-вывода достаточно создать собственные объекты, которые можно использовать аналогично этим операторам.

При работе с файлом можно выделить следующие этапы:

  • создать объект класса fstream (возможно, ofstream или ifstream);
  • связать объект класса fstream с файлом, который будет использоваться для операций ввода-вывода;
  • осуществить операции ввода-вывода в файл;
  • закрыть файл.
1
2
3
4
5
6
7
8
9
10
#include <fstream>
using namespace std;
int main()
{
  ofstream fout;
  fout.open("file.txt");
  fout << "Привет, мир!";
  fout.close();
  return 0;
}

В результате будет создан файл
Работа с файлами в C++

Режимы открытия файлов устанавливают характер использования файлов. Для установки режима в классе ios предусмотрены константы, которые определяют режим открытия файлов.

Константа Описание
ios::in открыть файл для чтения
ios::out открыть файл для записи
ios::ate при открытии переместить указатель в конец файла
ios::app открыть файл для записи в конец файла
ios::trunc удалить содержимое файла, если он существует
ios::binary открытие файла в двоичном режиме

Режимы открытия файлов можно устанавливать непосредственно при создании объекта или при вызове метода open().

ofstream fout("file.txt", ios::app);
fout.open("file.txt", ios::app);

Режимы открытия файлов можно комбинировать с помощью поразрядной логической операции ИЛИ |, например:

ios::out | ios::in - открытие файла для записи и чтения.

Произвольный доступ к файлу

Система ввода-вывода С++ позволяет осуществлять произвольный доступ с использованием методов seekg() и seekp().

  • ifstream &seekg(Смещение, Позиция);
  • ofstream &seekp(Смещение, Позиция);

Смещение определяет область значений в пределах файла (long int).

Система ввода-вывода С++ обрабатывает два указателя, ассоциированные с каждым файлом:

  • get pointer g - определяет, где именно в файле будет производиться следующая операция ввода;
  • put pointer p - определяет, где именно в файле будет производиться следующая операция вывода.

Позиция смещения определяется как

Позиция Значение
ios::beg Начало файла
ios::cur Текущее положение
ios::end Конец файла

Всякий раз, когда осуществляются операции ввода или вывода, соответствующий указатель автоматически перемещается.
С помощью методов seekg() и seekp() можно получить доступ к файлу в произвольном месте.

Можно определить текущую позицию файлового указателя, используя следующие функции:

  • streampos tellg() - позиция для ввода
  • streampos tellp() - позиция для вывода

 
Пример на С++

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include <iostream>
#include <fstream>
using namespace std;
int main()
{
  system("chcp 1251");
  system("cls");
  char s[80];
  fstream inOut;
  inOut.open("file.txt", ios::out);
  inOut << "строчка текста" << endl;
  inOut.seekp(8, ios::beg);
  inOut << "еще строчка текста";
  inOut.close();
  inOut.open("file.txt", ios::in);
  inOut.seekg(-6, ios::end);
  inOut >> s;
  inOut.close();
  cout << s;
  cin.get();
  return 0;
}

В результате выполнения первой части программы будет создан файл
Создание файла
Вторая часть программы выведет в консоль
Считывание данных из файла

Ещё один пример. Допустим, нам нужно заполнять таблицу

ФИО Дата рождения Хобби
     

Причем каждая вновь введенная строка должна размещаться в таблице непосредственно под "шапкой".

Алгоритм решения задачи следующий:

  • формируем очередную строку для вывода
  • открываем файл для чтения, считываем из него данные и сохраняем их в массив строк
  • закрываем файл
  • открываем файл для записи
  • выводим "шапку" таблицы
  • выводим новую строку
  • выводим все сохраненные строки обратно в файл, начиная со строки после шапки

Пример на C++

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
#include <iostream>
#include <fstream>
using namespace std;
#define LINES 100 // максимальное количество строк в файле
int main() {
  system("chcp 1251");
  system("cls");
  char line[LINES][100];
  char str[30];
  char s[] = "|                              |                |                              |";
  // Ввод данных для размещаемой строки
  cout << "ФИО: ";
  cin.getline(str, 30); // вводим ФИО
  for (int i = 0; str[i] != '\0'; i++) // копируем в строку без 0
    s[i + 2] = str[i];               // начиная с указанной позиции
  cout << "Дата: ";
  cin.getline(str,30);
  for (int i = 0; str[i] != '\0'; i++)
    s[i + 33] = str[i];
  cout << "Хобби: ";
  cin.getline(str,30);
  for (int i = 0; str[i] != '\0'; i++)
    s[i + 50] = str[i];
  
  fstream inOut;
  inOut.open("file.txt",  ios::in); // открываем файл для ввода
  // Считываем из файла имеющиеся данные
  int count = 0;
  while (inOut.getline(line[count], 100)) count++;
  inOut.close(); // закрываем файл
  
  inOut.open("file.txt", ios::out); // открываем файл для вывода
  inOut << "--------------------------------------------------------------------------------" << endl;
  inOut << "|   ФИО                        |  Дата          | Хобби                        |" << endl;
  inOut << "--------------------------------------------------------------------------------" << endl;
  inOut << s << endl; // выводим сформированную строку
  inOut << "--------------------------------------------------------------------------------" << endl;
  // Выводим обратно в файл все строки кроме "шапки" (первые 3 строки)
  for (int j = 3; j < count; j++)
  {
    inOut << line[j] << endl;
  }
  inOut.close();
  cin.get();
  return 0;
}

Результат выполнения:
Ввод строки таблицы
Ввод строки таблицы
Ввод строки таблицы

Полученный файл данных:
Файл данных


Назад: Язык C++

Комментариев к записи: 60

  • Евгений
    Здравствуйте Елена. Скажите, а можно ли как то узнать наступивший конец файла. Например, если количество строк в файле неизвестно, а нужно организовать цикл по их считыванию и прервать его по окончанию файла.


    • Николай
      test.eof() - функция которая определяет конец файла елся файл закончился вернёт 1 иначе 0:
      1
      2
      3
      4
      5
      6
      ifstream test("U:\\prog struct17\\list.txt"); // полное имя файла
          if (!test) {
              cout << "not found test_file ";
              return 0;
      while(!test.eof()){ //пока не конец.
      ....}

    • Метод eof(). Например
      1
      2
      3
      4
      5
      6
      7
      8
      ifstream fsInp; 
      int nVar;
      fsInp.open("data.txt");
      while(!fsInp.eof())
           { fsInp >> nVar; // Считали
                            // Обработали
           }
      fsInp.close();

  • Елена, здравствуйте! Помогите, пожалуйста. Есть код, работающий, но вывод делает в консоль, а так как вывод очень большой, то все результаты там не помещаются, только малая последняя часть. Подскажите, пожалуйста, где и что изменить, чтоб вывод записывало в файл. Если можно очень подробно или прям конкретным примером, я со всем этим только только столкнулась, поэтому пока не особо соображаю(( Вот мой код
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    import static java.lang.System.out;
    import java.util.Arrays;
    class Combinations
    {
        private static final int M = 12;
        private static final int N = 24;
        private static int[] generateCombinations(int[] arr)
        {
            if (arr == null)
            {
                arr = new int[M];
                for (int i = 0; i < M; i++)
                    arr[i] = i + 1;
                return arr;
            }
            for (int i = M - 1; i >= 0; i--)
                if (arr[i] < N - M + i + 1)
                {
                    arr[i]++;
                    for (int j = i; j < M - 1; j++)
                        arr[j + 1] = arr[j] + 1; 
                    return arr;
                }
            return null;
        }
        public static void main(String args[])
        {
            int[] arr = null;
            while ((arr = generateCombinations(arr)) != null)
                    out.println(Arrays.toString(arr));
        }
    }

    • Елена Вставская
      В настройках консоли (меню в верхнем левом углу) изменить размер буфера

  • Владимир
    Елена, не поможете? Я сделал сканер для 8-мм кинопленки, теперь хочу процесс усовершенствовать. Для лучшего сканирования нужно делать 2 BMP скана при разной экспозиции, затем слишком светлые пиксели (допустим сумма R, G и B выше 700 или где-то около этого, подберу при отладке), заменить аналогичными пикселями из второго файла, сделанного при меньшей экспозиции, затем сохранить изменения в первом файле, а второй удалить. Первый еще бы и в jpeg-e сохранить. В перспективе еще и 3-й скан должен появиться, в инфракрасном свете, но его пока нету, а если получится делать из 2-х, з-й не проблема. Размеры растра, тип файла известны и не могут измениться. Сжатия нет, 24-битный цвет. Думаю, что нужно без нестандартных библиотек открывать одним циклом (смещение 40) оба файла, затем вычислять сумму RGB, сравнивать с константой и при превышении заменять значениями их 2-го файла, затем удалить 2-й файл, сохранить 1-й ("шапку" просто скопировать, растр с изменениями) и еще бы его сразу jpeg -ом сделать. Просто скажите, я в правильную сторону копаю или нет? А если еще и какие-нибудь указания дадите, буду чрезвычайно признателен! Могу пленки отсканировать лучше "Мосфильма". Бесплатно, разумеется, я всем бесплатно это делаю. Это для души. Заранее благодарен

    • Елена Вставская
      Думаю, что "в правильную". Можно попробовать взять, например, среднее арифметическое для каждой точки из двух файлов. Но это нужно анализировать при отладке.

  • Елена, здравствуйте. Подскажите, пожалуйста, как можно сделать так, чтобы из первой строки файла считывался размер массива, а из второй - его элементы, количество которых равно значению из первой строки. Не нашла у вас на сайте ничего про построчный ввод из файла. Заранее спасибо.

    • Елена Вставская
      Ввод из файла осуществляется аналогично консольному вводу. После считывания порции данных указатель позиции файла автоматически перемещается на ее конец.

      • Да, но у вас в статьях нет ничего про, к примеру, getline. По вашим статьям я изучаю практически все, очень понятно и доходчиво написано, но этот блок то ли я не могу найти, то ли его нет. Подскажите, у вас на сайте есть статья, где более подробно описывается файловый ввод и вывод?

  • Здравствуйте, попыталась сделать вывод данных в файл, но почему то только создался документ, а данных там нет. Что не так?
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    ofstream fout("file.txt", ios::out);
        fout.open("file.txt", ios::out);
        for (int i = 0; i < SIZE; i++)
        {
            for (int j = 0; j < SIZE; j++)
                printf("%5d ", a[i][j]); 
            printf("\n");
           
                fout << a[i] << endl;
            
        }
    fout.close();


    • Елена Вставская
      Не совсем понимаю цель этого действия. Почему нельзя создать пустую строку? А вообще sr[0]=0;

  • И ещё один вопрос. Можно ли ввести несколько слов с консоли в одно значение char?

  • Можно ли как-то скопировать половину строки ? Выше вы копировали от середины и до конца, но мне нужно наоборот- от начала до середины ( или 10-го символа)

    • Елена Вставская
      Вроде рассмотрены оба варианта: поиск позиции от начала строки и от конца

      • Не совсем правильно сформулировала , от определённого индекса до определённого индекса. То есть, у нас есть строка(char sr[50]="blablablabla";) Я хочу скопировать с третього индекса по 10.

        • Елена Вставская
          Мы с файлом работе м или со строкой? Если со строкой, то функция strncpy(&sr[3], 7, dst);

  • 1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    #include <fstream>
    #include <iostream>

    using namespace std;
    #define LINES 100

    int main(int argc, char* argv[]) {
        system("chcp 1251");
        system("cls");
        char line[LINES][150];
        char str[30];
        char s[] = "|                               |                     |                                |                 ";
        cout << "Prizwyshce: ";
        cin.getline(str, 30); 
        for (int i = 0; str[i] != '\0'; i++) 
         s[i + 0] = str[i];              
        cout << "Matematyka: ";
        cin.getline(str, 30);
        for (int i = 0; str[i] != '\0'; i++)
            s[i + 33] = str[i];
        cout << "Programywannya: ";
        cin.getline(str, 30);
        for (int i = 0; str[i] != '\0'; i++)
           s[i + 61] = str[i];
        cout << "Metrologiya: ";
        cin.getline(str, 30);
        for (int i = 0; str[i] != '\0'; i++)
          s[i + 97] = str[i];



        ofstream file;
        file.open("EXAM.txt", ios::in);
        file << "------------------------------------------------------------------------------------------------------------" <<endl;
        file << "|Прізвище                      |Вища мат.|Програмування|Метрол.|"<<endl;
        file << "------------------------------------------------------------------------------------------------------------" << endl;
        file << s << endl;
        for (int j = 3; j<count; j++)
        {
            file << line[j] << endl;
        }

        file.close();
        cin.get();
        return 0;
    }
    надо сделать типа чтобы еще можно было добавить людей в список и выровнять это все

    • Елена Вставская
      Почему файл объявлен как поток вывода, а открывается для ввода? Чему равен count? Где тут люди? Почему при вводе нет цикла?

  • Здравствуйте, есть код:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    #include <iostream>
    #include <cstdlib>
    #include <fstream>
    #include <iomanip>
    #include <cmath>
    #include <string>
    using namespace std;

    void FuncA()
    {
      cout << "Данные записаны" << endl << endl;
    }
    void FuncB()
    {
      cout << "Функция 2";
    }
    void FuncC()
    {
      cout << "Функция 3";
    }
    int main()
    {
      setlocale(0, "");
      cout << "Введите название файла" << endl;
      char filename[40];
      cin.getline(filename, 40);
      ofstream File (filename);
      File << ".";
      cout << "Файл создан!" << endl;
      File.close();
      ifstream fin (filename);
        if (!fin.is_open())
          {
          cout << "Файл не может быть открыт!" << endl;
          }
        else
        {
          cout << "Файл открыт" << endl;
        }
        cout << "Выберите операцию: " << endl;
        int cmd = -1;
        do
        {
          if (cmd == 1)
          FuncA();
          else if (cmd == 2)
          FuncB();
          else if (cmd == 3)
          FuncC();
          cout << "1-Вывод размера типов данных\n2-Рассчёт фрактала\n3-Рассчёт активности по цефепиму и L-аргинину\n0-Выход" << endl;
          cin >> cmd;
        }
      while (cmd);
      return 0;
    }
    Как в функции(например FuncA) начать работу с уже созданным файлом filename?

  • Здравствуйте, подскажите как считать данные из файла, сохранённых в следующем виде: Check Type | Check name | Cost check | 12 |Full |50000 | 38 |Half |25000 | 156 |Special |79000 | и записать данные в структуру. Например: Поле "Struct->CheckType" имеет значение "12" Поле "Struct->CheckName" имеет значение "Full" Поле "Struct->CostCheck" имеет значение "50000"

    • Елена Вставская
      Считывать по строкам, далее строку разделять по символу | и присваивать значения полям структуры. Если поля структуры целочисленные, то предусмотреть ещё перевод из строки в число.

  • Здравствуйте. Возникла проблема, когда пытался переделать ваш код под себя. Выдается очень странный баг, хотя программа компилируется. Я добавил возможность использования программы повторно, без перезапуска консоли, через цикл while. И немного изменил шапку и ее ввод. В общем вот код. Если получится найти причину, буду очень благодарен.
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    #include <iostream>
    #include <fstream>
    using namespace std;
    #define LINES 100 
    int main() {
      system("chcp 1251");
      system("cls");
      int check = 1;
      char line[LINES][100];
      char str[41];
      char s[] = "|                    |                    |                                        |                    |                    |                    |                         |";
      while (check == 1) {
        cout << "Имя : ";
        cin.getline(str, 20);
        for (int i = 0; str[i] != '\0'; i++)
          s[i + 1] = str[i];
        cout << "Фамилия : ";
        cin.getline(str, 20);
        for (int i = 0; str[i] != '\0'; i++)
          s[i + 22] = str[i];
        cout << "Адрес проживания : ";
        cin.getline(str, 40);
        for (int i = 0; str[i] != '\0'; i++)
          s[i + 43] = str[i];
        cout << "Город : ";
        cin.getline(str, 20);
        for (int i = 0; str[i] != '\0'; i++)
          s[i + 84] = str[i];
        cout << "Почтовый индекс : ";
        cin.getline(str, 20);
        for (int i = 0; str[i] != '\0'; i++)
          s[i + 105] = str[i];
        cout << "Номер телефона : ";
        cin.getline(str, 20);
        for (int i = 0; str[i] != '\0'; i++)
          s[i + 126] = str[i];
        cout << "Адрес эл. почты : ";
        cin.getline(str, 25);
        for (int i = 0; str[i] != '\0'; i++)
          s[i + 147] = str[i];

        fstream abonent;
        abonent.open("file.txt", ios::in);

        int count = 0;
        while (abonent.getline(line[count], 100)) count++;
        abonent.close();

        abonent.open("file.txt", ios::app);
        abonent.seekg(0, ios::end);
        if (abonent.tellg() == 0) {
          abonent << "-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------" << endl;
          abonent << "|        Имя         |      Фамилия       |            Адрес проживания            |       Город        |  Почтовый индекс   |   Номер телефона   |     Адрес эл. почты     |" << endl;
          abonent << "-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------" << endl;
        }
        abonent << s << endl;
        abonent << "-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------" << endl;
        abonent.close();
        cout << "Продолжить? ";
        cin >> check;
      }
      cin.get();
      return 0;
    }

    • Елена Вставская
      Пока вижу 2 бага, не знаю, какой Вы имеете в виду. 1. Когда вводим данные второго и последующих лиц, программа "глотает" Имя. 2. Если, допустим, фамилия второго человека окажется короче, чем у первого, то она будет дополнена "остатком" предыдущей фамилии.


  • Николай
    Подскажите, а можно определить середину строки s, в файле при помощи tellg/tellp или seekg/seekp?

    • Елена Вставская
      Считать всю строку. Найти ее длину с помощью strlen() и сместить курсор на "минус" половину этого значения от текущей позиции.

      • Николай
        Наверно не то что Вы имели ввиду?
        1
        2
        3
        4
        5
        6
        7
        8
        9
        10
        11
        12
        13
        14
        15
        16
        17
        18
        19
        20
        21
        22
        23
        24
        #include <iostream>
        using namespace std;
        int main()
        {
            string buf;
            ifstream infile;
            infile.open("text.txt", ios::in);
            if(infile.is_open()){
                infile >> buf;
                short n = strlen(buf);
                short k=0;
                if(n%2) {
                    k = n/2;
                    cout << buf[k];
                }
                else cout << buf[k] << " " << buf[k+1];
            }
            else{
                cout << "File error."<< endl;
                return 1;
            }
            infile.close();
        return 0;
        }

  • Николай
    Спасибо за статью. Познавательно. Пробую использовать данный вывод в файл, но возникла проблема: Файл создается и очищается (проверено) но запись в файл не происходит, и после выполнения данного кода
    1
    2
    3
    4
    5
    6
    7
    std::string textoutbuf = "yjjfhjshdsjhf dkcfjdhj jfcjh 111111";
    textoutbuf.push_back('\n');
    //m_sock.fileLog << "yjjfhjshdsjhf dkcfjdhj jfcjh 111111";
    m_sock.fileLog << textoutbuf;
    INT qqq = GetLastError();
    m_sock.fileLog.flush();//очистить поток
    m_sock.fileLog.close();
    файл всегда нулевой длины. Что уже не пробовал, читал форумы но ответа пока не нашел. Может Вы подскажете в чем может быть проблема? Спасибо.

    • Елена Вставская
      Возможно, я чего-то не учитываю, поскольку приведен только фрагмент кода. Но такая реализация позволит получить файл с данными:
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      #include <fstream>
      using namespace std;
      int main()
      {
        ofstream m_sock;
        m_sock.open("C://1/file.txt");
        char textoutbuf[] = "yjjfhjshdsjhf dkcfjdhj jfcjh 111111\n";
        m_sock << textoutbuf;
        m_sock << "yjjfhjshdsjhf dkcfjdhj jfcjh 111111";
        m_sock.flush();
        m_sock.close();
        return 0;
      }


  • А как записать данные в файл с названием, определяемым самим пользователем? Насколько я понял, в качестве названия файла можно использовать только константу (?)

    • Елена Вставская
      Нет, Вы можете ввести имя файла в ходе выполнения программы.
      1
      2
      3
      4
      5
      char filename[40];
      cout >> "filename: ";
      cin << filename;
      inOut.open(filename,  ios::in);
      ...

  • извините, я наверно вас уже заколебал, с этой 4 строчкой... Но мне надо прочитать строчку из файла и вывести ее в консоль. Т.е. В файле есть 4 строка мне ее надо прочитать и вывести на экран. inOut.open("file.txt",ios::out); for(int i=0; i<4; i++) cout<<line[i]; выводит белиберду. То есть я хочу теперь эту табличку на экране увидеть, но не всю, а только ее часть, например строку 4.
    for(int i=0; i<100; i++) cout<<line[4][100]; Тоже не  работает

  • 1
    while ( inOut.getline (line[count], 100) ) count++;
    А как происходит перебор строк? Я как понимаю, мы читаем строку в массив line[1]; Потом читаем еще раз строку, но в массив line[2]; и т.д. до line[100]. А где мы говорим, что мы не читаем одну и туже строчку то? Как встать то на строчку 5? И прочитать что в строке 5 У нас Петров Петр.

    • Почему если в файле "file.txt" есть информация, то данный код не просто читает он удаляет все из файла?

      • Елена Вставская
        При считывании строки указатель позиции в файле автоматически смещается на её длину. Поэтому если мы считаем 4 строки, то окажемся на начале 5-ой. Считав её, мы получим нужную нам информацию.
        Если данные из файла считываются, то они не удаляются. Удаление данных происходит только при открытии файла в режиме записи (строка 32 последнего примера в статье).

        • Спасибо большое за ответы. Но а как мне получить строку под номером 4? Допустим я не знаю что в файле, и я хочу прочитать только 4 строчку. line[4] выводит все четвертые буквы всех строк, но не всю строку целиком. Может как то можно получить массив строк и массив символов за раз? Например my_line_txt[4][5] - четвертая строка 5 символ.

          • Елена Вставская
            line[4] - это и есть 4-ая строка. Первый индекс в массиве line[][] - это номер строки, второй - номер символа в строке.
            1
            2
            3
            int i;
            for(i=0; i<4; i++) inOut.getline(line[i], 100);
            inOut.getline(line[i], 100); // вот Ваша 4-ая строка


  • Подскажите пожалуйста (нигде найти не могу) Как выводить в файл строки сверху. было То, как зверь, она завоет, То заплачет, как дитя, Надо вставить сверху строчки, что бы получилось так: Буря мглою небо кроет, Вихри снежные крутя; То, как зверь, она завоет, То заплачет, как дитя, Только не говорите что для этого отдельный файл создавать надо....:)

    • Если использовать флаг ios::beg Да, он ставит курсор в начало файла. Но он удалит весь текст который там был. И вставить строчку не получиться. Вместо вставки происходит замена.

      • Елена Вставская
        Я, конечно, не буду говорить, что нужно создавать отдельный файл :) Но придётся считать всю информацию из файла и где-то её сохранить. Потом открыть файл для записи. Записать недостающие строки сверху, а потом снова выгрузить сохраненное содержимое файла.

        • А если надо  заполнить такую таблицу что бы последние введенные данные были наверху. То есть, есть шапка которую нельзя трогать. файл 1 "с шапкой" файл 2 "с новой строкой" файл 3 = файл 1+файл2; // итоговый наш файл файл 2 = получили новую строку файл 4 = скопировать все с 4 строчки и ниже из файла №3 файл 3 = встаем на четвертую строчку и добавляем файл №2 с нашей строкой файл 3 = копируем все из файла 4. Только так можно это реализовать? Как можно установить курсор на 4 строчку? ----------------------------------------------------------------------------------- | Фамилия  | Имя  |  Отчество  |   дата рождения  |   хобби   | ----------------------------------------------------------------------------------- |_________|_____|__________|_______________|________| |_________|_____|__________|_______________|________| |_________|_____|__________|_______________|________| |_________|_____|__________|_______________|________|

          • Как можно установить курсор на 4 строчку? И как можно скопировать все что ниже 4 строчки. Или удалить все что выше 4 строчки.

          • Елена Вставская
            Ответила в тексте статьи


  • Блог программиста
    Хорошая статья, но: 1) в последнем листинге используются операторы >> и <<, в статье не объясняется как именно они работают; 2) не упоминается функция getline - это единственный способ считать строку целиком; 3) в начале упоминается про бинарные файлы, но не описано как с ними работать; 4) если не всегда, то очень часто, входной файл обрабатывается до тех пор, пока не будут считаны все элементы. В статье нет слова про feof; 5) что если файл не удалось открыть? - там целый комплекс флажков есть и еще можно объект сравнить с нулем (есть перегруженный оператор для этого, который проверяет набор каких-то флажков) - так очень часто делают; 6) я не знаю что случится при попытке переместить каретку чтения в файле на недоступную позицию, но думаю, что вылетит исключение. Я могу посмотреть в документации, конечно, но мог бы и у вас прочитать (так-то в документации про seekp тоже написано); 7) я думаю, стоит упомянуть, что если файл не закрывать - то он закроется сам когда объект будет разрушен. Ну потому, что так-то, мне кажется, файлы не часто закрывают - это нужно делать только если есть вероятность, что программа завершится настолько аварийно, что до деструктора файла дело не дойдет. ЗЫ:. вот этот system("cls") я бы лично не использовал (как и system вообще) - некроссплатформенно это... По крайней мере по возможности его стоит избегать, никакой острой необходимости вставлять его в такие учебные статьи я не вижу ((

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *