Форум программистов, компьютерный форум, киберфорум
Наши страницы
С++ для начинающих
Войти
Регистрация
Восстановить пароль
 
Рейтинг 5.00/6: Рейтинг темы: голосов - 6, средняя оценка - 5.00
Lim0n
0 / 0 / 0
Регистрация: 19.11.2015
Сообщений: 16
1

Написать структуру "Список книг" (бинарный файловый ввод/вывод)

30.12.2015, 13:41. Просмотров 1096. Ответов 9
Метки нет (Все метки)

Здравствуйте, Дорогие форумчане! Всех с наступающим.

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

Мое приложение без проблем записывает данные в файл текстовом режиме, но если добавить заветную b, то в текстовом файле просто напросто стираются абзацы (это не очень похоже на двоичный режим), при чтении вместо списка выводится только первый элемент списка.

пожалуйста скажите что нужно поправить!

исходный код (для записи):
Кликните здесь для просмотра всего текста

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
#include "stdafx.h"
#include <clocale>
#include <stdio.h>
#include <tchar.h>
#include <conio.h>
#include <stdlib.h>
#include <string.h>
struct BookList // Структура "книга"
{
    char Author[64];
    char Title[128];
    char Firm[64];
    int year;
    int page;
    BookList *pNext, *pPred;
};
 
// Функция добавляет элемент в двухсвязный кольцевой список (в начало или в конец)
void add(BookList *&pF, BookList *p, bool first)
{ // Если first равен true, то элемент будет первым
    if (pF == 0) // Список пуст
    {
        pF = p->pNext = p->pPred = p;
        return;
    }
    p->pNext = pF;
    p->pPred = pF->pPred;
    pF->pPred->pNext = p;
    pF->pPred = p;
    if (first) pF = p; // Элемент будет первым
}
 
int main(int argc, char* argv[])
{
    setlocale(LC_ALL, "rus");
    BookList *pF = 0, *p;
    char Cont;  // Переменная для ввода условия продолжения ввода
    do    // Ввод списка
    {
        p = new BookList; // Выделяем память
        printf("\n");
        printf("Введите Автора: ");
        printf("\n");
        fflush(stdin);
        gets_s(p->Author);
        printf("Введите Название: ");
        printf("\n");
        fflush(stdin);
        gets_s(p->Title);
        printf("Введите Издательство: ");
        printf("\n");
        fflush(stdin);
        gets_s(p->Firm);
        printf("Введите год: ");
        printf("\n");
        scanf_s("%d", &p->year);
        printf("Введите количество страниц: ");
        printf("\n");
        scanf_s("%d", &p->page);
        add(pF, p, false); // Добавляю элемент в конец списка
        printf("Нажмите Enter, чтобы добавить еще одного сотруднка");
        Cont = _getch();    // Чтение кода клавиши с печатью символа
        printf("\n");
    } while (Cont == 13);
 
    FILE *pFile;
    fopen_s(&pFile, "MyBook.dat", "w");
    BookList *pi = pF;
    do
    {
        fprintf(pFile, "%s\n", pi->Author);
        fprintf(pFile, "%s\n", pi->Title);
        fprintf(pFile, "%s\n", pi->Firm);
        fprintf(pFile, "%d\n", pi->year);
        fprintf(pFile, "%d\n", pi->page);
        fprintf(pFile, "\n");
        pi = pi->pNext;
    } while (pi != pF);
    
    fclose(pFile); // Закрываем файл
    system("pause"); // Останавливаем программу, ждем нажатия любой клавиши
    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
#include "stdafx.h"
 
struct BookList // Структура "книга"
{
    char Author[64];
    char Title[128];
    char Firm[64];
    int year;
    int page;
    BookList *pNext, *pPred;
};
 
// Функция добавляет элемент в двухсвязный кольцевой список (в начало или в конец)
void add(BookList *&pF, BookList *p, bool first)
{ // Если first равен true, то элемент будет первым
    if (pF == 0) // Список пуст
    {
        pF = p->pNext = p->pPred = p;
        return;
    }
    p->pNext = pF;
    p->pPred = pF->pPred;
    pF->pPred->pNext = p;
    pF->pPred = p;
    if (first) pF = p; // Элемент будет первым
}
 
/*void add(BookList *&pF, BookList *p)  //Раннее при использований этой функции в более простой программе, список выводился в обратном порядке
{
    p->pNext = pF;
    pF = p;
}*/
 
int main(int argc, char* argv[])
{
    FILE *pFile;
    fopen_s(&pFile, "MyBook.dat", "r");
    setlocale(LC_ALL, "rus");
    BookList *pF = 0, *p;
    do  // чтение списка
    {
        p = new BookList; // Выделяем память
        //fflush(stdin);
        fgets(p->Author, 64, pFile);
        //fflush(stdin);      //я сомневаюсь в необходимости сброса буферов
        fgets(p->Title, 64, pFile);
        //fflush(stdin);
        fgets(p->Firm, 64, pFile);
        fscanf_s(pFile, "%d", &p->year);
        fscanf_s(pFile, "%d", &p->page);
        add(pF, p, false); // Добавляю элемент в конец списка
        p = p->pNext;
    } while (p != pF);
 
    
    //BookList *pi = pF;
    do
    {
        printf("%s", p->Author);
        printf("%s", p->Title);
        printf("%s", p->Firm);
        printf("%d\n", p->year);
        printf("%d\n", p->page);
        printf("\n");
        p = p->pNext;
    } while (p != pF);
 
    fclose(pFile); // Закрываем файл
    system("pause"); // Останавливаем программу, ждем нажатия любой клавиши
    return 0;
}
0
Лучшие ответы (1)
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
30.12.2015, 13:41
Ответы с готовыми решениями:

Решить задачу на файловый ввод/вывод (игра "Города")
Не могу понять задачу и решить её на Си!!! Срочно! Дело в том что я сейчас на...

Структура "Телефонная книга", файловый ввод/вывод
#define _CRT_SECURE_NO_WARNINGS #include&lt;iostream&gt; #include&lt;cstdio&gt;...

Найти причины возникновения ошибки "out of range" (файловый ввод/вывод)
if(READ) { char text2; std::ifstream *file=new std::ifstream(&quot;Rec.txt&quot;);...

Исправить ошибку "can't open input file" (файловый ввод/вывод)
в программе прописан параметр - название текстового файла pushkin.txt...

Файловый ввод/вывод: в строке поменять местами слова, разделенные союзом "и"
Задача такая : для заданной строки S поменять местами слова, разделенные союзом...

9
Hikari
Хитрая блондиночка $)
1451 / 963 / 399
Регистрация: 21.12.2015
Сообщений: 3,785
30.12.2015, 13:48 2
Лучший ответ Сообщение было отмечено Lim0n как решение

Решение

Бинарный файл нужно записывать так:
C
1
2
3
4
5
6
7
8
9
FILE *pFile;
    fopen_s(&pFile, "MyBook.dat", "w");
    BookList *pi = pF;
    do
    { 
        fwrite(pi,sizeof(BookList ),1,pFile);
        pi = pi->pNext;
    } while (pi != pF);
    fclose(pFile); // Закрываем файл
Ну и считывать:
C
1
2
3
4
5
6
7
8
9
    fopen_s(&pFile, "MyBook.dat", "r");
    BookList *pi;
    while(!feof(pFile))
    { 
        pi = new BookList;
        fread(pi,sizeof(BookList ),1,pFile);
        pi=... Тут уже вставляем в список.
    } 
    fclose(pFile); // Закрываем файл
Примерно так тогда получится работа с двоичными данными
2
Lim0n
0 / 0 / 0
Регистрация: 19.11.2015
Сообщений: 16
30.12.2015, 18:40  [ТС] 3
Hikari, спасибо за помощь, правда я не очень понял, не очень понял строчку:
pi=... Тут вставляем в список
поэтому вызвал на месте этой строки функцию void add и в обоих приложениях при открытии файлов третий к третьему параметру дописывал b (для двоичного режима)
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
BookList *pi;
    while (!feof(pFile))
    {
        pi = new BookList;
        fread(pi, sizeof(BookList), 1, pFile);
        add(pF, pi, false); // Добавляю элемент в конец списка
    }
    p = pF;
    do
    {
        printf("%s\n", p->Author);
        printf("%s\n", p->Title);
        printf("%s\n", p->Firm);
        printf("%d\n", p->year);
        printf("%d\n", p->page);
        printf("\n");
        p = p->pNext;
    } while (p != pF);
в результате выводится список (полностью и в правильном порядке) и мусор.
прикрепляю скрин консольки и MyBook.dat
0
Миниатюры
Написать структуру "Список книг" (бинарный файловый ввод/вывод)  
Вложения
Тип файла: rar MyBook.rar (199 байт, 1 просмотров)
Hikari
Хитрая блондиночка $)
1451 / 963 / 399
Регистрация: 21.12.2015
Сообщений: 3,785
30.12.2015, 19:37 4
Цитата Сообщение от Lim0n Посмотреть сообщение
не очень понял строчку
Ты как раз все правильно понял
А насчет мусора... ну подчищай нулями перед записью с помошью
C
1
2
p = new BookList;
memset(p,0,sizeof(BookList));
там, где у тебя ввод данных в элемент списка.
2
Lim0n
0 / 0 / 0
Регистрация: 19.11.2015
Сообщений: 16
30.12.2015, 22:05  [ТС] 5
Hikari, большое спасибо очень помог.

Прикрепляю готовые исходные коды для будущих нуждающихся)

Запись в файл:
Кликните здесь для просмотра всего текста

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
#include "stdafx.h"
#include <clocale>
#include <stdio.h>
#include <tchar.h>
#include <conio.h>
#include <stdlib.h>
#include <string.h>
 
struct BookList // Структура "книга"
{
    char Author[64];
    char Title[128];
    char Firm[64];
    int year;
    int page;
    BookList *pNext, *pPred;
};
 
// Функция добавляет элемент в двухсвязный кольцевой список (в начало или в конец)
void add(BookList *&pF, BookList *p, bool first)
{ // Если first равен true, то элемент будет первым
    if (pF == 0) // Список пуст
    {
        pF = p->pNext = p->pPred = p;
        return;
    }
    p->pNext = pF;
    p->pPred = pF->pPred;
    pF->pPred->pNext = p;
    pF->pPred = p;
    if (first) pF = p; // Элемент будет первым
}
 
int main(int argc, char* argv[])
{
    setlocale(LC_ALL, "rus");
    BookList *pF = 0, *p;
    char Cont;  // Переменная для ввода условия продолжения вводаf
    do    // Ввод списка
    {
        p = new BookList; // Выделяем память
        printf("\n");
        printf("Введите Автора: ");
        printf("\n");
        fflush(stdin);
        gets_s(p->Author);
        printf("Введите Название: ");
        printf("\n");
        fflush(stdin);
        gets_s(p->Title);
        printf("Введите Издательство: ");
        printf("\n");
        fflush(stdin);
        gets_s(p->Firm);
        printf("Введите год: ");
        printf("\n");
        scanf_s("%d", &p->year);
        printf("Введите количество страниц: ");
        printf("\n");
        scanf_s("%d", &p->page);
        add(pF, p, false); // Добавляю элемент в конец списка
        printf("Нажмите Enter, чтобы добавить еще одного сотруднка");
        Cont = _getch();    // Чтение кода клавиши с печатью символа
        printf("\n");
    } while (Cont == 13);
 
    FILE *pFile;
    fopen_s(&pFile, "MyBook.dat", "wb");
    BookList *pi = pF;
    do
    {
        fwrite(pi, sizeof(BookList), 1, pFile);
        pi = pi->pNext;
    } while (pi != pF);
    
    fclose(pFile); // Закрываем файл
    _getche(); // Останавливаем программу, ждем нажатия любой клавиши
    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
#include "stdafx.h"
#include <clocale>
#include <stdio.h>
#include <tchar.h>
#include <conio.h>
#include <stdlib.h>
#include <string.h>
 
struct BookList // Структура "книга"
{
    char Author[64];
    char Title[128];
    char Firm[64];
    int year;
    int page;
    BookList *pNext, *pPred;
};
 
// Функция добавляет элемент в двухсвязный кольцевой список (в начало или в конец)
void add(BookList *&pF, BookList *p, bool first)
{ // Если first равен true, то элемент будет первым
    if (pF == 0) // Список пуст
    {
        pF = p->pNext = p->pPred = p;
        return;
    }
    p->pNext = pF;
    p->pPred = pF->pPred;
    pF->pPred->pNext = p;
    pF->pPred = p;
    if (first) pF = p; // Элемент будет первым
}
 
vint main(int argc, char* argv[])
{
    FILE *pFile;
    fopen_s(&pFile, "MyBook.dat", "rb");
    setlocale(LC_ALL, "rus");
    BookList *pF = 0, *p;
    BookList *pi;
    while (!feof(pFile))
    {
        pi = new BookList;
        memset(pi, 0, sizeof(BookList));    // Заменяет "мусор" на нули
        fread(pi, sizeof(BookList), 1, pFile);
        add(pF, pi, false); // Добавляю элемент в конец списка
    }
 
    p = pF;
    do
    {
        if ((p->Author != 0) && (p->Title != 0) && (p->Firm != 0) && (p->year != 0) && (p->page!=0))    // "не печать" нулей созданных функцией memset()
        {
            printf("%s\n", p->Author);
            printf("%s\n", p->Title);
            printf("%s\n", p->Firm);
            printf("%d\n", p->year);
            printf("%d\n", p->page);
            printf("\n");   
        }
        p = p->pNext;
    } while (p != pF);
 
    fclose(pFile); // Закрываем файл
    system("pause"); // Останавливаем программу, ждем нажатия любой клавиши
    return 0;
}
0
Hikari
Хитрая блондиночка $)
1451 / 963 / 399
Регистрация: 21.12.2015
Сообщений: 3,785
30.12.2015, 22:31 6
Цитата Сообщение от Lim0n Посмотреть сообщение
очень помог
По-мо-гла

