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

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
 
Рейтинг: Рейтинг темы: голосов - 10, средняя оценка - 4.80
Флибустьер
0 / 0 / 0
Регистрация: 24.01.2011
Сообщений: 12
#1

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

02.08.2012, 13:48. Просмотров 1282. Ответов 20
Метки нет (Все метки)

Здравствуйте! Помогите понять ошибку. Создаю группу, записываю ее в файл (первым в файл записывается непонятный символ). Первый запуск нормальный, файл создается, но при повторном группа дописывается, а вот уже на функции 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);
}
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
02.08.2012, 13:48
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Запись и чтение вектора из файла (C++):

Запись и чтение вектора из файла - C++
Здравствуйте! Вот небольшая прога которая пишет в вектор структуру... при повторном запуске она читает с файла в вектор и по идее можно...

Запись/чтение вектора в/из файла.Структуры - C++
Доброе время суток.Проблема заключается в следующем: в файл идет запись вектора (запись вроде-бы успешна,насколько я могу судить).После...

Запись вектора uin8_t в бинарный файл и обратное чтение из файла - C++
Здравствуйте. Есть std::vector&lt;uint8_t&gt;. Нужно записать все элементы в бинарный файл, а затем считать обратно из файла в...

Чтение вектора структур из файла - C++
struct TRANSACTIONS { unsigned long long sender; unsigned long long receiver; unsigned long long amount; } ... ...

Вектора и чтение из файла и обратно (File IO) - C++
Ребят! Помогите как сможете! Я никак не могу связать перечисления между собой( И еще никак не могу сделать так, чтобы каждый раз, когда...

Запись и чтение с файла - C++
Есть названия машин, их цена и производитель. Нужно сделать программу, которая при вводе производителя выводит название машины и её цены. ...

20
Avazart
Эксперт С++
7213 / 5385 / 286
Регистрация: 10.12.2010
Сообщений: 23,808
Записей в блоге: 17
02.08.2012, 14:19 #2
Режит глаз использование Си-строк и сишних функций и fopen() наряду с STL.

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

Зачем перегружать операторы >> и << если не использовать их при выводе в файл ( а не только на экран)
0
grizlik78
Эксперт С++
1957 / 1450 / 116
Регистрация: 29.05.2011
Сообщений: 3,012
02.08.2012, 14:35 #3
И какой результат ожидается при использовании sizeof(N)?
0
Avazart
Эксперт С++
7213 / 5385 / 286
Регистрация: 10.12.2010
Сообщений: 23,808
Записей в блоге: 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 / 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 */
Запись имени студента. Или нет? Я с работой с файлами плохо пока знаком, написал, что мог
0
grizlik78
Эксперт С++
1957 / 1450 / 116
Регистрация: 29.05.2011
Сообщений: 3,012
02.08.2012, 15:09 #6
Цитата Сообщение от Флибустьер Посмотреть сообщение
Узнать размер хранимых данных и перейти на новую строку?
sizeof(N) возвращает количество байт, необходимых для представления переменной N. То есть это размер типа int, который равен, как правило, четырём, независимо от значения N.
0
Avazart
Эксперт С++
7213 / 5385 / 286
Регистрация: 10.12.2010
Сообщений: 23,808
Записей в блоге: 17
02.08.2012, 15:11 #7
fprintf - текстовый и вообще зачем там \t ?

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

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

Да и обязательно ли использовать бинарный режим с файлом ?
0
Флибустьер
0 / 0 / 0
Регистрация: 24.01.2011
Сообщений: 12
02.08.2012, 15:25  [ТС] #10
Цитата Сообщение от Avazart Посмотреть сообщение
Да и обязательно ли использовать бинарный режим с файлом ?
Нет, не критично. Шилдта обязательно гляну, думал в инете найти информацию
0
Avazart
Эксперт С++
7213 / 5385 / 286
Регистрация: 10.12.2010
Сообщений: 23,808
Записей в блоге: 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;
}
//---------------------------------------------------------------------------
1
Флибустьер
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;
        }
 
    }
 
}
И тут я столкнулся с магией... Программа записывает в файл данные из вектора, но при повторном запуске, вместо того, чтобы считать данные из файла и занести их в вектор, она удаляет данные из файла, в вектор ничего не попадает. Где я ошибся?
0
Avazart
Эксперт С++
7213 / 5385 / 286
Регистрация: 10.12.2010
Сообщений: 23,808
Записей в блоге: 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 / 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;
        }
    }
}
0
Avazart
Эксперт С++
7213 / 5385 / 286
Регистрация: 10.12.2010
Сообщений: 23,808
Записей в блоге: 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
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
05.08.2012, 13:50
Привет! Вот еще темы с ответами:

Запись и чтение с файла - C++
Здравствуйте,помогите пожалуйста ..есть две структуры, но каждая записывается и считывается с разных файлов, не посоветует как можно...

Запись и чтение из файла - C++
Доброго время суток! Так от балди решыл набросать прогу которая создаёт файл записывает туда 11 рандомных чисел,потом з помощю ifstream я...

Запись и чтение из файла - C++
Всем добрый вечер, как можно записать данные в файл? Например записать в txt файл список паролей. На одном сайте нашел информацию по...

Запись и чтение с файла - C++
Подскажите пожалуйста как правильно записать массив в файл и считать его оттуда в другой массив? Если можно пример кода не в чистом с,а...


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

Или воспользуйтесь поиском по форуму:
15
Yandex
Объявления
05.08.2012, 13:50
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru