2015-10-29 3 views
0

Так вот что я получил:Зачем писать странные вещи?

#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 
#include <ctype.h> 
#include <math.h> 

int main() 
{ 

FILE *fin; 
struct STR { 
    float d; 
    int x; 
} testing; 

testing.d = 11.12; 
testing.x = 31121; 


    fin = fopen("output.txt", "w"); 
    //fprintf(fin,"%7.4f %7d\n",testing.d,testing.x); 
    fwrite(&testing, sizeof(struct STR),1,fin); 
    fclose(fin); 
    return 0; 
} 

Так что же происходит, когда я скомпилировать и запустить? Я получаю это:

"…ë1A‘y " 

Когда я закомментируйте fwrite и использовать fprintf, я получаю это:

"11.1200 31121" 

Может кто-нибудь объяснить мне это? Я попытался запустить его на windows и linux, и оба раза вывод был неясным.

Кроме того, я думаю, что, пока мы находимся на тему, как размер текстового файла с «11.1200 31121» равен 16 байтам? Я думал, что целые числа (на 32-битной машине) равны по 4 байта? Это 16 байт, потому что в txt-файле содержится 16 общих символов?

Благодаря

+1

'fprintf()' преобразует числа в формат для чтения человеком в соответствии с типом номера (int, float и т. Д.), А 'fwrite()' записывает число в двоичном формате, точно как он хранится в памяти , когда вы используете 'fwrite()' для сохранения struct, вы используете 'fread()' для чтения в struct, не нужно делать преобразования. но 'fprintf' вам придется делать некоторые преобразования из текста обратно в двоичный формат, и это преобразование обрабатывается функциями' sscanf() 'и аналогичными – milevyo

ответ

0

Вы открываете файл в виде текстового файла, но вы пишете двоичные данные, это не человек для чтения. Чтобы правильно его прочитать, вам нужно fread(). Вместо этого fprintf() пишет текст, как вы можете проверить.

Так

#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 
#include <ctype.h> 
#include <math.h> 

struct STR { 
    float d; 
    int x; 
} testing; 

int main() 
{ 

    FILE *file; 
    testing.d = 11.12; 
    testing.x = 31121; 


    file = fopen("output.txt", "wb"); 
    if (file != NULL) 
    { 
     fwrite(&testing, sizeof(struct STR), 1, file); 
     fclose(file); 
    } 

    file = fopen("output.txt", "rb"); 
    if ((file != NULL) && (fread(&testing, sizeof(struct STR), 1, file) == 1)) 
    { 
     fprintf(stdout, "%f -- %d\n", testing.d, testing.x); 
     fclose(file); 
    } 

    return 0; 
} 

должны четко.

0

Как сказал iharob, вы пишете двоичные данные, которые интерпретируются как бессмысленные символы в текущей локали, а не для человека, читаемые ASCII. Кроме того, причина, по которой ваш компилятор выделяет шестнадцать байтов в структуру, - это заполнение. Причина, по которой компилятор составляет 16 байтов, заключается в том, что ваш процессор имеет специальные инструкции для более эффективного индексирования массивов структур, когда их размер малой мощности равен двум.

Если вы действительно хотите сериализовать свои данные в переносном двоичном формате или передать его по сети, вы должны использовать тип точной ширины, такой как int32_t, а не int (который был 16, 32 или 64 бит и могут иметь другую ширину, чем таковые), а также преобразовать в определенную консистенцию, а не в какой бы то ни было порядок нативного байта. Классическим решением является htonl(). Кроме того, выпишите каждое поле отдельно, чтобы избежать проблем с заполнением или использовать расширение компилятора, чтобы упаковать структуру и отключить отладку.

Смежные вопросы