Форум программистов, компьютерный форум CyberForum.ru

Чтение начиная с конца файла - C++

Восстановить пароль Регистрация
 
Рейтинг: Рейтинг темы: голосов - 13, средняя оценка - 4.92
ArkTaS
1 / 1 / 0
Регистрация: 01.07.2013
Сообщений: 127
06.08.2013, 21:22     Чтение начиная с конца файла #1
Всем добрый вечер! Программа создает самопальный класс список как в STL и пишет/ читает с файла Вот результат работы: Чтение начиная с конца файла. Считывать в обратном порядке, затем переворачивать не предлагайте. Помогите пожалуйста заставить ее читать символы в обратном порядке.
Пробовал вносить в функцию чтения такие изменения( помечены !! в коментариях) , но программа висла при запуске:
Режим ios::ate почему то не работает
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
void linklist::read()
{
   ifstream file;
   file.open("ex8.txt", ios::ate);     // !!
   file.seekg(0, ios::end);   // !!
   cout<<endl;
   while(!file.tellg())     //  !!
   {
   link* newlink = new link; // выделяем память
   file>>newlink->data;
//  cout<<newlink->data<<' ';
   newlink->next = first; // запоминаем значение first
   first = newlink; // first теперь указывает на новы
   }
   file.close();
}
Сама программа без изменений, та что считывает в обратном порядке:
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
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
#include <fstream> // для потоковых файловых функций
#include <iostream>
#include <istream>
#include <string>
#include <typeinfo> // для typeid()
using namespace std;
#include <process.h> // для exit()
 
 
struct link // один элемент списка
{
   int data; // некоторые данные
   link* next; // указатель на следующую структуру
};
class linklist // список
{
private:
   link* first;
  // static fstream file;
public:
   linklist() { first = NULL;  } // первого элемента пока нет
   void additem(int d); // добавление элемента
   void display(); // показ данных
   void read();
   void write();
  /* static void Open()
   {
       file.open("ex8.txt", ios::in | ios::out | ios::trunc );
   }*/
};
///////////////////////////////////////////////////////////
void linklist::additem(int d) // добавление элемента
{
   link* newlink = new link; // выделяем память
   newlink->data = d; // запоминаем данные
   newlink->next = first; // запоминаем значение first
   first = newlink; // first теперь указывает на новый элемент
}
///////////////////////////////////////////////////////////
void linklist::display()
{
   link* current = first; // начинаем с первого элемента
   while(current) // пока есть данные
  {
   cout << current->data << ' '; // печатаем данные
   current = current->next; // двигаемся к следующему элементу
  }
}
 
void linklist::write()
{
   ofstream file;
   file.open("ex8.txt" );
  file.seekp(0);
   link* current = first; // начинаем с первого элемента
   while(current) // пока есть данные
   {
    file << current->data; // записываем данные
    current = current->next; // двигаемся к следующему элементу
    if(current)
        file<<' ';
   }
   file.close();
}
 
void linklist::read()
{
   ifstream file;
   file.open("ex8.txt");
 //  file.seekg(0, ios::end);
   cout<<endl;
   while(!file.eof())
   {
   link* newlink = new link; // выделяем память
   file>>newlink->data;
//  cout<<newlink->data<<' ';
   newlink->next = first; // запоминаем значение first
   first = newlink; // first теперь указывает на новы
   }
   file.close();
}
//fstream linklist::file;
///////////////////////////////////////////////////////////
 
void main()
{
   setlocale( LC_ALL,"Russian" );
 
   linklist li; // создаем переменную-список
 //  linklist::Open();
 
   li.additem(25); // добавляем туда несколько чисел
   li.additem(36);
   li.additem(49);
   li.additem(64);
   li.display(); // показываем список
 
   li.write();
 
   linklist li2;
   li2.read();
   li2.display();
 
   cout<<endl;
   system("pause");
}
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
alsav22
5282 / 4801 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
06.08.2013, 22:00     Чтение начиная с конца файла #2
Перед очередным чтением, передвигайте курсор назад от текущего положения:
C++
1
file.seekg(-n, ios::cur);
Над вычислением значения n, подумайте.

