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

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

Войти
Регистрация
Восстановить пароль
 
 
Рейтинг: Рейтинг темы: голосов - 10, средняя оценка - 4.60
zerO2hacK
1 / 1 / 0
Регистрация: 06.03.2012
Сообщений: 72
#1

Считывание из файла в массив структур - C++

13.02.2013, 10:38. Просмотров 1532. Ответов 22
Метки нет (Все метки)

Доброго времени суток!

Есть структура:
C++
1
2
3
4
5
6
7
8
9
10
11
struct iDiscipline{
        char name[10];
        int num_course;
        int num_term;
        int am_lec;
        int am_pr;
        int am_lab;
        int am_one;
        int am_ALL;
        char form[1]; //e-exam || t-test
}disciplines[MAX]={'\0'};
и файл типа:
Кол-во записей: 2
Номер: |0||1|
Наименование: |mat||ter|
Номер курса; |1||1|
Номер семестра: |1||1|
Лекции (ч): |1||1|
Практика (ч): |1||1|
Лабы (ч): |1||1|
Сам.раб. (ч): |1||1|
ВСЕГО (ч): |4||4|
Форма отчета: |t||e|
и функция считывания из файла:
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
void fload(){
    clear();//чистим всю структуру
    int am=0;
    char name[10];
    cout<<"Введите имя файла - ";cin>>name;
    ifstream f;
    f.open(name);
    //
    f.seekg(16)>>am;
    //for (int i=0; i<am; i++) f.seekg(36+i)>>"| ">>i>>"  |";
    int dop=0;
    for (int i=0; i<am; i++){
        int j=0;
        do f.seekg(51+3*am+i+1)>>disciplines[i].name[j++]; while (f>>"|");
        dop+=j;
    }
    for (int i=0; i<am; i++) f.seekg(68+2*am+dop+i+1)>>disciplines[i].num_course;
    for (int i=0; i<am; i++) f.seekg(85+3*am+dop+i+1)>>disciplines[i].num_term;
    for (int i=0; i<am; i++) f.seekg(102+4*am+dop+i+1)>>disciplines[i].am_lec;
    for (int i=0; i<am; i++) f.seekg(119+5*am+dop+i+1)>>disciplines[i].am_pr;
    for (int i=0; i<am; i++) f.seekg(136+6*am+dop+i+1)>>disciplines[i].am_lab;
    for (int i=0; i<am; i++) f.seekg(153+7*am+dop+i+1)>>disciplines[i].am_one;
    for (int i=0; i<am; i++) f.seekg(170+8*am+dop+i+1)>>disciplines[i].am_ALL;
    for (int i=0; i<am; i++) f.seekg(187+9*am+dop+i+1)>>disciplines[i].form[0];
    //
    f.close();
}
Сперва думал как мне перепрыгивать ненужные слова...сразу к числам, названиям - нашел функцию tellg()...пошаманил с ней чуток.

Выбивает ошибку в этом куске:
C++
1
2
3
4
5
for (int i=0; i<am; i++){
        int j=0;
        do f.seekg(51+3*am+i+1)>>disciplines[i].name[j++]; while (f>>"|");
        dop+=j;
    }
Мол, бинарный ">>": не найден оператор, принимающий левый операнд типа "std::ifstream" (или приемлемое преобразование отсутствует).

В чем косяк то, прошу помощи

Добавлено через 3 минуты
переменная am: кол-во записей
dop: это кол-во символов в названиях дисциплин

