Модераторы: bsa
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Чтение и вывод файла в С, последняя запись выводится два раза 
V
    Опции темы
Crafty
Дата 5.7.2009, 20:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 319
Регистрация: 3.11.2008

Репутация: 12
Всего: 14



Начал изучать работу с файлами и возникла проблема. Почему-то в следующем примере, когда я ввожу самую последнию запись(100-ую) в файл, то при выводе на консоль содержимого файла она выводиться два раза.
Код

#include <stdio.h>

struct clientData {
    int acctNum;
    char lastName[15];
    char firstName[10];
    double balance;
};

void New(void);
void Add(void);
void Read(void);
int enterChoise(void);

int main()
{
    int choise;

    while( (choise = enterChoise()) != 4) {
        switch ( choise ) {
            case 1:
                New();
                break;
            case 2:
                Add();
                break;
            case 3:
                Read();
                break;
        }
    }
    return 0;
}

void New(void)
{
    FILE *cfPtr;
    int i;
    struct clientData blankClient = { 0, "", "", 0.0};

    if((cfPtr = fopen("credit.dat", "w")) == NULL)
        printf("File could not be open\n");
    else {
        for(i = 1; i <= 100; i++)
            fwrite(&blankClient,
                    sizeof(struct clientData), 1, cfPtr);
        fclose(cfPtr);
    }
}

void Add(void)
{
    FILE *cfPtr;
    struct clientData client = { 0, "", "", 0.0};

    if((cfPtr = fopen("credit.dat", "r+")) == NULL)
        printf("File could not be open\n");
    else {
        printf("Enter account number"
            " (1 to 100, 0 to end input)\n?");
        scanf("%d", &client.acctNum);

        while( client.acctNum != 0){
            printf("Enter lastname, firstname, balance\n?");
            fscanf(stdin, "%s%s%lf", client.lastName,
                client.firstName, &client.balance);
            fseek(cfPtr, (client.acctNum - 1) * sizeof(struct clientData), SEEK_SET);
            fwrite(&client, sizeof(struct clientData), 1,cfPtr);
            printf("Enter account number\n?");
            scanf("%d", &client.acctNum);
        }
        fclose(cfPtr);
    }
}

void Read(void)
{
    FILE *cfPtr;
    struct clientData client = { 0, "", "", 0.0};

    if((cfPtr = fopen("credit.dat", "r")) == NULL)
        printf("File could not be open\n");
    else {
        printf("%-6s%-16s%-11s%10s\n", "Acct", "Last Name",
                "First Name", "Balance");

        while(!feof(cfPtr)) { /* <---------------------- думаю проблема в этом месте*/
            fread(&client, sizeof( struct clientData), 1, cfPtr);
            if (client.acctNum != 0)
                printf("%-6d%-16s%-11s%10.2f\n",
                client.acctNum, client.lastName,
                client.firstName, client.balance);
        }
        fclose(cfPtr);
    }
    
}

int enterChoise(void)
{
    int menuChoise;

    printf("\nEnter your choise\n"
        "1 - create new file\n"
        "2 - add record\n"
        "3 - read file\n"
        "4 - end program\n?");
    scanf("%d", &menuChoise);
    return menuChoise;
}



И еще не могу понять почему иногда в файл записывается какой-то мусор.
PM MAIL   Вверх
jonie
Дата 5.7.2009, 21:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 5613
Регистрация: 21.8.2005
Где: Владимир

Репутация: 6
Всего: 118



везде где читаете-пишите делайте это в бинарном режиме. например "rb" режим.

Это поможет в решении проблем.


--------------------
Что-то не поняли? -> Напейтесь до зеленых человечков... эта сверхцивилизация Вам поможет...
PM MAIL Jabber   Вверх
Crafty
Дата 5.7.2009, 22:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 319
Регистрация: 3.11.2008

Репутация: 12
Всего: 14



jonie, Поменял везде на бинарный режим, но проблема осталась. Все также выводиться два раза подряд последняя запись в файле.
Вот скриншот
user posted image
Код

#include <stdio.h>

struct clientData {
    int acctNum;
    char lastName[15];
    char firstName[10];
    double balance;
};

void New(void);
void Add(void);
void Read(void);
int enterChoise(void);

int main()
{
    int choise;

    while( (choise = enterChoise()) != 4) {
        switch ( choise ) {
            case 1:
                New();
                break;
            case 2:
                Add();
                break;
            case 3:
                Read();
                break;
        }
    }
    return 0;
}

void New(void)
{
    FILE *cfPtr;
    int i;
    struct clientData blankClient = { 0, "", "", 0.0};

    if((cfPtr = fopen("credit.dat", "wb")) == NULL)
        printf("File could not be open\n");
    else {
        for(i = 1; i <= 100; i++)
            fwrite(&blankClient,
                    sizeof(struct clientData), 1, cfPtr);
        fclose(cfPtr);
    }
}