Добавлено через 16 минут
И всегда проверяйте открытие файла для чтения, у вас, может быть, файл не открывается.
C++
1
2
3
4
5
6
7
8
9
10
...
ifstream file;
file.open("ex8.txt", ios::ate);
if (!file.is_open())
{
     cout << "Error!" << endl;
     return;
}  
else
{...
ArkTaS
1 / 1 / 0
Регистрация: 01.07.2013
Сообщений: 127
07.08.2013, 15:16  [ТС]     Чтение начиная с конца файла #3
Пришел к выводу что так лучше не делать если данные записаны в символьном виде, т.к если элементы будут занимать разное количество символов невозможно будет посчитать смещение n. Так что взял попросту считал в временный массив а потом уже создал и заполнил список)
alsav22
5282 / 4801 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
07.08.2013, 22:04     Чтение начиная с конца файла #4
Цитата Сообщение от ArkTaS Посмотреть сообщение
Пришел к выводу что так лучше не делать если данные записаны в символьном виде, т.к если элементы будут занимать разное количество символов
В каком конкретно виде?
Цитата Сообщение от ArkTaS Посмотреть сообщение
Так что взял попросту считал в временный массив
Это говорит о том, что данные, всё-таки, имеют конкретный размер, иначе, как выделить массив, неизветсно под какой размер данных?
ArkTaS
1 / 1 / 0
Регистрация: 01.07.2013
Сообщений: 127
07.08.2013, 22:27  [ТС]     Чтение начиная с конца файла #5
Цитата Сообщение от alsav22 Посмотреть сообщение
Сообщение от ArkTaS
Пришел к выводу что так лучше не делать если данные записаны в символьном виде, т.к если элементы будут занимать разное количество символов
В каком конкретно виде?
ну например 4500 56 9999999 и список размером больше 100
после записи в файл 4500 будет размером 4 символа, 56 в 2 символа и т.д. А при считывании задом наперед нужно знать размер всех элементов для правильного смещения указателя чтения. Поэтому считаю что лучше не читать форматированную запись задом наперед. В бинарном виде можно, всегда пожалуйста ! - размер мы знаем

Добавлено через 2 минуты
Цитата Сообщение от alsav22 Посмотреть сообщение
Это говорит о том, что данные, всё-таки, имеют конкретный размер, иначе, как выделить массив, неизветсно под какой размер данных?
Так для упражнения я втулил обычный массив с запасом. Но лучше конечно использовать вектор. Он сам свой размер отрегулирует.
alsav22
5282 / 4801 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
07.08.2013, 23:22     Чтение начиная с конца файла #6
Если в файле int через пробел записаны, то можно так:
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
47
#include <fstream> 
#include <iostream>
using namespace std;
 
int main()
{
   int arr[3] = {1, 123, 12345};
 
   ofstream fout("f.txt");
   for (int i = 0; i < 3; ++i)
       fout << arr[i] << ' ';
 
   fout.close();
 
   ifstream fin("f.txt"); // в файле: "1 123 12345 "
   if (!fin)
    {
        cout << "Error!" << endl;
        system("pause");
   }
   else
   {
       fin.seekg(-3, ios::end);
       
       int n;
       int pcur;
       while (true)
       {
            if (fin.peek() == ' ' || (pcur = fin.tellg()) == 0)
            {
                pcur = fin.tellg();
                
                fin >> n;
                cout << n << ' ';
                
                if (pcur == 0) break;
                fin.seekg(pcur - 1);
            }
            else fin.seekg(-1, ios::cur);
       }
       fin.close();
    }
   
   cout << endl;
   system("pause");
   return 0;
}
Миниатюры
Чтение начиная с конца файла  
ArkTaS
1 / 1 / 0
Регистрация: 01.07.2013
Сообщений: 127
08.08.2013, 00:11  [ТС]     Чтение начиная с конца файла #7
Четко написано, для меня камнем преткновения как раз стало то что после чтения элемента неизвестного размера курсор смещался не известно на сколько. Не догадался хранить его позицию в переменной pcur = fin.tellg(), а так же выполнять проверку fin.peek() == ' '
Все понятно кроме 34 строки fin.seekg(-3, ios::end). Почему именно -3 на -2 тоже работает, а так же почему не работает на -1 ?
alsav22
5282 / 4801 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
08.08.2013, 01:41     Чтение начиная с конца файла #8
Цитата Сообщение от ArkTaS Посмотреть сообщение
а так же почему не работает на -1 ?
Курсор будет на последнем пробеле, считается конец файла, после этого курсор не перемещается (нужно флаги сбросить).
Цитата Сообщение от ArkTaS Посмотреть сообщение
Почему именно -3 на -2 тоже работает
Можно и -2, но если предположить, что число состоит хотя бы из одной цифры, то лучше -3 (попадём или на пробел перед однозначным числом, или на цифру многозначного числа).
Esecman
38 / 26 / 6
Регистрация: 31.12.2013
Сообщений: 329
04.03.2014, 16:18     Чтение начиная с конца файла #9
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
#include <iostream>
#include <fstream> 
using namespace std;
 