P.S. Надо что ли в подписи как-то обозначиться, а то народ окончания ставит неверно
1
GbaLog-
30.12.2015, 23:26
  #7

Не по теме:

Hikari, Я сразу догадался, когда 1-й раз вас увидел на форуме, не знаю как. :D

0
Hikari
31.12.2015, 09:24
  #8

Не по теме:

Цитата Сообщение от makfak Посмотреть сообщение
не знаю как.
Действительно, как? По улыбающемуся личику Бёрди наверное :hihi:

0
GbaLog-
31.12.2015, 13:27
  #9

Не по теме:

Hikari, Кто у вас там на аватарке улыбается я, конечно, не в курсе, но скорее всего по аватарке. :)

0
Lim0n
0 / 0 / 0
Регистрация: 19.11.2015
Сообщений: 16
02.01.2016, 20:12  [ТС] 10
ой прости
0
02.01.2016, 20:12
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
02.01.2016, 20:12

Записать в бинарный файл массив объектов Student (бинарный файловый ввод/вывод)
Здравствуйте. Стоит задача записать в бинарный файл массив объектов student:...

Поиск в массиве объектов типа "Student" по заданному полю (файловый ввод/вывод)
Здравствуйте. Стоит такая задача: Создать структуру «студент» со следующими...

Поиск в массиве объектов типа "Student" по заданному полю (файловый ввод/вывод)
Помогите написать программу 1. Файл содержит итоги контрольного срока, каждая...


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

Или воспользуйтесь поиском по форуму:
10
Ответ Создать тему
Опции темы

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