Visual Basic, .NET, ASP, VBScript
 

   
   
     

Форум - Общий форум

Страница: 1 |

 

  Вопрос: VС++ Загрузка массива структур Добавлено: 28.04.06 15:19  

Автор вопроса:  HACKER
Мож я конечно тут достал некоторых с++ом, и форум вроде не для этого, но на другие форумы я чё-то редко появляюсь, тут привычнее :)

Итак, работаю с массивом структур. Бинарно сохраняю её в файл, цель - загрузить обратно из файла. При этом я нехочу пасать в сам файл, сколько там элементов, а хочу высчитать это определив размер файла / sizeof (структуры). В принципи всё получается, но трабла в том, что после чтения из бинарного файла в структуру (котороая вроде прошла нормально, покрайнемере ошибок не вылетало), потом эту структуру неполучается прочитать, т.е. когда циклом вывожу элементы, Си, как обычно в доль и в поперёк меня посылает :)

Ниже собственно код и скрин ошибки
P.s. name space ещё учим, так что "так надо" :))
#include <iostream>
#include <windows.h>
#include "Unit23.h"
using namespace grup;

void main(){
   int n=0;
   int mode=0;
   char tmp[128];
   printf ( to_oem(" Ну-ка введите чё хотите сделать! :)\n\n") );
   printf ( to_oem(" 0 - пАказать как умеем записывать :)\n") );
   printf ( to_oem(" 1 - пАказать как умеем читать :)\n") );
   printf ( to_oem(" 2 - Ну его нах, уже ничего хочеться :))))\n\n") );

   printf ( to_oem("Итак, Ваш выбор: ") ); cin >> mode;  

   char filename[]="binary.txt";
   char filename2[]="text.txt";
   
   if (mode == 0){
system("cls");
printf ( to_oem("\nСколько студентов? ") ); cin>>n;
printf ( to_oem("\nОни эфиопы? ") ); cin>>tmp;
printf ( to_oem(" Ладно, неважно...:)\n\n") );

printf ( to_oem(" Введите там чё нибуть про эфиопов...\n") );
   
    stud*IB=new stud[n];      
   
inputFromkeyboard (IB,n);            //Ввод с клавы
inputToBinaryFile (IB,n,filename);   // Запись в бинарный файл  
inputToTextFile (IB,n,filename2);    // Запись в текстовый файл
   
cout<<"\n";  
   
outputStuctToScreen (IB,n); //Вывод на экран
delete[]IB;
   }else if (mode == 1){
   /// ЧИТАЕМ БИНАРНЫЙ ФАЙЛ !!! ///

   stud* IB; //Только указатель! БЕЗ объяв. размера массива стрктур!

n = outputFromBinaryFile (IB, filename); //ф-ция чтения, которая сама создаст массив из нужного кол-ва элементов и возвратит число полученных элементов
        
outputStuctToScreen (IB,n); //Вывод на экран

delete[]IB;

   }else if (mode == 2){
printf ( to_oem("\n\n Да и правельно, всёравно чтение глючённое :)") );
   }
   cin.get();cin.get();  
}


Unit23.h

#include <iostream>
#include <fstream>

#include <windows.h>
using namespace std;

namespace grup{

struct stud{
char FIO[30];
float bals[5];
int ng;
};

float Sred(float *arr,int n);  
void inputToTextFile(stud*IB, int n, char* FN);
void inputToBinaryFile(stud*IB, int n, char* FN);
void inputFromkeyboard(stud*IB,int n);
   
    void outputStuctToScreen(grup::stud*IB, int n);  
int outputFromTextFile (stud*IB, char* filename);
int outputFromBinaryFile (grup::stud*IB, char* filename);  
}  //konec namespace grup

long filesize(char* sFileName);
static char* to_oem ( char* lpString );

int grup::outputFromTextFile (grup::stud* IB, char* filename){
//Считываем из текстового файла и возвращает полученное кол-во элементов массива
int i=0; //счётчик
ifstream in(filename);
while(!in.eof()){
in>>IB[i].FIO;
for(int j=0; j<5; j++){
in>>IB[i].bals[j];
}//for...
in>>IB[i].ng;
i++;
     }//while...
       in.close();
   return i;
    }//void...

void grup::outputStuctToScreen(grup::stud*IB, int n){
//Вывод структуры на экран
     int i=0;
     for (i=0;i<n;i++){
cout<<"Stud# "<<i+1<<"\n";
cout<<"\tFIO: "<<IB[i].FIO<<"\n\tbals: ";
for(int j=0; j<5; j++) cout<<""<<IB[i].bals[j]<<" ";      
cout<<"\n\t#group: "<<IB[i].ng<<"\n";
     }//for...      
    }//void...

   int grup::outputFromBinaryFile (grup::stud* IB, char* filename){
//Считываем из бинарного и возвращает полученное кол-во элементов массива

  ifstream in(filename,ios::in|ios::binary);
    long fsize=filesize(filename);   // размер файла
int array_size = (fsize / sizeof(stud));    // автоматически считаем размер массива

IB = new grup::stud[array_size];// создаём массив (выделяем память) '<<<<< Размер правельно определяется и фишка ВРОДЕ ПРОКАТУЕТ
//но при выводе на экран всё заглючит :(   
  in.read((char*)IB,sizeof(stud)*array_size); //грузим в него данные из файла
  in.close();
  return array_size;
   } //int...

   void grup::inputToBinaryFile(grup::stud*IB, int n, char* FN){
//Запись в бинарный файл
ofstream out(FN,ios::out|ios::binary);
        out.write((char*)IB,sizeof(grup::stud)*n);
        out.close();
   } //void inputToBinaryFile(grup::stud*IB, int n, char* FN)

   void grup::inputToTextFile(grup::stud*IB, int n, char* FN){
//Записть структуры в текстовы файл
     ofstream out(FN);
       for(int i=0; i<n; i++){
       out<<IB[i].FIO<<"\n";
       for(int j=0; j<5; j++){
        out<<IB[i].bals[j]<<" ";
       }//for j...
       out<<"\n";
       out<<IB[i].ng<<"\n";
       }//for...;
     }//void...  
   
 
   void grup::inputFromkeyboard(grup::stud*IB,int n){
   //Ввод с клавы
   int i=0;
      for(i=0;i<n;i++){
cin.ignore();
         cout<<"Stud# "<<i+1<<"\n";
         cout<<"\tFIO : ";
         cin.getline(IB[i].FIO,30);
         cout<<"\t#group : ";
         cin>>IB[i].ng;
         cout<<"\tbals: ";
         //cin.ignore();
         for(int j=0;j<5;j++)
         cin>>IB[i].bals[j];
        }

  for(i=0;i<n;i++){
          for(int j=0;j<n-i-1;j++){
if(IB[i].ng>IB[i+1].ng){
stud tmp=IB[i];
IB[i]=IB[i+1];
IB[i+1]=tmp;
} //if...
  } //for(int j...
  } //for(i...
   } //void grup::inputFromkeyboard(grup::stud*IB,int n)

    float grup::Sred(float *arr,int n){
//Сред. значение массива
        float srbal;
        for(int j=0; j<n; j++) srbal = srbal + (arr[j]);
srbal = srbal / n;            
        return srbal;
    }// float grup::Sred(stud*IB,int n)

// $$$$$$$$$$$$$$$$$$ END GRUP $$$$$$$$$$$$$$$$$$

long filesize(char* sFileName)
{
FILE *file;                                              // Объявляем
if ((file = fopen(sFileName, "r")) == NULL) return 0;    // Открываем и смотрим шобы хендел был не NULL    
long curpos, length; // Рабочие лошадки
curpos = ftell(file); // Ставим курсор в начало
fseek(file, 0L, SEEK_END); // Передвигаем в конец
length = ftell(file); // То на сколько передвинулось - размер
fseek(file, curpos, SEEK_SET); //
fclose(file); // Закрываем поток
return length;
}

static char* to_oem ( char* lpString )  
// перевод в дос-кодировку для отображения кириллицы
{
char    buffer[512];
CharToOem ( lpString, buffer ); //Вот она! :) API ф-ия для ковертирования строки в кириллицу для DOS'a (або консольного режима :) )
return ( buffer );
}


т.е. прошу обратить внимание на ф-ции
inputToBinaryFile
outputFromBinaryFile
outputStuctToScreen
При загрузке структуры с бинарного файла (outputFromBinaryFile) потом при выводе на экран (outputStuctToScreen) она чё-то вылетает :(

Полный исходник:
aia.net.ua/project.rar (~ 5 КБ)

Срин ошибки 1:
aia.net.ua/screen1.rar (~ 12 КБ)
Потом жму ОК, вываливается мой "любимый" ассемблер :)
aia.net.ua/screen2.rar (~ 9 КБ)

Дочитал до конца? Завидую твоему терпению! :) В таком случае может ещё хватит тебя чтобы разобраться во всей этой мути? :)

Ответить

  Ответы Всего ответов: 13  

Номер ответа: 1
Автор ответа:
 LamerOnLine



ICQ: 334781088 

Вопросов: 108
Ответов: 2822
 Профиль | | #1 Добавлено: 28.04.06 15:29
Ужоснах...
Не проще ли в отладчике отдебажить чем приводить весь этот креатифф :)

Ответить

Номер ответа: 2
Автор ответа:
 HOOLIGAN



Вопросов: 0
Ответов: 1066
 Профиль | | #2 Добавлено: 28.04.06 15:38
Для начала в to_oem убери локальный buffer[256], сделай его глобальным, или передавай его адрес из вызывающей процедуры также, как и lpString. А то возможно, что содержимое буфера будет где-то затерто после выхода из процедуры.

char* to_oem (char* lpString, char* lpOutput){
    CharToOem (lpString, lpOutput);
    return lpOutput;
}


если сделать буфер глобальным, то ничего переделывать не надо. Если передавать буфер вторым параметром, то надо переписать вызовы to_oem, добавив вторым параметром адрес принимающего буфера.

Ответить

Номер ответа: 3
Автор ответа:
 DJ MATHEMATIC



Вопросов: 17
Ответов: 18
 Профиль | | #3 Добавлено: 28.04.06 16:08
Да!!!До этого мне еще далеко! (((:

Ответить

Номер ответа: 4
Автор ответа:
 LamerOnLine



ICQ: 334781088 

Вопросов: 108
Ответов: 2822
 Профиль | | #4 Добавлено: 28.04.06 16:44
Не говори. Понимаешь, день предпраздничный, нормальные люди уже на работе бухают, водка стремительно кончается, но находятся же такие Ужоснахи, морочащие нам голову и ломающие весь кайф :()

Ответить

Номер ответа: 5
Автор ответа:
 HOOLIGAN



Вопросов: 0
Ответов: 1066
 Профиль | | #5 Добавлено: 28.04.06 16:50
//==========================================================
FILE* write_to_file (STUDENT* pStudent, int count){
    FILE*   fHandle = fopen ("C:\\student.dat", "w";);
    if (!fHandle) return 0;
    if (count == fwrite (pStudent, sizeof(STUDENT), count, fHandle))
        printf ( to_oem("\n\Записано %d структур\n";), count );
    fclose (fHandle);
    return fHandle;
}

//==========================================================
int read_from_file (STUDENT* pStudent, int count){
    int     cnt;
    FILE*   fHandle = fopen ("C:\\student.dat", "r";);
    if (!fHandle) return 0;
    cnt = fread (pStudent, sizeof(STUDENT), count, fHandle);
    printf ( to_oem("\n\Считано %d структур\n";), cnt );
    fclose (fHandle);
    return cnt;
}

//==========================================================
void out_to_screen(STUDENT* pStudent, int count){
    int     i,j;

    for (i=0; i<count; i++){
        printf ("\n---------------------------------\n";);
        printf (to_oem("Студент %s группа: %d\n";), pStudent->name, pStudent->group_ID);
        printf (to_oem("Оценки:  ";));
        for (j=0; j<5; j++)    printf ("%d ", pStudent->mark[j];);
        pStudent ++;
    }
}


попробуй. тут буфер для ф-ции to_oem сделан как глобальный.

Ответить

Номер ответа: 6
Автор ответа:
 vito



Разработчик Offline Client

Вопросов: 23
Ответов: 879
 Web-сайт: softvito.narod2.ru
 Профиль | | #6
Добавлено: 28.04.06 18:14
Поздравляю HACKER, растешь!!!

Вот твоя ощибка.

stud* IB; //Только указатель! БЕЗ объяв. размера массива стрктур!

n = outputFromBinaryFile (IB, filename); //ф-ция чтения, которая сама создаст массив из нужного кол-ва элементов и возвратит число полученных элементов
         
outputStuctToScreen (IB,n); //Вывод на экран

IB - некорректно используем указатель.
Когда возвращаемся из функции, он никуда не указывает.
Вот вся проблема;)))
Все остальое правильно!!

Как исправить.
Объявим указатель глобально.

#include <iostream>
#include <fstream>

#include <windows.h>
using namespace std;

namespace grup{

struct stud{
char FIO[30];
float bals[5];
int ng;
};

/////////////////////////////////////////////////////////////////////////////////////////
grup::stud* IB = NULL ; //Только указатель! БЕЗ объяв. размера массива стрктур!
///////////////////////////////////////////////////////////////////////////////////////////
float Sred(float *arr,int n);  
void inputToTextFile(stud*IB, int n, char* FN);
void inputToBinaryFile( int n, char* FN);
void inputFromkeyboard(stud*IB,int n);
   ////////////////////////////////////////////////////////////////////////////////////////////////////////////
                   void outputStuctToScreen(  int n);// соответственно изменим прототипы функций  
///////////////////////////////////////////////////////////////////////////////////////////////////////////////

int outputFromTextFile (grup::stud* IB, char* filename);
int outputFromBinaryFile (  char* filename);  
  //konec namespace grup


И сами функции.

void grup::outputStuctToScreen(  int n){
//Вывод структуры на экран
     int i=0;
     for (i=0;i<n;i++){
cout<<"Stud# "<<i+1<<"\n";
cout<<"\tFIO: "<<IB[i].FIO<<"\n\tbals: ";
for(int j=0; j<5; j++) cout<<""<<IB[i].bals[j]<<" ";      
cout<<"\n\t#group: "<<IB[i].ng<<"\n";
     }//for...      
    }//void...

   int grup::outputFromBinaryFile (  char* filename){
//Считываем из бинарного и возвращает полученное кол-во элементов массива

  ifstream in(filename,ios::in|ios::binary);
    long fsize=filesize(filename);   // размер файла
int array_size = (fsize / sizeof(stud));    // автоматически считаем размер массива

IB = new grup::stud[array_size];// создаём массив (выделяем память) '<<<<< Размер правельно определяется и фишка ВРОДЕ ПРОКАТУЕТ
//но при выводе на экран всё заглючит :(   
  in.read((char*)IB,sizeof(stud)*array_size); //грузим в него данные из файла
  in.close();
  return array_size;
   } //int...

И вызывать будем по другому.
 

/// ЧИТАЕМ БИНАРНЫЙ ФАЙЛ !!! ///

n = outputFromBinaryFile ( filename); //ф-ция чтения, которая сама создаст массив из нужного кол-ва элементов и возвратит число полученных элементов
        
outputStuctToScreen (n); //Вывод на экран



Все всех с праздником!!! Работу нафинг!!!!:)))

Ответить

Номер ответа: 7
Автор ответа:
 HACKER


 

Разработчик Offline Client

Вопросов: 236
Ответов: 8362
 Профиль | | #7 Добавлено: 28.04.06 18:33
Ну хулиган - ты мАзги :))
Я от выросту, у меня тоже будут большие яйца и большие мозги :))))))))0

RESPECT!!! Спасибо большое!!!!

Ответить

Номер ответа: 8
Автор ответа:
 HACKER


 

Разработчик Offline Client

Вопросов: 236
Ответов: 8362
 Профиль | | #8 Добавлено: 28.04.06 18:35