int main()
{
   ifstream fin("data.txt");
   if (!fin)
    {
        cout << "Error! File not found" << endl;
        system("pause");
   }
   else
   {
       fin.seekg(-3, ios::end);
       
       float n = 0;
       int pcur;
       while (true)
       {
            if ((pcur = fin.tellg()) == 0)
            {
                pcur = fin.tellg();
                
                while(!fin.eof()) {
                string str;
                getline(fin, str);
                cout << str << endl;
                }
 
                if (pcur == 0) break;
                fin.seekg(pcur - 1);
            }
            else fin.seekg(-1, ios::cur);
       }
       
       fin.close();
    }
   
   cout << endl;
   system("pause");
   return 0;
}
Немного переделал под себя.
Но мне все равно не удается прочитать числа с конца файла
Числа без пробелов.

На каждой строке по одному числу :-)
Type Float(int n =0 >> float n = 0)
alsav22
5282 / 4801 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
04.03.2014, 16:50     Чтение начиная с конца файла #10
Цитата Сообщение от Esecman Посмотреть сообщение
Немного переделал под себя.
Поэтому:
Цитата Сообщение от Esecman Посмотреть сообщение
не удается прочитать числа с конца файла
У меня в коде пробел ищется, а потом читается число. А у вас?
zer0mail
2189 / 1872 / 187
Регистрация: 03.07.2012
Сообщений: 6,665
Записей в блоге: 1
05.03.2014, 15:39     Чтение начиная с конца файла #11
Так надо читать в обратном порядке или выводить в обратном порядке?
Esecman
38 / 26 / 6
Регистрация: 31.12.2013
Сообщений: 329
06.03.2014, 11:34     Чтение начиная с конца файла #12
выводить в обратном порядке
Знаю, что нужно использовать функции fseek , но не знаю как применить :|

Добавлено через 15 часов 45 минут
heYyYyYYyYyYyYyYYyyYYyYYyY
ValeryS
Модератор
6377 / 4843 / 442
Регистрация: 14.02.2011
Сообщений: 16,061
06.03.2014, 11:40     Чтение начиная с конца файла #13
Цитата Сообщение от Esecman Посмотреть сообщение
Знаю, что нужно использовать функции fseek , но не знаю как применить :|
идешь на конец файла
1 потом сдвигаешь на одну запись к началу
2 потом читаешь
3 потом на две записи к началу( одна только что прочитанная, другая перед ней)
если достигли начала считываем и выходим иначе к п.2
но это будет долго
проще и быстрее считать весь файл в стек (std::stack) и потом достать оттуда записи
Esecman
38 / 26 / 6
Регистрация: 31.12.2013
Сообщений: 329
06.03.2014, 21:24     Чтение начиная с конца файла #14
А код можно? (Пример его )

Добавлено через 1 час 41 минуту
UP!!!
Esecman
38 / 26 / 6
Регистрация: 31.12.2013
Сообщений: 329
08.03.2014, 19:52     Чтение начиная с конца файла #15
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
#include <iostream>
#include <fstream>
 
using namespace std;
 
int main ( )  {
    
   FILE* fp;
   fp = fopen("new.txt", "r");
    
   ifstream file; // ifstream func
   
   char mystring[100];
   
   int array = 0; // value
   
   int NUM_OF_FILE = 0; // value
 
   file.open("data.txt"); // для использования getline();
   
   //file.seekg(-1, ios::end); // перенесем указатель в конец.
   
   //file.seekg(0, ios::end);
    
   while(!file.eof()) {
   string str;
   getline(file, str);
   NUM_OF_FILE++;
   cout << str << endl;
   }
   
   fseek(fp, 0, SEEK_END);
     
   long size=ftell(fp); // получим общее число байтов в файле.
   
   cout << size << " bytes in file" << endl;
   
   system("pause");
}
Вот, набросок кода.
Правильно использовано?

Закомментировал то, что не работает.

Перед while(!file.eof())
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
15.03.2014, 21:36     Чтение начиная с конца файла
Еще ссылки по теме:

Чтение файла с несколькими знаками конца файла C++
Разделить число на 3 группы, начиная с конца C++
Чтение запросов до конца файла C++

Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
Esecman
38 / 26 / 6
Регистрация: 31.12.2013
Сообщений: 329
15.03.2014, 21:36     Чтение начиная с конца файла #16
Ребята, хелпаните :-)

Добавлено через 22 часа 56 минут
ппц

Добавлено через 2 часа 23 минуты
Помогите, ребята))
Yandex
Объявления
15.03.2014, 21:36     Чтение начиная с конца файла
Ответ Создать тему
Опции темы

Текущее время: 02:38. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru