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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> fread() и fwrite() 
V
    Опции темы
ressac
Дата 13.4.2009, 17:15 (ссылка)    | (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

Репутация: нет
Всего: 1



Код

 void insertarEnOrden(char nombre[],TPersona per, int nelem){
     FILE * f;
     TPersona p;
     int enc = 0,pos = 0,i;

     f = fopen(nombre,"r+b");
     if(f==NULL)
        puts("Error de apertura\n");
     else{

         fread(&p,sizeof(TPersona),1,f);
         while(!feof(f)&&!enc){
             if(per.edad < p.edad){
                enc = 1;
             }else{
                fread(&p,sizeof(TPersona),1,f);
                pos++;
             }
         }
     }

     for(i=nelem-1;i>=pos;i--){
        printf("\n\n %i",ftell(f));
        fseek(f,sizeof(TPersona)*i,SEEK_SET);
        printf("\n\n %i",ftell(f));
        fread(&p,sizeof(TPersona),1,f);
        printf("\n\n %i",ftell(f));
        fseek(f,sizeof(TPersona)*(i+1),SEEK_SET); //не понимаю зачем?
        printf("\n\n %i",ftell(f));
        fwrite(&p,sizeof(TPersona),1,f);
        printf("\n\n %i",ftell(f));
     }

     puts("\n\n");

     //Escribo la nueva persona en el fichero en la posicion pos
     fseek(f,sizeof(TPersona)*pos,SEEK_SET);
     fwrite(&per,sizeof(TPersona),1,f);
     fclose(f);
}


не понимаю зачем эта операция? если после предыдущего fread() указатель сместился куда надо, это видно при помощии fteel(), но ВОТ если убрать этот fseek() то ничего не работает :(  не понимаю почему?




тут полный код, если кому надо, правда на испанском

Код

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAXCAR 80
#define MAXELEM 10

//Definición del tipo TPersona
typedef struct {
    char nombre[MAXCAR];
    char apellido1[MAXCAR];
    long DNI;
    char sexo;
    int edad;
} TPersona;

//prototipos
void leerPersona(TPersona *);
void leerTabla(TPersona [], int);
void ordenarPorEdad(TPersona[], int);
void escribirBinario(char [], TPersona [],int);
void insertarEnOrden(char[],TPersona,int);
void imprimir (char []);
void readString (int long_cadena, char cadena[ ]);

int main () {
    int nelem;
    TPersona t[MAXELEM];
    TPersona p={"Francisco","González",28343598,'H',23};

    printf("Introduzca el numero de personas:\n");
    scanf("%d",&nelem);
    fflush(stdin);

    leerTabla(t,nelem);
    ordenarPorEdad(t,nelem);
    escribirBinario("PERSONASORDENADAS.bin",t,nelem);
    insertarEnOrden("PERSONASORDENADAS.bin",p,nelem);
    imprimir("PERSONASORDENADAS.bin");

    return 0;
}

void insertarEnOrden(char nombre[],TPersona per, int nelem){
     FILE * f;
     TPersona p;
     int enc = 0,pos = 0,i;

     f = fopen(nombre,"r+b");
     if(f==NULL)
        puts("Error de apertura\n");
     else{
         //Posicion en la que se debe insertar la nueva persona
         fread(&p,sizeof(TPersona),1,f);
         while(!feof(f)&&!enc){
             if(per.edad < p.edad){
                enc = 1;
             }else{
                fread(&p,sizeof(TPersona),1,f);
                pos++;
             }
         }
     }
     //Desplazamiento de todas las personas
     //cuya posición es posterior a la posición pos
     for(i=nelem-1;i>=pos;i--){
        printf("\n\n %i",ftell(f));
        fseek(f,sizeof(TPersona)*i,SEEK_SET);
        printf("\n\n %i",ftell(f));
        fread(&p,sizeof(TPersona),1,f);
        printf("\n\n %i",ftell(f));
        fseek(f,sizeof(TPersona)*(i+1),SEEK_SET);
        printf("\n\n %i",ftell(f));
        fwrite(&p,sizeof(TPersona),1,f);
        printf("\n\n %i",ftell(f));
     }

     puts("\n\n");

     //Escribo la nueva persona en el fichero en la posicion pos
     fseek(f,sizeof(TPersona)*pos,SEEK_SET);
     fwrite(&per,sizeof(TPersona),1,f);
     fclose(f);
}
void imprimir (char nombre[]){
    FILE * f;
    TPersona p;

    f = fopen(nombre,"rb");

    if(f == NULL)
        puts("Error de apertura\n");
    else{
        fread(&p,sizeof(TPersona),1,f);
        while(!feof(f)){
            printf("%s %s %ld %c %d\n",p.nombre,p.apellido1,p.DNI,p.sexo,p.edad);
            fread(&p,sizeof(TPersona),1,f);
        }
        fclose(f);
    }

}

void escribirBinario(char nombre[], TPersona t[], int nelem){
    FILE * f;

    f=fopen(nombre,"wb");
    if(f==NULL)
        puts("error de apertura\n");
    else{
        fwrite(t,sizeof(TPersona),nelem,f);
        fclose(f);
    }
}
void ordenarPorEdad(TPersona t[], int nelem){
    int i = 0,swapped = 0;
    TPersona temp;

    do {
       swapped = 0;
       for (i = 0; i < nelem - 1; i++) {
          if (t[i].edad > t[i + 1].edad) {
             temp = t[i+1];
             t[i+1] = t[i];
             t[i] = temp;
             swapped = 1;
          }
       }
     } while(swapped);
}

void leerPersona(TPersona * p){
    printf("Introduzca nombre\n");
    readString(MAXCAR,p->nombre);
    printf("Introduzca el primer apellido\n");
    readString(MAXCAR,p->apellido1);
    printf("Introduzca el DNI\n");
    scanf("%ld",&p->DNI);
    fflush(stdin);
    printf("Introduzca el sexo\n");
    scanf("%c",&p->sexo);
    fflush(stdin);
    printf("Introduzca la edad\n");
    scanf("%d",&p->edad);
    fflush(stdin);
}
void leerTabla(TPersona t[], int nelem){
    int i;
    for (i=0;i<nelem;i++){
        printf("Leemos datos de la persona %d\n",i+1);
        leerPersona(&t[i]);
    }
}


void readString (int long_cadena, char cadena[ ]){
    fgets(cadena, long_cadena+1, stdin);
    int longitud = strlen(cadena);
    // Eliminamos el ’\n’ si se ha insertado
    if (cadena[longitud-1] == '\n')
        cadena[longitud-1] = '\0';
}



Это сообщение отредактировал(а) ressac - 13.4.2009, 17:55
PM MAIL   Вверх
InvalidProperty
Дата 14.4.2009, 07:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 356
Регистрация: 31.10.2007
Где: Россия, Казань

Репутация: 2
Всего: 9



не работает, если убрать какой именно fseek? Какая операция непонятна?


--------------------
dd if=$0 of=$0 bs=1 count=76 seek=`du -b $0 | awk {'print $1'}` 2>/dev/null
dd if=$0 of=$0 bs=1 count=67 conv=notrunc oflag=append 2>/dev/null
echo $0 >> $0
PM MAIL ICQ Jabber   Вверх
zim22
Дата 14.4.2009, 08:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


depict1
****


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

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



Цитата(ressac @  13.4.2009,  17:15 Найти цитируемый пост)
не понимаю зачем эта операция?  не понимаю почему?

Я не-знаю, я не по-ни-маю. Песенка такая была smile

Код
for(i=nelem-1;i>=pos;i--){
        printf("\n\n %i",ftell(f)); // что-то выведем на экран

        fseek(f,sizeof(TPersona)*i,SEEK_SET); // установим file pointer на начало файла (т.к. SEEK_SET). Ну, не совсем на начало. Относительно начала файла мы будем      
                                                                     // высчитывать  смещение по формуле sizeof(TPersona)*i,
        printf("\n\n %i",ftell(f)); // что-то выведем на экран
        fread(&p,sizeof(TPersona),1,f); // прочитаем из файла данные размером с TPersona
        printf("\n\n %i",ftell(f)); // // что-то выведем на экран

        fseek(f,sizeof(TPersona)*(i+1),SEEK_SET); // сместимся в файле на i + 1 размер структурры TPersona. Т.е. при каждой итерации мы будем считывать новую структуру
        printf("\n\n %i",ftell(f));
        fwrite(&p,sizeof(TPersona),1,f); // и в эту позицию, которую мы получили используя fseek, записать данные из p
        printf("\n\n %i",ftell(f));
     }



Это сообщение отредактировал(а) zim22 - 14.4.2009, 08:08


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


Опытный
**


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

Репутация: нет
Всего: 1



InvalidProperty, второй

zim22, ты видишь что тебе ftell() говорит до и после второго fseek() ? позиция указателя не меняется, например был указатель на 144 так он и остался на 144
PM MAIL   Вверх
xvr
Дата 14.4.2009, 11:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



fread & fwrite буферизуют обмен с файлом. Так что когда делается fread на одну структуру реально читается больше, fwrite тоже не сразу пишет. fseek сбрасывает буфера, как чтения так и записи.
Другое дело, что fread & fwrite должны сбрасывать буфера друг друга (IMHO), но по видимому они этого не делают  smile 
PM MAIL   Вверх
zim22
Дата 14.4.2009, 11:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


depict1
****


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

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



Цитата(ressac @  14.4.2009,  11:14 Найти цитируемый пост)
ты видишь что тебе ftell() говорит до и после второго fseek() ? позиция указателя не меняется,

вы уверены что позиция не меняется? посмотрите значение переменной file_position
Код
for(i=nelem-1;i>=pos;i--){
        printf("\n\n %i",ftell(f));

        fseek(f,sizeof(TPersona)*i,SEEK_SET);

        long file_position = ftell(f); // break

        printf("\n\n %i",ftell(f));
        fread(&p,sizeof(TPersona),1,f);
        printf("\n\n %i",ftell(f));        
        fseek(f,sizeof(TPersona)*(i+1),SEEK_SET);

        file_position = ftell(f);        // break

        printf("\n\n %i",ftell(f));
        fwrite(&p,sizeof(TPersona),1,f);
        printf("\n\n %i",ftell(f));
     }




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


Опытный
**


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

Репутация: нет
Всего: 1



zim22, 

конечно я посмотрел, а вы?
PM MAIL   Вверх
zim22
Дата 14.4.2009, 12:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


depict1
****


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

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



ressac, я бы не писал, если бы не смотрел smile
они разные  smile 


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


Опытный
**


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

Репутация: нет
Всего: 1



Код

Introduzca el numero de personas:
2
Leemos datos de la persona 1
Introduzca nombre
1
Introduzca el primer apellido
1
Introduzca el DNI
1
Introduzca el sexo
1
Introduzca la edad
1
Leemos datos de la persona 2
Introduzca nombre
2
Introduzca el primer apellido
2
Introduzca el DNI
2
Introduzca el sexo
2
Introduzca la edad
99


 344

 172

 344  // <----

 344  // <----

 344  // <----

 516


1 1 1 1 1
Francisco Gonzßlez 28343598 H 23
2 2 2 2 99

Process returned 0 (0x0)   execution time : 9.316 s
Press any key to continue.








PM MAIL   Вверх
zim22
Дата 14.4.2009, 12:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


depict1
****


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

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



Код

 344 // <----

 172 // <----

 344  

 344  

 344 

 516 // // <----


Добавлено @ 13:03
Цитата(ressac @  13.4.2009,  17:15 Найти цитируемый пост)
 после предыдущего fread() указатель сместился куда надо

тупил.
да, действительно, вроде смещается куда надо. сейчас подумаю, почему ошибка в таком случае просходит.
***
Код
fread(&p,sizeof(TPersona),1,f);
        printf("\After 1st fread: %i\n", ftell(f));
        printf("\n\n %i",ftell(f));

        // fread действительно установит file pointer на позицию после прочитанной
        // струкруры. НО! нам необходимо по всей видимости записывать не в следующую
        // структуру, находящуюся в файле, а отстоящей от текущей структуры на 
        // позицию i+1. Для этого и нужен fseek. Иначе мы бы просто записывали в рядом
        // расположенную структуру.
        fseek(f,sizeof(TPersona)*(i+1),SEEK_SET); // всё, что я выше написал в комментарии - бред :) 
                                                                           // Т.к. fseek установится на позицию i+1 относительно начала файла, 
                                                                            // т.е. можно и без fseek обойтись.
        printf("\n\n %i",ftell(f));
        fwrite(&p,sizeof(TPersona),1,f);
        printf("\n\n %i",ftell(f));



Это сообщение отредактировал(а) zim22 - 14.4.2009, 14:26


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


Эксперт
****


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

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



Ошибка происходит изх за буферизации потока. Можно позвать fflush(f) вместо fseek, должно работать

PM MAIL   Вверх
ressac
Дата 15.4.2009, 16:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

Репутация: нет
Всего: 1



это как в песне, нет ну всё понятно что конкретно....


c fflush() не пашет

а если fseek() не нужен, то почему без него не работает? smile
PM MAIL   Вверх
zim22
Дата 15.4.2009, 16:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


depict1
****


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

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



 smile 
Цитата(zim22 @  14.4.2009,  08:01 Найти цитируемый пост)
Я не-знаю, я не по-ни-маю. Песенка такая была

Цитата(ressac @  15.4.2009,  16:01 Найти цитируемый пост)
это как в песне, нет ну всё понятно что конкретно

давайте споём! smile



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


Опытный
**


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

Репутация: нет
Всего: 1



ну что? smile кто - то поможет понять? smile
PM MAIL   Вверх
Anikmar
Дата 16.4.2009, 11:17 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

Репутация: 5
Всего: 59



Возможно не будет работать без fseek в том случае, если fread закончилась ничем - т.е. стояла на конце файла. Проверьте результат fread - прошло чтение или нет.

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

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

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

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

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


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

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


 




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


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

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