Мож я конечно тут достал некоторых с++ом, и форум вроде не для этого, но на другие форумы я чё-то редко появляюсь, тут привычнее :)
Итак, работаю с массивом структур. Бинарно сохраняю её в файл, цель - загрузить обратно из файла. При этом я нехочу пасать в сам файл, сколько там элементов, а хочу высчитать это определив размер файла / 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(" Введите там чё нибуть про эфиопов...\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...
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) она чё-то вылетает :(
Для начала в to_oem убери локальный buffer[256], сделай его глобальным, или передавай его адрес из вызывающей процедуры также, как и lpString. А то возможно, что содержимое буфера будет где-то затерто после выхода из процедуры.
если сделать буфер глобальным, то ничего переделывать не надо. Если передавать буфер вторым параметром, то надо переписать вызовы to_oem, добавив вторым параметром адрес принимающего буфера.
Не говори. Понимаешь, день предпраздничный, нормальные люди уже на работе бухают, водка стремительно кончается, но находятся же такие Ужоснахи, морочащие нам голову и ломающие весь кайф )
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); //ф-ция чтения, которая сама создаст массив из нужного кол-ва элементов и возвратит число полученных элементов
гы, я пока пробовал и Vito отпостил, тож спасибо! но я уже переточил как HOOLIGAN показывал, вроде работает, вот ссылка, мож кому пригодится и/или интересно тоже...