Добавлено через 5 минут
ну и на всякий, функция записи в файл:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
void fsave(){
    char name[10];
    int am=0;
    cout<<"Введите имя файла - ";cin>>name;
    ofstream f;
    f.open(name);
    f<<"Кол-во записей: "; for (int i=0; i<MAX; i++) if (disciplines[i].name[0]) am++; f<<am<<endl;
    f<<"Номер:           "; for (int i=0; i<MAX; i++) {if (disciplines[i].name[0]) f<<"|"<<i<<"|";}
    f<<endl<<"Наименование:    "; for (int i=0; i<MAX; i++) {if (disciplines[i].name[0]) f<<"|"<<disciplines[i].name<<"|"; }
    f<<endl<<"Номер курса;     "; for (int i=0; i<MAX; i++) {if (disciplines[i].name[0]) f<<"|"<<disciplines[i].num_course<<"|";}
    f<<endl<<"Номер семестра:  "; for (int i=0; i<MAX; i++) {if (disciplines[i].name[0]) f<<"|"<<disciplines[i].num_term<<"|";}
    f<<endl<<"Лекции (ч):      "; for (int i=0; i<MAX; i++) {if (disciplines[i].name[0]) f<<"|"<<disciplines[i].am_lec<<"|"; }
    f<<endl<<"Практика (ч):    "; for (int i=0; i<MAX; i++) {if (disciplines[i].name[0]) f<<"|"<<disciplines[i].am_pr<<"|"; }
    f<<endl<<"Лабы (ч):        "; for (int i=0; i<MAX; i++) {if (disciplines[i].name[0]) f<<"|"<<disciplines[i].am_lab<<"|";}
    f<<endl<<"Сам.раб. (ч):    "; for (int i=0; i<MAX; i++) {if (disciplines[i].name[0]) f<<"|"<<disciplines[i].am_one<<"|"; }
    f<<endl<<"ВСЕГО (ч):       "; for (int i=0; i<MAX; i++) {if (disciplines[i].name[0]) f<<"|"<<disciplines[i].am_ALL<<"|";}
    f<<endl<<"Форма отчета:    "; for (int i=0; i<MAX; i++) {if (disciplines[i].name[0]) f<<"|"<<disciplines[i].form[0]<<"|";}
    f<<endl;
    f.close();
}
0
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
13.02.2013, 10:38
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Считывание из файла в массив структур (C++):

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

Считывание файла в массив и запись нового файла - C++
Консоль VS C++. Текстовый файл открывается как бинарный, и считывается по 100 байт в массив - и сразу они переписываются в другой файл. В...

Массив структур из файла - C++
#include &lt;iostream&gt; #include &lt;fstream&gt; #include &lt;conio.h&gt; #include &lt;iomanip&gt; #include &lt;stdlib.h&gt; #include &lt;cstring&gt; #include...

Массив структур из файла - C++
Помогите, пожалуйста, с поиском ошибки. Нам дан текстовый файл, из 3 столбцов и 5 строк, с разделителями в виде пробелов и новой строки -...

Считывание в массив с файла - C++
Как считать числа из файла в массив, но сделать это со второй строки? К примеру: 6 10 12 63 25 23 И мне нужно просто пропустить...

Считывание из файла в массив - C++
#include &quot;stdafx.h&quot; #include &lt;stdio.h&gt; #include &lt;iostream&gt; #include &lt;conio.h&gt; using namespace std; int main() { FILE*...

Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
alsav22
5420 / 4816 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
13.02.2013, 11:47 #2
Цитата Сообщение от zerO2hacK Посмотреть сообщение
while (f>>"|");
Это как понимать?
1
zerO2hacK
1 / 1 / 0
Регистрация: 06.03.2012
Сообщений: 72
13.02.2013, 11:57  [ТС] #3
Цитата Сообщение от alsav22 Посмотреть сообщение
Это как понимать?
ну вообще я хотел написать, что б считывалось (оно же посимвольно считывает?) до символа '|', но похоже что не правильно это...

Добавлено через 2 минуты
Цитата Сообщение от zerO2hacK Посмотреть сообщение
f.seekg(51+3*am+i+1)
блин, а здесь же получается вообще, что считывается ТОЛЬКО символ на позиции 51+3*am+i+1....ведь не меняется же это значение, и постоянно перекидывает на эту позицию.

блин...я запутался
0
alsav22
5420 / 4816 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
13.02.2013, 15:40 #4
Цитата Сообщение от zerO2hacK Посмотреть сообщение
ну вообще я хотел написать, что б считывалось (оно же посимвольно считывает?) до символа '|', но похоже что не правильно это...
В цикле считывайте символы в какую-нибудь символьную переменную и проверяйте её на равенство '|', если не равно, то помещайте символ куда надо. Если равно, то выход.

Добавлено через 3 часа 36 минут
Мой вам совет: уберите из файла все пояснения к данным("Кол-во записей:", "Номер:" и пр.) и разделители между числами('|'). Они там совершенно не нужны. Это намного упростит код. Создайте класс iDiscipline и в нём перегрузите операторы << и >> для записи в файл и чтения из файла, и в них уже пропишите: как записывать объекты класса в файл, и как читать их оттуда.
1
vua72
415 / 415 / 85
Регистрация: 28.11.2010
Сообщений: 1,183
Завершенные тесты: 1
13.02.2013, 16:15 #5
может использовать бинарный файл, со структурами так проще, да и обычно так делают.
1
zerO2hacK
1 / 1 / 0
Регистрация: 06.03.2012
Сообщений: 72
13.02.2013, 16:25  [ТС] #6
Цитата Сообщение от alsav22 Посмотреть сообщение
Создайте класс iDiscipline
лаба по структурному прогрммированию, так что без ООП

