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

Запись и чтение вектора из файла - C++

Восстановить пароль Регистрация
 
 
Рейтинг: Рейтинг темы: голосов - 10, средняя оценка - 4.80
Флибустьер
 Аватар для Флибустьер
0 / 0 / 0
Регистрация: 24.01.2011
Сообщений: 12
02.08.2012, 13:48     Запись и чтение вектора из файла #1
Здравствуйте! Помогите понять ошибку. Создаю группу, записываю ее в файл (первым в файл записывается непонятный символ). Первый запуск нормальный, файл создается, но при повторном группа дописывается, а вот уже на функции void ReadGroup(char *path, group&g); вылетает ошибка.

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
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
#include <iostream>
#include <vector>
#include <conio.h>
#include <stdio.h>
#include <string.h>
#include <vector>
#include <fstream>
#include <iostream>
#include <algorithm>
#include <conio.h>
using namespace std;
 
struct Student
{
   char name [30], surname [30], year [10];
};
 
ostream& operator<<(ostream& os, Student &s)
{
    os<< "\nName-" << s.name << " Surname-" << s.surname << " Year-" << s.year << '\n';
    return os;
}
istream& operator >> (istream& is, Student &s)
{
    char nam [30], surnam [30], yer [10];
    cout << "\nName-";
    is >> nam; 
    cout << "Surame-";
    is >> surnam;
    cout << "Year-";
    is >> yer;
    cout << '\n';
    strcpy_s(s.name,nam);
    strcpy_s(s.surname,surnam);
    strcpy_s(s.year, yer);
    return is;
}
 
class group
{
    vector<Student> m;
    char names[30];
public:
    group();
    ~group() {/*del();*/}
    // Конструктор копирования
    group(Student& L)   { group  temp; temp.add(L);}
    void add(Student s) {m.push_back(s);}
    void del() { m.pop_back ();}
    void del(int pos) { m.erase(m.begin()+pos); }
    void Set (char *nam) { strcpy_s (names, nam);}
    void Sort (group&);
    void Serch(group& L, char *s2);
    void print ()
            {
                for (unsigned int i=0; i < m.size(); i++)
                    {
                        cout << "\nName " << m[i].name << "\nSurname " << m[i].surname << "\nYear "<< m[i].year << '\n'; 
                    }
            }
    int size(){return m.size();}
    Student& operator[](int pos) {return m[pos];}
        
        void WriteGroup(char *path, group&g);
        void ReadGroup(char *path, group&g);
    
};
 
void WriteGroup(char *path, group&g)
    {
        FILE *f=fopen(path, "a+"); //аналог fscanf(f, "%s", str);
        if (!f){puts("Error!"); return;}
        int N=g.size();
            fwrite(&g, sizeof(N), 1,f); 
            
        for (int i=0; i<N; i++)
            {
                fwrite (&g[i].name, sizeof(N), 1,f); fprintf(f, "\t");
                fwrite (&g[i].surname, sizeof(N), 1,f); fprintf(f, "\t");
                fwrite (&g[i].year, sizeof(N), 1,f); fprintf(f, "\n");
            }
        fclose(f);
    }
void ReadGroup(char *path, group&g)
    {
        FILE *f=fopen(path, "r+"); 
        if (!f){puts("Error!"); return;}
        int N=g.size();
        
        fread(&g, sizeof(N), 1,f); //&m - адрес объектаб sizeof(N)- кол-во байтб 1 - кол-вой объектов, f-файл
        printf("Name\tSurname\tYear\n");
        for (int i=0; i<N; i++)
            {
                fread (&g[i], sizeof(N)/4, 1,f); 
                fread (&g[i].name, sizeof(N)/4, 1,f); 
                fread (&g[i].surname, sizeof(N)/4, 1,f); 
                fread (&g[i].year, sizeof(N)/4, 1,f); 
            }
        fclose(f);
 
 
    }
void main ()
{
    Student  first, first1, first2, first3;
    
    strcpy_s(first.name,"Ivanovich");
    strcpy_s(first.surname,"Ivanov");
    strcpy_s(first.year,"22");
    
    strcpy_s(first1.name,"Petr");
    strcpy_s(first1.surname,"Petrov");
    strcpy_s(first1.year,"23");
    
    strcpy_s(first2.name,"Alex");
    strcpy_s(first2.surname,"Alexeev");
    strcpy_s(first2.year,"20");
 
    group gr1;
    gr1.add(first);
    gr1.add(first1);
    gr1.add(first2);
    
    cout << gr1 << '\n';
    
    WriteGroup("E:\\Ra.txt",gr1);
    ReadGroup( "E:\\Ra.txt",gr1);
}
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
02.08.2012, 13:48     Запись и чтение вектора из файла
Посмотрите здесь:

Си, Запись и Чтение из файла. C++
C++ Запись и чтение из файла
C++ запись\чтение из файла
C++ Запись/чтение вектора в/из файла.Структуры
Запись и чтение из файла C++
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Avazart
 Аватар для Avazart
6900 / 5140 / 252
Регистрация: 10.12.2010
Сообщений: 22,588
Записей в блоге: 17
02.08.2012, 14:19     Запись и чтение вектора из файла #2
Режит глаз использование Си-строк и сишних функций и fopen() наряду с STL.

Так и не понятно в каком виде должены сохранятся данные в файл?
Двоичном/текстовом ?
Вы используете оба... и ожидаете что это будет работать ?!!!

Зачем перегружать операторы >> и << если не использовать их при выводе в файл ( а не только на экран)
grizlik78
Эксперт C++
 Аватар для grizlik78
1882 / 1414 / 101
Регистрация: 29.05.2011
Сообщений: 2,958
02.08.2012, 14:35     Запись и чтение вектора из файла #3
И какой результат ожидается при использовании sizeof(N)?
Avazart
 Аватар для Avazart
6900 / 5140 / 252
Регистрация: 10.12.2010
Сообщений: 22,588
Записей в блоге: 17
02.08.2012, 14:42     Запись и чтение вектора из файла #4
А это ?
C++
1
fwrite (&g[i].name, sizeof(N), 1,f); fprintf(f, "\t");/*  fwrite и fprintf  */
Флибустьер
 Аватар для Флибустьер
0 / 0 / 0
Регистрация: 24.01.2011
Сообщений: 12
02.08.2012, 15:06  [ТС]     Запись и чтение вектора из файла #5
Цитата Сообщение от Avazart Посмотреть сообщение
Так и не понятно в каком виде должены сохранятся данные в файл?
Бинарном. При завершении работы дынные из вектора должны быть записаны в файл, при повторном запуске считать и если новые есть - дописать в конец.

Цитата Сообщение от grizlik78 Посмотреть сообщение
И какой результат ожидается при использовании sizeof(N)?
Узнать размер хранимых данных и перейти на новую строку?
Цитата Сообщение от Avazart Посмотреть сообщение
А это ?
Код C++
1
fwrite (&g[i].name, sizeof(N), 1,f); fprintf(f, "\t");/* fwrite и fprintf */
Запись имени студента. Или нет? Я с работой с файлами плохо пока знаком, написал, что мог
grizlik78
Эксперт C++
 Аватар для grizlik78
1882 / 1414 / 101
Регистрация: 29.05.2011
Сообщений: 2,958
02.08.2012, 15:09     Запись и чтение вектора из файла #6
Цитата Сообщение от Флибустьер Посмотреть сообщение
Узнать размер хранимых данных и перейти на новую строку?
sizeof(N) возвращает количество байт, необходимых для представления переменной N. То есть это размер типа int, который равен, как правило, четырём, независимо от значения N.
Avazart
 Аватар для Avazart
6900 / 5140 / 252
Регистрация: 10.12.2010
Сообщений: 22,588
Записей в блоге: 17
02.08.2012, 15:11     Запись и чтение вектора из файла #7
fprintf - текстовый и вообще зачем там \t ?

Добавлено через 32 секунды
Я с работой с файлами плохо пока знаком
Ну так читайте и знакомтесь
Флибустьер
 Аватар для Флибустьер
0 / 0 / 0
Регистрация: 24.01.2011
Сообщений: 12
02.08.2012, 15:16  [ТС]     Запись и чтение вектора из файла #8
Цитата Сообщение от Avazart Посмотреть сообщение
Ну так читайте и знакомтесь
Уже пару дней сижу, ищу темы, все перемешалось. Не подскажите, где смотреть? Надо в STL написать для работы с файлами
Avazart
 Аватар для Avazart
6900 / 5140 / 252
Регистрация: 10.12.2010
Сообщений: 22,588
Записей в блоге: 17
02.08.2012, 15:17     Запись и чтение вектора из файла #9
А книги читать не пробовали к примеру Шилда?

Как то глупо выглядит попытка к коду Си прилепить С++ STL

Да и обязательно ли использовать бинарный режим с файлом ?
Флибустьер
 Аватар для Флибустьер
0 / 0 / 0
Регистрация: 24.01.2011
Сообщений: 12
02.08.2012, 15:25  [ТС]     Запись и чтение вектора из файла #10
Цитата Сообщение от Avazart Посмотреть сообщение
Да и обязательно ли использовать бинарный режим с файлом ?
Нет, не критично. Шилдта обязательно гляну, думал в инете найти информацию
Avazart
 Аватар для Avazart
6900 / 5140 / 252
Регистрация: 10.12.2010
Сообщений: 22,588
Записей в блоге: 17
02.08.2012, 16:00     Запись и чтение вектора из файла #11
Приблизительно так
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
//--------------------------------------------------------------------------
struct student
{
  std::string name,surname,year;
 
  student(const std::string& n,
          const std::string& sn,
          const std::string& y):name(n),surname(sn),year(y){};
};
 
std::ostream& operator<<(std::ostream& stream,const student &obj)
{
 stream<<obj.name<<"\t"<<obj.surname<<"\t"<<obj.year;
 return stream;
}
 
std::istream& operator>>(std::istream& stream, student &obj)
{
  stream>>obj.name>>obj.surname>>obj.year;
  return stream;
}
//----------------------------------------------------------------------
int main()
{
using namespace std;
system("chcp 1251");
 
vector<student> v;
 
v.push_back(student("1","2","3")); // числа вместа строк для простоты 
v.push_back(student("5","6","7"));
v.push_back(student("8","9","10"));
// Вывод на экран
copy(v.begin(),v.end(),ostream_iterator<student>(cout,"\n"));
// Вывод в файл
ofstream ofs("1.txt");
if(ofs) copy(v.begin(),v.end(),ostream_iterator<student>(ofs,"\n"));
else cerr<<"Error!!"<<endl;
 
system("pause");
return 0;
}
//---------------------------------------------------------------------------
Флибустьер
 Аватар для Флибустьер
0 / 0 / 0
Регистрация: 24.01.2011
Сообщений: 12
05.08.2012, 13:22  [ТС]     Запись и чтение вектора из файла #12
Спасибо

Добавлено через 20 часов 1 минуту
Мучения продолжаются. Благодаря Avazart написал следующую программу:
Call.h
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
#include <iostream>
#include <vector>
#include <iterator>
#include <conio.h>
#include <fstream>
#pragma once
 
 
class Call
{
 
int day;
int month;
int year;
int min;
int sec;
int areacode;
int callNumber;
double cast;
double payFoCall;
 
public:
    Call(void);
    ~Call(void);
    double CallCast();
    friend std::ostream &operator << (std::ostream &stream, Call c);
    friend std::istream &operator >> (std::istream &stream, Call &c);
};
Call.cpp
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
#include <iostream>
#include <vector>
#include <iterator>
#include <conio.h>
#include <fstream>
#include "Call.h"
 
 
Call::Call(void)
{
}
 
 
Call::~Call(void)
{
}
 
double Call::CallCast()
{
    this->payFoCall = this->min * 0.5;
    return payFoCall;
}
 
 
std::ostream &operator <<(std::ostream &stream, Call c)
{
    stream << "In date: " << c.day << '.' << c.month << '.' << c.year;
    stream << " you call in number ";
    stream << '(';
    std::cout.width(3);
    std::cout.fill('0');
    stream << c.areacode << ')' << '-' << c.callNumber << ",\nlength of call ";
    stream << c.min << "min " << c.sec << "sec. Call cast ";
    stream << c.CallCast() << '\n';
    return stream;
}
 
std::istream &operator >> (std::istream &stream, Call &c)
{
    std::cout << "Enter day/month/year call: ";
    stream >> c.day >> c.month >> c.year;
    std::cout << "Enter min/sec call: ";
    stream >> c.min >> c.sec;
    std::cout << "Enter areacode: ";
    stream >> c.areacode;
    std::cout << "Enter number call: ";
    stream >> c.callNumber;
    std::cout << std::endl;
    return stream;
}
main //тут не корректно работает
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
#include "Call.h"
#include <iostream>
#include <vector>
#include <iterator>
#include <conio.h>
#include <fstream>
 
using namespace std;
int main()
{
    Call c;
    vector<Call> calls;
    ifstream ifs("Calls.txt");
    ofstream ofs("Calls.txt");
    //тут надо заполнить вектор из файла, не работает
    if(ifs.is_open())
                {
                    copy(istream_iterator<Call>(ifs), istream_iterator<Call>(), back_inserter(calls));
                }
    else cerr << "Error!!";
    ifs.close();
 
    char key;
    for(;;){
        do{
            cout << "1. Entry number\n";
            cout << "2. Out numbers\n";
            cout << "3. Exit\n";
            cout << "Select: ";
            cin >> key;
        }while (key <'1' || key >'3');
        switch(key){
        case '1':
            //вводим новый объект
            cin >> c;
            //добавляем его в вектор
            calls.push_back(c);
            break;
        case '2':
            //выводим весь вектор на экран
            copy(calls.begin(),calls.end(),ostream_iterator<Call>(cout));
            break;
        case '3':
            //запись вектора в файл и выход
            if(ofs) copy(calls.begin(),calls.end(),ostream_iterator<Call>(ofs));
            else cerr<<"Error!!"<<endl;
            ofs.close();
            return 0;
        }
 
    }
 
}
И тут я столкнулся с магией... Программа записывает в файл данные из вектора, но при повторном запуске, вместо того, чтобы считать данные из файла и занести их в вектор, она удаляет данные из файла, в вектор ничего не попадает. Где я ошибся?
Avazart
 Аватар для Avazart
6900 / 5140 / 252
Регистрация: 10.12.2010
Сообщений: 22,588
Записей в блоге: 17
05.08.2012, 13:28     Запись и чтение вектора из файла #13
Для записи не открывайте файл раньше времени, а то оно его усекает до нулевой длины
C++
1
2
3
4
5
6
7
8
9
10
 //...
   ifstream ifs("Calls.txt");
    //тут надо заполнить вектор из файла, не работает
    if(ifs.is_open())
                {
                    copy(istream_iterator<Call>(ifs), istream_iterator<Call>(), back_inserter(calls));
                }
    else cerr << "Error!!";
    ofstream ofs("Calls.txt");
//...
Флибустьер
 Аватар для Флибустьер
0 / 0 / 0
Регистрация: 24.01.2011
Сообщений: 12
05.08.2012, 13:45  [ТС]     Запись и чтение вектора из файла #14
Убрал, переместил после закрытия файла для чтения. Все равно обнуляет после открытия и в вектор ничего не пишется
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
int main()
{
    Call c;
    vector<Call> calls;
    ifstream ifs("Calls.txt");
    
    //тут надо заполнить вектор из файла, не работает
    if(ifs.is_open())
                {
                    copy(istream_iterator<Call>(ifs), istream_iterator<Call>(), back_inserter(calls));
                }
    else cerr << "Error!!";
    ifs.close();
    ofstream ofs("Calls.txt");
    char key;
    for(;;){
        do{
            cout << "1. Entry number\n";
            cout << "2. Out numbers\n";
            cout << "3. Exit\n";
            cout << "Select: ";
            cin >> key;
        }while (key <'1' || key >'3');
        switch(key){
        case '1':
            //вводим новый объект
            cin >> c;
            //добавляем его в вектор
            calls.push_back(c);
            break;
        case '2':
            //выводим весь вектор на экран
            copy(calls.begin(),calls.end(),ostream_iterator<Call>(cout));
            break;
        case '3':
            //запись вектора в файл и выход
            if(ofs) copy(calls.begin(),calls.end(),ostream_iterator<Call>(ofs));
            else cerr<<"Error!!"<<endl;
            ofs.close();
            _getch();
            return 0;
        }
    }
}
Avazart
 Аватар для Avazart
6900 / 5140 / 252
Регистрация: 10.12.2010
Сообщений: 22,588
Записей в блоге: 17
05.08.2012, 13:50     Запись и чтение вектора из файла #15
А если упростить до
C++
1
2
3
4
5
6
7
8
9
10
11
12
int main()
{
    vector<Call> calls;
    ifstream ifs("Calls.txt");
 
    if(ifs)  copy(istream_iterator<Call>(ifs), istream_iterator<Call>(), back_inserter(calls));
    else cerr << "Error!!";
 
    cout<<endl<< "size:\t"<< calls.size()<<endl;
 
return 0;
}
???
Флибустьер
 Аватар для Флибустьер
0 / 0 / 0
Регистрация: 24.01.2011
Сообщений: 12
05.08.2012, 13:54  [ТС]     Запись и чтение вектора из файла #16
Выдала
size: 0

Но не обнулила файл
Avazart
 Аватар для Avazart
6900 / 5140 / 252
Регистрация: 10.12.2010
Сообщений: 22,588
Записей в блоге: 17
05.08.2012, 13:56     Запись и чтение вектора из файла #17
Ну ошибка здесь

C++
1
2
3
4
5
6
7
8
9
10
11
12
std::ostream &operator <<(std::ostream &stream, Call c)
{
    stream << "In date: " << c.day << '.' << c.month << '.' << c.year;
    stream << " you call in number ";
    stream << '(';
    std::cout.width(3);
    std::cout.fill('0');
    stream << c.areacode << ')' << '-' << c.callNumber << ",\nlength of call ";
    stream << c.min << "min " << c.sec << "sec. Call cast ";
    stream << c.CallCast() << '\n';
    return stream;
}
Не понятно чего вы ожидали? Как должно было это потом прочитатся?
Уберите от сюда все строки-пояснения скобки итп.
grizlik78
Эксперт C++
 Аватар для grizlik78
1882 / 1414 / 101
Регистрация: 29.05.2011
Сообщений: 2,958
05.08.2012, 13:57     Запись и чтение вектора из файла #18
Цитата Сообщение от Флибустьер Посмотреть сообщение
Выдала
size: 0
И это не удивительно. Операторы потокового ввода и вывода друг-другу не соответствует. При выводе записывается большое количество информации, неожиданной для оператора ввода.
Тут надо определиться, должен ли выходной файл быть удобным для чтения человеку или машине.
Флибустьер
 Аватар для Флибустьер
0 / 0 / 0
Регистрация: 24.01.2011
Сообщений: 12
05.08.2012, 14:13  [ТС]     Запись и чтение вектора из файла #19
Операторы ввода и вывода приведены в соответствие:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
std::ostream &operator <<(std::ostream &stream, Call c)
{
    stream << c.day << c.month << c.year;
    stream << c.areacode << c.callNumber;
    stream << c.min << c.sec ;
    stream << c.payFoCall;
    return stream;
}
 
std::istream &operator >> (std::istream &stream, Call &c)
{
    stream >> c.day >> c.month >> c.year;
    stream >> c.areacode >> c.callNumber;
    stream >> c.min >> c.sec;
    stream >> c.payFoCall;
    return stream;
}
main выглядит так:
C++
1
2
3
4
5
6
7
8
vector<Call> calls;
    ifstream ifs("Calls.txt");
 
    if(ifs)  copy(istream_iterator<Call>(ifs), istream_iterator<Call>(), back_inserter(calls));
    else cerr << "Error!!";
 
    cout<<endl<< "size:\t"<< calls.size()<<endl;
    _getch();
Файл не пустой, но при чтении данные не записываются в вектор, Error!! не выводится, size = 0... После закрытия программы файл не обнуляется
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
05.08.2012, 14:17     Запись и чтение вектора из файла
Еще ссылки по теме:

C++ Запись и чтение с файла
Чтение вектора структур из файла C++
C++ Запись и чтение из файла

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

Или воспользуйтесь поиском по форуму:
Avazart
 Аватар для Avazart
6900 / 5140 / 252
Регистрация: 10.12.2010
Сообщений: 22,588
Записей в блоге: 17
05.08.2012, 14:17     Запись и чтение вектора из файла #20
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
std::ostream &operator << (const std::ostream &stream,const Call& c)
{
    stream <<  c.day       << "\t"   << c.month   << "\t"    << c.year << std::endl;
    stream <<  c.areacode  << "\t"   << c.callNumber << std::endl;
    stream <<  c.min       << "\t"   << c.sec << std::endl;
    stream <<  c.payFoCall <<endl;
 
    return stream; 
}
 
std::istream &operator >> (std::istream &stream, Call &c)
{
    stream >> c.day >> c.month >> c.year;
    stream >> c.areacode >> c.callNumber;
    stream >> c.min >> c.sec;
    stream >> c.payFoCall;
 
    return stream;
}
Yandex
Объявления
05.08.2012, 14:17     Запись и чтение вектора из файла
Ответ Создать тему
Опции темы

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