void Add(void)
{
    FILE *cfPtr;
    struct clientData client = { 0, "", "", 0.0};

    if((cfPtr = fopen("credit.dat", "r+b")) == NULL)
        printf("File could not be open\n");
    else {
        printf("Enter account number"
            " (1 to 100, 0 to end input)\n?");
        scanf("%d", &client.acctNum);

        while( client.acctNum != 0){
            printf("Enter lastname, firstname, balance\n?");
            fscanf(stdin, "%s%s%lf", client.lastName,
                client.firstName, &client.balance);
            fseek(cfPtr, (client.acctNum - 1) * sizeof(struct clientData), SEEK_SET);
            fwrite(&client, sizeof(struct clientData), 1,cfPtr);
            printf("Enter account number\n?");
            scanf("%d", &client.acctNum);
        }
        fclose(cfPtr);
    }
}

void Read(void)
{
    FILE *cfPtr;
    struct clientData client = { 0, "", "", 0.0};

    if((cfPtr = fopen("credit.dat", "rb")) == NULL)
        printf("File could not be open\n");
    else {
        printf("%-6s%-16s%-11s%10s\n", "Acct", "Last Name",
                "First Name", "Balance");

        while(!feof(cfPtr)) {
            fread(&client, sizeof( struct clientData), 1, cfPtr);
            if (client.acctNum != 0)
                printf("%-6d%-16s%-11s%10.2f\n",
                client.acctNum, client.lastName,
                client.firstName, client.balance);
        }
        fclose(cfPtr);
    }
    
}

int enterChoise(void)
{
    int menuChoise;

    printf("\nEnter your choise\n"
        "1 - create new file\n"
        "2 - add record\n"
        "3 - read file\n"
        "4 - end program\n?");
    scanf("%d", &menuChoise);
    return menuChoise;
}


PM MAIL   Вверх
Crafty
Дата 5.7.2009, 23:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 319
Регистрация: 3.11.2008

Репутация: 12
Всего: 14



Упростил пример, записываю в файл две тройки, а выводится на консоль три тройки. С чем это связано и как можно исправить?
Код

#include <stdio.h>

int main()
{
    FILE *fPtr;
    int i, number = 3;

    if ((fPtr = fopen("credit.dat", "wb")) == NULL)
        printf("File could not be opened\n");
    else {
        for(i = 1; i <= 2; i++)
            fwrite(&number, sizeof(number), 1, fPtr);
        fclose(fPtr);
    }

    if ((fPtr = fopen("credit.dat", "rb")) == NULL)
        printf("File could not be opened\n");
    else {
        printf("Numbers\n");

        while(!feof(fPtr)) {
            fread(&number, sizeof(number), 1, fPtr);
            printf("%d\n", number);
        }
        fclose(fPtr);
    }

    return 0;
}

PM MAIL   Вверх
Crafty
Дата 5.7.2009, 23:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 319
Регистрация: 3.11.2008

Репутация: 12
Всего: 14



Нашел решение проблемы  smile 

Код

    while(!feof(fPtr)) {
            if(fread(&number, sizeof(number), 1, fPtr) != 0)
                printf("%d\n", number);
        }


Теперь все как надо работает.

PS

Плохо что в книге об это ничего не сказано, а дан просто пример который некорректно работает.

Это сообщение отредактировал(а) Crafty - 5.7.2009, 23:59
PM MAIL   Вверх
zim22
Дата 6.7.2009, 08:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


depict1
****


Профиль
Группа: Завсегдатай
Сообщений: 2682
Регистрация: 15.1.2009
Где: Украина

Репутация: 29
Всего: 69



Цитата(Crafty @  5.7.2009,  23:50 Найти цитируемый пост)
но, а дан просто пример который некорректно работает

что за книга? не пора ли её выкинуть?


--------------------
PM MAIL   Вверх
xvr
Дата 6.7.2009, 14:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

Репутация: 35
Всего: 223



feof возвращает признак 'Конца файла'. Этот признак устанавливается, когда делается попытка прочесть данные ПОСЛЕ последних данных в файле. Т.е. после НЕУСПЕШНОГО вызова любой функции ввода (в том числе и fread)
Т.е. для своевременного определения конца файла надо проверять результат fread, feof уже можно и не вызывать  smile 
PM MAIL   Вверх
Crafty
Дата 6.7.2009, 15:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 319
Регистрация: 3.11.2008

Репутация: 12
Всего: 14



Цитата(zim22 @  6.7.2009,  08:08 Найти цитируемый пост)
что за книга? не пора ли её выкинуть?
 "Как программировать на С" Дейтел & Дейтел.



xvr, Спасибо теперь стало понятней.
PM MAIL   Вверх
zim22
Дата 7.7.2009, 17:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


depict1
****


Профиль
Группа: Завсегдатай
Сообщений: 2682
Регистрация: 15.1.2009
Где: Украина

Репутация: 29
Всего: 69



Цитата(Crafty @  6.7.2009,  15:11 Найти цитируемый пост)
 "Как программировать на С" Дейтел & Дейтел.

нормальные у них книги.  smile 


--------------------
PM MAIL   Вверх
Crafty
Дата 7.7.2009, 17:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 319
Регистрация: 3.11.2008

Репутация: 12
Всего: 14



Цитата(zim22 @  7.7.2009,  17:01 Найти цитируемый пост)
Цитата(Crafty @  6.7.2009,  15:11 ) "Как программировать на С" Дейтел & Дейтел.нормальные у них книги.   

Стоит продолжать читать? а то я не совсем понял  smile 
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "C/C++: Для новичков"
JackYF
bsa

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, JackYF, bsa.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Для новичков | Следующая тема »


 




[ Время генерации скрипта: 0.1053 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.