Цитата Сообщение от alsav22 Посмотреть сообщение
уберите из файла все пояснения к данным
наверно так и сделаю...что нибудь типа
"матан 1 1 1 1 1 1 4 t;прога 1 2 25 25 25 25 100 е"

Добавлено через 2 минуты
Цитата Сообщение от vua72 Посмотреть сообщение
использовать бинарный файл, со структурами так проще
что именно проще будет?
0
alsav22
5420 / 4816 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
13.02.2013, 18:20 #7
Цитата Сообщение от zerO2hacK Посмотреть сообщение
наверно так и сделаю...что нибудь типа
"матан 1 1 1 1 1 1 4 t;прога 1 2 25 25 25 25 100 е"
Только так:
матан
1
1
1
1
1
1
4
t
прога
1
2
25
25
25
25
100
e

Строку getline() считать, потом семь чисел через >> (этот оператор будет читать до '\n' ), потом строку - getline(). Кстати, зачем там массив char, если один символ? Можно просто char, и тогда читать >>.
1
vua72
415 / 415 / 85
Регистрация: 28.11.2010
Сообщений: 1,183
Завершенные тесты: 1
13.02.2013, 19:31 #8
Цитата Сообщение от zerO2hacK Посмотреть сообщение
лаба по структурному прогрммированию, так что без ООП
что именно проще будет?
в принципе, бинарный, имхо, проще. только нужно использовать для чтения метод read, а для записи - write.
Единственное, в файле вы ничего не сможете прочитать, только через свою программу. Плюс, запись и чтение всей структуры целиком одной командой. Я агитирую за бинарный )

Добавлено через 3 минуты
2 примера из Праты
Кликните здесь для просмотра всего текста
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
// binary.cpp -- бинарный файловый ввод-вывод
#include <iostream> // не требуется в большинстве систем
#include <fstream>
#include <iomanip>
#include <cstdlib> // (или stdlib.h) для exit()
inline void eatline() { while (std::cin.get() != '\n') continue; }
struct planet
{
    char name[20];      // название планеты
    double population;  // население
    double g;               // ускорение свободного падения
};
const char * file = "planets.dat";
int main()
{
    using namespace std;
    planet pl;
    cout << fixed << right;
    // показать начальное содержимое
    ifstream fin;
    fin.open(file, ios_base::in |ios_base::binary); // бинарный файл
    //Примечание: некоторые системы не принимают режим ios_base::binary
    if (fin.is_open())
    {
        cout << "Текущее содержимое файла "
              << file << ":\n";
        while (fin.read((char *) &pl, sizeof pl))
        {
            cout << setw(20) << pl.name << ": "
                  << setprecision(0) << setw(12) << pl.population
                  << setprecision(2) << setw(6) << pl.g << endl;
        }
        fin.close();
    }
    // добавить новые данные
    ofstream fout(file,
    ios_base::out | ios_base::app | ios_base::binary);
    //Примечание: некоторые системы не принимают режим ios::binary
    if (!fout.is_open())
    {
        cerr << "Не удается открыть файл " << file << " для вывода:\n";
        exit(EXIT_FAILURE);
}
    cout << "Введите название планеты (или пустую строку для завершения):\n";
    cin.get(pl.name, 20);
    while (pl.name[0] != '\0')
    {
        eatline();
        cout << "Введите численность населения планеты: ";
        cin >> pl.population;
        cout << "Введите ускорение свободного падения планеты: ";
        cin >> pl.g;
        eatline();
        fout.write((char *) &pl, sizeof pl);
        cout << "Введите название планеты (или пустую строку для завершения):\n ";
        cin.get(pl.name, 20);
    }
    fout.close();
    // показать измененный файл
    fin.clear(); // не обязательно в некоторых реализациях, но не помешает
    fin.open(file, ios_base::in | ios_base::binary);
    if (fin.is_open())
    {
        cout << "Новое содержимое файла "
              << file << ":\n";
        while (fin.read((char *) &pl, sizeof pl))
        {
            cout << setw(20) << pl.name << ": "
                  << setprecision(0) << setw(12) << pl.population
                  << setprecision(2) << setw(6) << pl.g << endl;
        }
        fin.close();
    }
    cout << "Готово.\n";
    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
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
#include <iomanip>
#include <cstdlib>      // (или stdlib.h) для exit()
const int LIM = 20;
struct planet
{
    char name[LIM];         // название планеты
    double population;  // население
    double g;               // ускорение свободного падения
};
const char * file = "planets.dat";  // ПРЕДПОЛАГАЕТСЯ, ЧТО СУЩЕСТВУЕТ                                               // (пример binary.cpp)
inline void eatline() { while (std::cin.get() != '\n') continue; }
int main()
{
    using namespace std;
planet pl;
cout << fixed;
// показать начальное содержимое
fstream finout;         // читать и писать потоки
finout.open(file,
ios_base::in | ios_base::out | ios_base::binary);
//ПРИМЕЧАНИЕ: некоторые системы Unix требуют опустить | ios::binary
int ct = 0;
if (finout.is_open())
{
    finout.seekg(0); // перейти в начало
        cout << "Текущее содержимое файла "
          << file << ":\n";
        while (finout.read((char *) &pl, sizeof pl))
        {
            cout << ct++ << ": " << setw(LIM) << pl.name << ": "
                  << setprecision(0) << setw(12) << pl.population
                  << setprecision(2) << setw(6) << pl.g << endl;
        }
        if (finout.eof())
            finout.clear(); // очистить флаг eof
        else
        {
            cerr << "Ошибка чтения " << file << ".\n";
            exit(EXIT_FAILURE);
        }
    }
    else
    {
        cerr << file << " файл не может быть открыт -- завершение.\n";
        exit(EXIT_FAILURE);
    }
    // изменить запись
    cout << "Введите номер записи, которую нужно изменить: ";
    long rec;
    cin >> rec;
eatline(); // избавиться от символов новой строки
    if (rec < 0 || rec >= ct)
    {
        cerr << "Неверный номер записи -- завершение.\n";
exit(EXIT_FAILURE);
    }
    streampos place = rec * sizeof pl;  // преобразовать в тип streampos
    finout.seekg(place);                    // произвольный доступ
    if (finout.fail())
    {
        cerr << "Ошибка при попытке перемещения указателя\n";
        exit(EXIT_FAILURE);
    }
    finout.read((char *) &pl, sizeof pl);
    cout << "Ваш выбор:\n";
    cout << rec << ": " << setw(LIM) << pl.name << ": "
          << setprecision(0) << setw(12) << pl.population
          << setprecision(2) << setw(6) << pl.g << endl;
    if (finout.eof())
        finout.clear(); // очистить флаг eof
    cout << "Введите название планеты: ";
    cin.get(pl.name, LIM);
    eatline();
    cout << "Введите население планеты: ";
    cin >> pl.population;
    cout << "Введите ускорение свободного падения: ";
    cin >> pl.g;
    finout.seekp(place);    // вернуться назад
    finout.write((char *) &pl, sizeof pl) << flush;
    if (finout.fail())
    {
        cerr << "Ошибка при попытке записи\n";
        exit(EXIT_FAILURE);
    }
    // показать измененный файл
    ct = 0;
    finout.seekg(0);        // перейти в начало файла
    cout << "Новое содержимое файла " << file
          << ":\n";
    while (finout.read((char *) &pl, sizeof pl))
    {
        cout << ct++ << ": " << setw(LIM) << pl.name << ": "
              << setprecision(0) << setw(12) << pl.population
              << setprecision(2) << setw(6) << pl.g << endl;
    }
    finout.close();
    cout << "Готово.\n";
    return 0;
}
1
alsav22
5420 / 4816 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
13.02.2013, 19:56 #9
Цитата Сообщение от vua72 Посмотреть сообщение
Я агитирую за бинарный
Чтение структуры целиком из файла в память и наоборот(без использования спецприёмов) не очень правильная вещь(а может, и совсем неправильная). Есть такое понятие - выравнивание. http://www.kalinin.ru/programming/cpp/31_07_00.shtml
http://habrahabr.ru/post/142662/
1
zerO2hacK
1 / 1 / 0
Регистрация: 06.03.2012
Сообщений: 72
13.02.2013, 23:26  [ТС] #10
Цитата Сообщение от alsav22 Посмотреть сообщение
Кстати, зачем там массив char, если один символ?
имеешь ввиду поле char form[1]? блин. даже не знаю зачем так написал...видимо мне так привычнее было.
как исправлю всё, следуя вашим рекомендациям, отпишусь

Добавлено через 1 минуту
Цитата Сообщение от alsav22 Посмотреть сообщение
Строку getline() считать
т.е. считывание из файла можно с помощью getline() сделать?

Добавлено через 13 секунд
всмысле строки

Добавлено через 2 часа 53 минуты
Цитата Сообщение от zerO2hacK Посмотреть сообщение
т.е. считывание из файла можно с помощью getline() сделать?
извиняюсь за тупость
0
alsav22
5420 / 4816 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
13.02.2013, 23:35 #11
Цитата Сообщение от zerO2hacK Посмотреть сообщение
т.е. считывание из файла можно с помощью getline() сделать?
Нужно. >> читает до пробельного символа, т.е. если строка из нескольких слов, то считает только первое.
1
zerO2hacK
1 / 1 / 0
Регистрация: 06.03.2012
Сообщений: 72
14.02.2013, 00:05  [ТС] #12
C++
1
2
3
4
5
6
7
8
9
10
11
for (int i=0; f.eof(); i++){
        f.getline(disciplines[i].name,10);//считываем строку
        f>>disciplines[i].num_course;;
        f>>disciplines[i].num_term;
        f>>disciplines[i].am_lec;
        f>>disciplines[i].am_pr;
        f>>disciplines[i].am_lab;
        f>>disciplines[i].am_one;
        f>>disciplines[i].am_ALL;
        f>>disciplines[i].form;
    }
не считывает((

Добавлено через 3 минуты
пробывал getline() по другому запустить - getline(f,disciplines[i].name) - ваще не компилится

Добавлено через 5 минут
Цитата Сообщение от alsav22 Посмотреть сообщение
через >> (этот оператор будет читать до '\n' )
а потом перекидывает на следующую строчку?

Добавлено через 2 минуты
ооо!! что то считало))
0
alsav22
5420 / 4816 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
14.02.2013, 00:05 #13
Цитата Сообщение от zerO2hacK Посмотреть сообщение
пробывал getline() по другому запустить - getline(f,disciplines[i].name) - ваще не компилится
Так в string читать нужно, поэтому и не компилится. А в файле что?
1
zerO2hacK
1 / 1 / 0
Регистрация: 06.03.2012
Сообщений: 72
14.02.2013, 00:06  [ТС] #14
Цитата Сообщение от zerO2hacK Посмотреть сообщение
for (int i=0; f.eof(); i++){
здесь не добавил "!" перед f.eof(), т.е.
C++
1
for (int i=0; !f.eof(); i++)
Добавлено через 31 секунду
Цитата Сообщение от alsav22 Посмотреть сообщение
А в файле что?
matan
1
1
1
1
1
1
4
t
eqw
1
2
25
25
25
1
76
e
0
alsav22
5420 / 4816 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
14.02.2013, 00:12 #15
Цитата Сообщение от zerO2hacK Посмотреть сообщение
здесь не добавил "!" перед f.eof()
Сейчас читает?

Добавлено через 2 минуты
Цитата Сообщение от zerO2hacK Посмотреть сообщение
а потом перекидывает на следующую строчку?
При следующем чтении пропустит '\n' и будет читать до следующего стандартного пробельного символа (в данном коде до '\n').
1
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
14.02.2013, 00:12
Привет! Вот еще темы с ответами:

Считывание из файла в массив - C++
Задание: Дан в файл в котором записана матрица вершин, необходимых для создания 3D фигуры. Написать программу, которая считывает данную...

Считывание файла в массив - C++
Здравствуйте Мне была поставлена задача сделать рандомный выбор строк из файла. И я не знаю как считать из файла строки в массив что бы к...

Заполнить из файла массив структур - C++
задача такая файле есть данные которые имеют Количество строк: 5. Столбцы: Фамилия, Место жительства, Год рождения. Определить ...

Считать массив структур из файла - C++
Видела похожие темы, но так и не дошло:( В общем, количество структур в файле мне известно. Нужно считать их в массив. Проблема в том,...


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

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

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