union okpo
{
double num;
char str[8];
};
union okpo uokpo;
uokpo.num=StrToFloat(Edit1->Text);
Помогите с вещественными числами.
По идее все должно быть тихо и гладко, все числа сохраняет/загружает, вот только при вводе числа 2766077 при загрузке выдает NAN - нечисло , обьясните пожалуйста в чем глюк. Еще есть одно число незапомнил точно какое ввожу nnnnnnnnnn,15 а при загрузке выдает nnnnnnnnnn,1 =(.
void __fastcall TForm1::SaveClick(TObject *Sender)
{
union okpo
{
double num;
char str[8];
};
union okpo uokpo;
uokpo.num=StrToFloat(Edit1->Text);
AnsiString fspr;
FILE *fs;
fs=fopen("temp.txt", "w");
for(int i=0;i<8;i++)
{
fputc(uokpo.str, fs);
}
fclose(fs);
}
//---------------------------------------------------------------------------
void __fastcall TForm1::LoadClick(TObject *Sender)
{
union okpo
{
double num;
char str[8];
};
union okpo uokpo;
FILE *fs;
fs=fopen("temp.txt", "r");
for(int i=0;i<8;i++)
{
uokpo.str=fgetc(fs);
}
fclose(fs);
Edit1->Text=uokpo.num;
}
Цитата:
Originally posted by ReaLeter
Ниже приведен код, в кратце - сохраняет введеннное вещественное число на диск, по нажатию кнопки загружает его в Edit1.
По идее все должно быть тихо и гладко, все числа сохраняет/загружает, вот только при вводе числа 2766077 при загрузке выдает NAN - нечисло , обьясните пожалуйста в чем глюк. Еще есть одно число незапомнил точно какое ввожу nnnnnnnnnn,15 а при загрузке выдает nnnnnnnnnn,1 =(.
void __fastcall TForm1::SaveClick(TObject *Sender)
{
union okpo
{
double num;
char str[8];
};
union okpo uokpo;
uokpo.num=StrToFloat(Edit1->Text);
AnsiString fspr;
FILE *fs;
[COLOR=firebrick] fs=fopen("temp.txt", "wb");[/COLOR]
for(int i=0;i<8;i++)
{
fputc(uokpo.str, fs);
}
fclose(fs);
}
//---------------------------------------------------------------------------
void __fastcall TForm1::LoadClick(TObject *Sender)
{
union okpo
{
double num;
char str[8];
};
union okpo uokpo;
FILE *fs;
[COLOR=firebrick] fs=fopen("temp.txt", "rb");[/COLOR]
for(int i=0;i<8;i++)
{
uokpo.str=fgetc(fs);
}
fclose(fs);
Edit1->Text=uokpo.num;
}
Ниже приведен код, в кратце - сохраняет введеннное вещественное число на диск, по нажатию кнопки загружает его в Edit1.
По идее все должно быть тихо и гладко, все числа сохраняет/загружает, вот только при вводе числа 2766077 при загрузке выдает NAN - нечисло , обьясните пожалуйста в чем глюк. Еще есть одно число незапомнил точно какое ввожу nnnnnnnnnn,15 а при загрузке выдает nnnnnnnnnn,1 =(.
void __fastcall TForm1::SaveClick(TObject *Sender)
{
union okpo
{
double num;
char str[8];
};
union okpo uokpo;
uokpo.num=StrToFloat(Edit1->Text);
AnsiString fspr;
FILE *fs;
[COLOR=firebrick] fs=fopen("temp.txt", "wb");[/COLOR]
for(int i=0;i<8;i++)
{
fputc(uokpo.str, fs);
}
fclose(fs);
}
//---------------------------------------------------------------------------
void __fastcall TForm1::LoadClick(TObject *Sender)
{
union okpo
{
double num;
char str[8];
};
union okpo uokpo;
FILE *fs;
[COLOR=firebrick] fs=fopen("temp.txt", "rb");[/COLOR]
for(int i=0;i<8;i++)
{
uokpo.str=fgetc(fs);
}
fclose(fs);
Edit1->Text=uokpo.num;
}
AFAIR, надо так, как я красным выделил.
Объяснить, почему?
Цитата:
Originally posted by Plisteron
AFAIR, надо так, как я красным выделил.
Объяснить, почему?
AFAIR, надо так, как я красным выделил.
Объяснить, почему?
Спасибо огромное, работает. Обьяснение тоже было бы очень кстати для понимания сути =)
Цитата:
Originally posted by ReaLeter
Спасибо огромное, работает. Обьяснение тоже было бы очень кстати для понимания сути =)
Спасибо огромное, работает. Обьяснение тоже было бы очень кстати для понимания сути =)
Когда ты пишешь:
Код:
У тебя в массиве str записано 8 байт с различными значениями от '\x0' до '\xFF'. Конкретные значения, будем считать, нам неизвестны, они зависят, понятно, от текста в Edit1.
Открываем файл на чтение конструкцией fs=fopen("temp.txt", "r"); -- файл открывается на чтение в текстовом режиме, т.е. принимается, что строка заканчивается на '\x0A', по достижении значения '\x1A' (EOF, сиречь End-of-File) чтение файла прекращается. В твоём случае EOF твоей восьмибайтовой строки был достигнут уже на втором байте (видимо, такое числовое значение было введено в Edit1).
Конструкции fs=fopen("temp.txt", "wb"); и fs=fopen("temp.txt", "rb"); говорят, что файл надо открывать в двоичном виде и читать не до EOF, а до реального конца файла вместе с любыми non-ASCII-символами.
Кстати, я бы немного по-другому юнион сделал, приблизительно так:
Код:
typedef union union_okpo
{
double num;
char str[sizeof(double)];
} okpo;
FILE *fs;
okpo uokpo = StrToFloat(Edit1->Text);
// ^^^ Кстати, а если юзер нечисловое значение в Edit1 введёт?
size_t howmuch_bytes = sizeof(okpo);
if((fs = fopen("temp.txt", "wb")) != NULL && fwrite(&uokpo, howmuch_bytes, 1, fs) == howmuch_bytes * 1)
/* Если будет массив окпов (или окпей?), то вместо единичек в fwrite() и в howmuch_bytes * 1
будет размерность массива */
{
/* Всё записано нормально, едем дальше */
fclose(fs);
}
else
{
/* Обработка ошибки записи*/
}
{
double num;
char str[sizeof(double)];
} okpo;
FILE *fs;
okpo uokpo = StrToFloat(Edit1->Text);
// ^^^ Кстати, а если юзер нечисловое значение в Edit1 введёт?
size_t howmuch_bytes = sizeof(okpo);
if((fs = fopen("temp.txt", "wb")) != NULL && fwrite(&uokpo, howmuch_bytes, 1, fs) == howmuch_bytes * 1)
/* Если будет массив окпов (или окпей?), то вместо единичек в fwrite() и в howmuch_bytes * 1
будет размерность массива */
{
/* Всё записано нормально, едем дальше */
fclose(fs);
}
else
{
/* Обработка ошибки записи*/
}
Дальше аналогично с чтением.
Цитата:
Originally posted by Plisteron
файл надо открывать в двоичном виде и читать не до EOF, а до реального конца файла
файл надо открывать в двоичном виде и читать не до EOF, а до реального конца файла
Спасибо за разяснение.
Цитата:
Originally posted by Plisteron
Кстати, я бы немного по-другому юнион сделал, приблизительно так:
Дальше аналогично с чтением.
Кстати, я бы немного по-другому юнион сделал, приблизительно так:
Код:
typedef union union_okpo
{
double num;
char str[sizeof(double)];
} okpo;
FILE *fs;
okpo uokpo = StrToFloat(Edit1->Text);
// ^^^ Кстати, а если юзер нечисловое значение в Edit1 введёт?
size_t howmuch_bytes = sizeof(okpo);
if((fs = fopen("temp.txt", "wb")) != NULL && fwrite(&uokpo, howmuch_bytes, 1, fs) == howmuch_bytes * 1)
/* Если будет массив окпов (или окпей?), то вместо единичек в fwrite() будет размерность массива */
{
/* Всё нормально, едем дальше */
}
else
{
/* Обработка ошибки записи*/
}
{
double num;
char str[sizeof(double)];
} okpo;
FILE *fs;
okpo uokpo = StrToFloat(Edit1->Text);
// ^^^ Кстати, а если юзер нечисловое значение в Edit1 введёт?
size_t howmuch_bytes = sizeof(okpo);
if((fs = fopen("temp.txt", "wb")) != NULL && fwrite(&uokpo, howmuch_bytes, 1, fs) == howmuch_bytes * 1)
/* Если будет массив окпов (или окпей?), то вместо единичек в fwrite() будет размерность массива */
{
/* Всё нормально, едем дальше */
}
else
{
/* Обработка ошибки записи*/
}
Дальше аналогично с чтением.
sizeof() мне неподходит так как есть существующий файл с четкой структурой одной записи - 2 байта номер int, 8 байт второй номер float, 8 байт окпо float, 30 байт название в кодировке DOS и т.д. Проверку на нечисловое проверяю при наборе в Edit1.
Спасибо за fwrite(&uokpo, howmuch_bytes, 1, fs) избавлюсь от цикла =), жалко одно, так как юнионы разных размеров и чар массив в одной записи, что нельзя одну запись в файл скопом вывести =(.
Цитата:
Originally posted by ReaLeter
Спасибо за разяснение.
sizeof() мне неподходит так как есть существующий файл с четкой структурой одной записи - 2 байта номер int, 8 байт второй номер float, 8 байт окпо float, 30 байт название в кодировке DOS и т.д. Проверку на нечисловое проверяю при наборе в Edit1.
Спасибо за fwrite(&uokpo, howmuch_bytes, 1, fs) избавлюсь от цикла =), жалко одно, так как юнионы разных размеров и чар массив в одной записи, что нельзя одну запись в файл скопом вывести =(.
Спасибо за разяснение.
sizeof() мне неподходит так как есть существующий файл с четкой структурой одной записи - 2 байта номер int, 8 байт второй номер float, 8 байт окпо float, 30 байт название в кодировке DOS и т.д. Проверку на нечисловое проверяю при наборе в Edit1.
Спасибо за fwrite(&uokpo, howmuch_bytes, 1, fs) избавлюсь от цикла =), жалко одно, так как юнионы разных размеров и чар массив в одной записи, что нельзя одну запись в файл скопом вывести =(.
Млын...
Код:
typedef struct my_hard_record
{
int number;
double number2;
okpo uokpo;
char name[30];
int i_t_d;
} hard_record;
hard_record x;
{
int number;
double number2;
okpo uokpo;
char name[30];
int i_t_d;
} hard_record;
hard_record x;
И записываешь всю структуру одним fwrite();
а sizeof применена для того, чотбы код переносимый получить. Это под Win32 double 8 байт занимает, а вдруг ты, например, под IBM AS400 или Itanium прогу пишешь? Кто знает, сколько байт там double?