Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Для новичков > Вывод из файла структуры.


Автор: toxx 19.4.2009, 11:44
Хотел опробовать средства fread fwrite.Нашел программу базы данных, ввод работает нормально, а вывод косячит почемуто...(выводит только 1 запись,при наличии в файле допустим 3х).Никак не пойму почему.Просмотрел имеющиеся темы, попробовал вывод переписать из других тем(не помогло).
Функция вывода из файла.
Код

void print(FILE *f)
{clrscr();
 int i;
 char name[10];
 struct Personal sotr;
 printf("Vvedite imy faila: ");
 scanf("%s",name);
 f=fopen(name,"r");
 while (!feof(f))
 {
  fread(&sotr, sizeof(sotr),1,f);
  printf("%s %s %s %s ",sotr.fio, sotr.data, sotr.dolgn, sotr.zp);
 }
 fclose(f);
 getch();
 }


Сама программа

Код

#include <stdio.h>
#include <conio.h>

struct Personal
  {char fio[25];
   char data[20];
   char dolgn[20];
   char zp[10];
  };

void menu();
void create(FILE *,int );
void print(FILE *);
void dozapis(FILE *,int );
void correct(FILE *);
int len(FILE *);

void main()
{int vybor,n,l;
 FILE *f;
 do{
clrscr();
menu();
printf("Vash vybor: ");
scanf("%d",&vybor);
 switch (vybor){
  case 1:printf("Vvedite kol-vo sotrudnicov: ");
     scanf("%d",&n);
     create(f,n);break;
  case 2:print(f);break;
  case 3:correct(f);break;
  case 4: printf("Vvedite kol-vo sotrudnicov: ");
    scanf("%d", &n);
    dozapis(f,n);break;
  case 5:break;
  case 6:l=len(f); printf("%d",l);break;
  default :puts("\n Nevernyi vvod.Vvedite chislo ot 1 do 5 ");
  }
  }while (vybor!=5);
}

void menu(void)
{puts("\t Menu");
 puts("1.Sozdat fail. \n");
 puts("2.Prosmotr faila. \n");
 puts("3.Izmenit fail. \n");
 puts("4.Dozapis v fail. \n");
 puts("5.Vyxod. \n");
}


void create(FILE *f,int n)
{clrscr();
 int i;
 char name[10];
 struct Personal sotr;
 printf("Vvedite imy sozdavaemogo faila: ");
 scanf("%s",name);
 if((f=fopen(name,"w"))==NULL)
  {printf("Ne udaetsy otkryt fail na zapis.\n");
  }
  for (i=0;i<n;i++)
   {clrscr();
 printf("Vvedite svedeniy o %d sotrudnike:\n",i+1);
 printf("F.I.O.:\n");
 scanf("%s",sotr.fio);
 printf("Data rogdeniy:\n");
 scanf("%s",sotr.data);
 printf("Dolgnost:\n");
 scanf("%s",sotr.dolgn);
 printf("Zarplata:\n");
 scanf("%s",sotr.zp);
 fwrite(&sotr, sizeof(sotr),1,f);
   }
  fclose(f);
 }


void print(FILE *f)
{clrscr();
 int i;
 char name[10];
 struct Personal sotr;
 printf("Vvedite imy faila: ");
 scanf("%s",name);
 f=fopen(name,"r");
 //for (i=0;i<n;i++)
 //fread(&sotr, sizeof(sotr),1,f);
 while (!feof(f))

 {fread(&sotr, sizeof(sotr),1,f);
  printf("%s %s %s %s ",sotr.fio, sotr.data, sotr.dolgn, sotr.zp);
  //fread(&sotr, sizeof(sotr),1,f);
 }
 fclose(f);
 getch();
 }


void dozapis(FILE *f,int n)
{clrscr();
 struct Personal sotr;
 int i;
 char name[10];
 printf("Vvedite imy faila na dozapis: ");
 scanf("%s",name);
 if((f=fopen(name,"a"))==NULL)
  {printf("Ne udaetsy otkryt fail na zapis.\n");
  }
 for (i=0;i<n;i++)
 {printf("Vvedite svedeniy o %d sotrudnike:\n",i+1);
 printf("F.I.O.:\n");
 scanf("%s",sotr.fio);
 printf("Data rogdeniy:\n");
 scanf("%s",sotr.data);
 printf("Dolgnost:\n");
 scanf("%s",sotr.dolgn);
 printf("Zarplata:\n");
 scanf("%s",sotr.zp);
 fwrite(&sotr, sizeof(sotr),1,f);
   }
  fclose(f);

}
 void correct(FILE *f)
 {char name[10],fam[25];
  int v,l;
  struct Personal sotr;
  printf("Vvedite imy faila: ");
  scanf("%s",name);
  if((f=fopen(name,"r+"))==NULL)
  {printf("Ne udaetsy otkryt fail na zapis.\n");
  }
  printf("Vvedite familiu sotrudnika dly correctirovki: ");
  scanf("%s", &fam);
  while(!feof(f))
  {fread(&sotr, sizeof(sotr),1,f);
 if(!strcmp(fam,sotr.fio))
  {l++;
   fseek(f,sizeof(sotr),SEEK_CUR);
   printf("Chto chotite ispravit:\n 1.Familiu.\n 2.Dolgnost.\n 3.Zarplatu\n");
   printf("Vash vybor: ");
   scanf("%d",&v);
    switch(v)
    {case 1:printf("Vvedite novyu familiu ");
      scanf("%s",&sotr.fio);
      printf("Dannye izmeneny.\n");
      break;
  case 2:fseek(f,(sizeof(sotr.fio)+sizeof(sotr.data)),SEEK_CUR);
      printf("Vvedite novyu dolgnost ");
      scanf("%s",&sotr.dolgn);
      printf("Dannye izmeneny.\n");
      break;
  case 3:fseek(f,(sizeof(sotr.fio)+sizeof(sotr.data)+sizeof(sotr.dolgn)),SEEK_CUR);
      printf("Vvedite novyu zarplatu ");
      scanf("%s",&sotr.zp);
      printf("Dannye izmeneny.\n");
      break;
  default:puts("Nevernyi vvod.\n");
    }
    fclose(f);
  }
 if (l=0) {
  printf("Takogo sotrudnica net");
 }
 getch();
  }
  }

 int len(FILE *f)
 {struct Personal sotr;
  char name[10];
  int l=0;
  printf("Vvedite imy faila: ");
  scanf("%s",name);
   if((f=fopen(name,"r+"))==NULL)
   {printf("Ne udaetsy otkryt fail.\n");
 }
   while(!feof(f))
 {fread(&sotr, sizeof(sotr),1,f);
  l++;
 }
 getch();
 return l;

 }

Автор: nubliK 20.4.2009, 05:28
Исходный твой
Код

while (!feof(f))
 {
  fread(&sotr, sizeof(sotr),1,f);
  printf("%s %s %s %s ",sotr.fio, sotr.data, sotr.dolgn, sotr.zp);
 }


Я привык использовать потоки ввода вывода - поэтому не пинай

Код

string s;
while (getline(f, s))
  cout << s << "\n"


помогло?

Автор: mrbrooks 20.4.2009, 09:43
nubliK, есть подозрение камрад - что автор пишет на С.

Автор: zim22 20.4.2009, 09:57
Цитата(nubliK @  20.4.2009,  05:28 Найти цитируемый пост)
fread(&sotr, sizeof(sotr),1,f);


Цитата(nubliK @  20.4.2009,  05:28 Найти цитируемый пост)
while (getline(f, s))

вы считаете, что написали эквивалентный код?

Автор: toxx 20.4.2009, 16:46
nubliK

Я сам использую потоки))Поэтому сделал без проблем это задание, а один человек делает через средстава ввода/вывода Си а Си++, отсюда у неё стока гемороя.Я сам попытался вникнуть в эту писанину вродебы все по нормально, на форуме копался нашел варианты вывода из файла не помогло(


mrbrooks
По поводу Си выше))


zim22

Да уж неособо эквивалентный средства разные)

Автор: zim22 20.4.2009, 17:12
Цитата(toxx @  20.4.2009,  16:46 Найти цитируемый пост)
Да уж неособо эквивалентный средства разные)

результаты разные. код, предложенный nubliK'ом не читает структуру. он читает строку текста.

Автор: toxx 20.4.2009, 19:48
zim22
Да я понимаю, просто хотелосьбы чтобы не потоками было сделано, fread fwrite.Потокамибы ябы сам переписал)А когда делаешь fread fwrite выводит только одну запись из файла при наличии допустим 3х(

Автор: zim22 20.4.2009, 19:50
toxx, я могу вам посоветовать упростить программу до "не-могу" и разобраться с простейшим примером. т.е. возьмите и напишите очень простую программу с нуля. разберитесь, как работают функции fread, fwrite

Автор: toxx 20.4.2009, 20:15
zim22
Хорошо =)

Автор: nubliK 21.4.2009, 02:22
to mrbrooks я это понял. просто проще хотелось.

zim22 - а разве файл не будет текстовый?

Ну раз за потоки отпинали по полной - тогда попробуй из этого примера что нибудь сотворить

Код

#include <stdio.h>

int main()
{
    FILE *fp = fopen("файл.txt", "r");
    int c;
    c = getc(fp);
    while (c != EOF) {
        /* Выводим файл в stdout */
        putchar(c);
        c = getc(fp);
    }
    if (feof(fp))
      puts("Конец файла достигнут.");
    else if (ferror(fp))
      puts("Ошибка чтения из потока.");
    else
      /*НЕДОСТИГНУТ*/
      puts("getc() завершилась с неопознанной ошибкой.");

    fclose(fp);
    return 0;
}


взято здесь  http://ru.wikipedia.org/wiki/Feof 

Код

/* feof example: byte counter */
#include <stdio.h>
int main ()
{
  FILE * pFile;
  long n = 0;
  pFile = fopen ("myfile.txt","rb");
  if (pFile==NULL) perror ("Error opening file");
  else
  {
    while (!feof(pFile)) {
      fgetc (pFile);
      n++;
      }
    fclose (pFile);
    printf ("Total number of bytes: %d\n", n-1);
  }
  return 0;
}


http://www.cplusplus.com/reference/clibrary/cstdio/feof/

Автор: nubliK 21.4.2009, 03:27
И еще! У меня твоя программа заработала легко, но только под Dev-C++ и как то очень странно - в результате она показывает из файла последнюю запись дважды и запрос на дату рождения, должность и заработную плату выплевывает разом, а не последовательно - могу прислать тебе скрин как оно работает.
Я выкинул функцию clrscr() потому что компил(Dev-C++) ругался.  описания ее я так и не нашел в твоем исходнике.
Студия исходник не осилила - почему - понятия не имею (как то они все там лихо стандартизировали и теперь старые функции Си либо не определены либо определены но не в том значении как было раньше).


Автор: toxx 21.4.2009, 17:33
Цитата(nubliK @ 21.4.2009,  03:27)
И еще! У меня твоя программа заработала легко, но только под Dev-C++ и как то очень странно - в результате она показывает из файла последнюю запись дважды и запрос на дату рождения, должность и заработную плату выплевывает разом, а не последовательно - могу прислать тебе скрин как оно работает.
Я выкинул функцию clrscr() потому что компил(Dev-C++) ругался.  описания ее я так и не нашел в твоем исходнике.
Студия исходник не осилила - почему - понятия не имею (как то они все там лихо стандартизировали и теперь старые функции Си либо не определены либо определены но не в том значении как было раньше).

Могу сказать еще больше, у того кто писал эту программу, она спрашивает  только первые 2 поля при создании, пользуемся одним компилятором, а результат разный(У меня спрашивает всё, только вывод косячит).Вобщем это чтото не понятное.Человек уже неделю мучается с этим ефом.Конечно попробую что ты нашел,только вродебы пробовали это).Спасибо, что запустил программу.

Автор: zim22 21.4.2009, 17:44
Цитата(nubliK @  21.4.2009,  02:22 Найти цитируемый пост)
а разве файл не будет текстовый?

это похоже на считывание текста? подсказка: это считывание в бинарном режиме структуры.
Код

fread(&sotr, sizeof(sotr),1,f); 
printf("%s %s %s %s ",sotr.fio, sotr.data, sotr.dolgn, sotr.zp);


Автор: Dov 21.4.2009, 19:19
Б-ррррр, кошмар какой...  Даже не знаю с чего начать... Ладно, сделаем так.
toxx, вот тебе примерчик твоей проги в облегчённом виде, разбирайся. Я отметил места, где сделал изменения, остальное ты сам должен понять. 

Скажу только, что если ты спрашиваешь пользователя о количестве записей, то ты должен организовать массив структур, соответсвующего размера.  Я, для примера, взял массив из трёх структур, а тебе,возможно, прийдётся  динамически создавать. 
Код

struct Personal
{
    char    fio[25];
    char    data[20];
    char    dolgn[20];
    char    zp[10];
};

void    menu();
void    create( FILE *, int );
void    print( FILE * );

void main()
{
    int        vybor, n, l;
    FILE   *f;

    do
    {
        menu();
        printf( "Vash vybor: " );
        scanf( "%d", &vybor );

        switch( vybor )
        {
        case 1:
            //printf( "Vvedite kol-vo sotrudnicov: " );
            //scanf( "%d", &n );
            n = 3;
            create( f, n );break;
        case 2:
            print( f );break;
        default :
            puts( "\n Nevernyi vvod.Vvedite chislo ot 1 do 5 " );
        }
    }while( vybor != 5 );
}

void menu( void )
{
    puts( "\t Menu" );
    puts( "1.Sozdat fail. \n" );
    puts( "2.Prosmotr faila. \n" );
}


void create( FILE *f, int n )
{
    int                i;
    char            name[10];

    struct Personal    sotr[3];                  // <<==

    printf( "Vvedite imy sozdavaemogo faila: " );
    scanf( "%s", name );

    if( ( f = fopen( name, "wb" ) ) == NULL ) // <<==
    {
        printf( "Ne udaetsy otkryt fail na zapis.\n" );
    }

    for( i = 0; i < n; i++ )
    {
        printf( "Vvedite svedeniy o %d sotrudnike:\n", i + 1 );
        printf( "F.I.O.:\n" );              
        scanf( "%s", sotr[i].fio );           // <<== 
        printf( "Data rogdeniy:\n" );
        scanf( "%s", sotr[i].data );          // <<==
        printf( "Dolgnost:\n" );
        scanf( "%s", sotr[i].dolgn );         // <<==
        printf( "Zarplata:\n" );
        scanf( "%s", sotr[i].zp );            // <<==
    }

    fwrite( &sotr, sizeof( Personal ), 3, f );// <<== 

    fclose( f );
}


void print( FILE *f )
{
    int                i;
    char            name[10];

    struct Personal    sotr[3];                  // <<==

    printf( "Vvedite imy faila: " );
    scanf( "%s", name );

    f = fopen( name, "rb" );//                // <<==

    fread( &sotr, sizeof( Personal ), 3, f ); // <<==

    for(i = 0; i < 3; i++ )                   // <<==
    {
        printf( "%s %s %s %s \n", sotr[i].fio, sotr[i].data, sotr[i].dolgn, sotr[i].zp ); // <<==
    }

    fclose( f );
    getch();
}

Автор: toxx 21.4.2009, 21:46
Dov
Спасибо за проделанную работу.

f = fopen( name, "rb" )

Проблема была в том как открыт файл.Спасибо, всё понятно=)

Автор: nubliK 22.4.2009, 01:22
Да! zim22 не похоже =) я исходил из той мысли что файл блокнотом открылся и читался нормально в строчку. - так можно дойти до чего угодно только не до сути. Ошибку понял. Спасибо за подзатыльник.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)