гы, я пока пробовал и Vito отпостил, тож спасибо! но я уже переточил как HOOLIGAN показывал, вроде работает, вот ссылка, мож кому пригодится и/или интересно тоже...

aia.net.ua\file_struct.rar

Ответить

Номер ответа: 9
Автор ответа:
 Neco



ICQ: 247906854 

Вопросов: 133
Ответов: 882
 Web-сайт: neco.pisem.net
 Профиль | | #9
Добавлено: 28.04.06 18:55
Ну и ещё вариантик баяна:

#include <stdio.h>
#include <windows.h>

void copy_str(char *cnst,char *var);
long filesize(char* sFileName);

struct tpNeco
{
char name[50];
char surname[50];
int  ball;
};

int main()
{
char *f_name="d:\\students.txt";
// ---------------------------------- writing
// Init
int max=10,i=0;
tpNeco *w_buf=new tpNeco[max];
memset(w_buf,0,sizeof(tpNeco)*max);

// Generating
for(i=0;i<max;++i)
{
w_buf[i].ball    = i;
copy_str((char*)&w_buf[i].name,    "Nicolay";);
copy_str((char*)&w_buf[i].surname, "Uvaliev";);
}

// Writing
FILE *to_w=fopen(f_name,"w";);
fwrite(w_buf,sizeof(tpNeco),max,to_w);
fclose(to_w);

delete (w_buf);

// ---------------------------------- reading

int sz=filesize(f_name);
if (sz > -1)
{
int r_max=(int)sz/sizeof(tpNeco);
if (r_max > 0)
{
tpNeco *r_buf=new tpNeco[r_max];
FILE *to_r=fopen(f_name,"r";);
fread(r_buf,sizeof(tpNeco),r_max,to_r);
fclose(to_r);

printf("id\tsurname\t\tname\t\tballs\n\n";);

for (i=0;i<r_max;++i)
{
printf("%d\t%s\t\t%s\t\t%d\n",i,r_buf[i].surname,r_buf[i].name,r_buf[i].ball);
}
printf("\n\nComleted";);
}else{
printf("file courrupted\n";);
}

}else{
printf("file not found\n";);
}
getchar();
return 0;
}

void copy_str(char *cnst,char *var)
{
int len=strlen(var);
if (len<50) strncpy(cnst,var,len);
}

long filesize(char* sFileName)
{
FILE *file;
if ((file = fopen(sFileName, "r";)) == NULL) return -1;
long  length;//curpos,
fseek(file, 0L, SEEK_END);
length = ftell(file);
fclose(file);
return length;
}

Ответить

Номер ответа: 10
Автор ответа:
 Neco



ICQ: 247906854 

Вопросов: 133
Ответов: 882
 Web-сайт: neco.pisem.net
 Профиль | | #10
Добавлено: 28.04.06 19:03
Хулиган, как делаешь, что intend сохранялся? Во многих форумах сбрасывается...

P.S. Прочитал ещё раз название топа - Visual C++. 8))))

Ответить

Номер ответа: 11
Автор ответа:
 HACKER


 

Разработчик Offline Client

Вопросов: 236
Ответов: 8362
 Профиль | | #11 Добавлено: 28.04.06 19:03
ну тоже самое в принципе... Всем пасибо!

Ответить

Номер ответа: 12
Автор ответа:
 HACKER


 

Разработчик Offline Client

Вопросов: 236
Ответов: 8362
 Профиль | | #12 Добавлено: 28.04.06 19:05
P.S. Прочитал ещё раз название топа - Visual C++. 8))))

Не, ну кодю то в нём (имеется ввиду не Борланд), а шо не визуал то понятно :)

Ответить

Номер ответа: 13
Автор ответа:
 LamerOnLine



ICQ: 334781088 

Вопросов: 108
Ответов: 2822
 Профиль | | #13 Добавлено: 28.04.06 20:10
Всем пасибо!

А мне то за что? Ну, ладно, и тебе здоровья, с праздничком, тостик за тебя :))

Ответить

Страница: 1 |

Поиск по форуму



© Copyright 2002-2011 VBNet.RU | Пишите нам