Какова роль второго параметра и третьего параметра в fwrite ()?Почему нам нужен 3rcount здесь? - PullRequest
2 голосов
/ 09 февраля 2012

Привет fwrite () подписи выглядит следующим образом:

size_t fwrite ( const void * ptr, size_t size, size_t count, FILE * stream );

http://msdn.microsoft.com/en-us/library/h9t88zwz.aspx

Я не понял разницу между 2-й параметр "размер" и 3-й параметр "count "?

Означает ли это, что размер данных, скопированных из буфера в файл, имеет размер" size ".И какую роль здесь должен сыграть отсчет.??

Ответы [ 3 ]

3 голосов
/ 09 февраля 2012

Предположим, у вас есть массив как:

T a[N]; //T is the type of each element
        //and N is the number of elements in the array
//fill the array here

Теперь вы хотите записать этот массив, используя fwrite, поэтому вы передаете a в качестве первого аргумента как:

fwrite(a, ..... ); 

Теперь, как fwrite узнает, сколько байтов нужно записать? Он не может знать это из своего первого аргумента, потому что a преобразуется в const void*, что приводит к потере большого количества полезной информации, такой как тип каждого элемента в массиве 1 , тем самым мог бы рассчитать размер каждого элемента, но эта информация теряется в тот момент, когда вы передаете a в качестве первого аргумента. Таким образом, вам нужно передать размер каждого элемента как:

fwrite(a, sizeof(T), ....);

Теперь fwrite знает адрес (или указатель), с которого он будет читать элементы, а также знает размер каждого элемента. Но он все еще не знает , сколько элементов . Таким образом, вы передаете количество элементов в массиве, как:

fwrite(a, sizeof(T), N, ...);

И теперь он знает все о данных. Теперь все, что нужно знать, это указатель файла. Итак, здесь вы пишете это как:

FILE *fp = /*.....*/ ;
fwrite(a, sizeof(T), N, fp);

Надеюсь, это поможет.


1. Когда a преобразуется в const void*, он также теряет другую полезную информацию, которая является числом элементов. Но в C вы не можете передать массив в качестве аргумента. Когда вы это сделаете, он превратится в указатель, потеряв информацию о размере массива. fwrite - это функция из библиотеки C. Однако, если вы используете fwrite в C ++, вы можете заключить его в шаблон функции следующим образом:

template<typename T, size_t N>
size_t fwrite(T (&a)[N], FILE *fp)
{
   return fwrite(a, sizeof(T), N, fp); //call the C function here
}

Тогда вы можете просто назвать это как:

int a={1,2,3,4,5,6,7};
double b={10,20,30,40,50,60,70};

fwrite(a,fp); 
fwrite(b,fp); 

Хорошо выглядит? Но вы не можете передать указатель на это:

float *c = new float[100];

fwrite(c,fp); //compilation error

Это потому, что наш шаблон функции fwrite будет принимать только массив, а не указатель.

3 голосов
/ 09 февраля 2012

вы пишете COUNT вещи, каждая из которых имеет размер SIZE.

Итак, если у вас есть массив из 50 структур FooBar, вы должны сделать:

fwrite( some_pointer, sizeof(FooBar), 50, some_stream );

Таким образом, вы могли бы всегда устанавливать размер в 1 и вместо этого писать:

fwrite( some_pointer, 1, 50 * sizeof(FooBar), some_stream);

но я считаю, что первый способ, если не сказать больше, гораздо легче читать и меньше подвержен ошибкам.

1 голос
/ 09 февраля 2012

Размер - это размер каждого элемента, который вы хотите написать.Если это байты, вы должны использовать 1, в противном случае используйте sizeof(whatever).

Количество - это число элементов, которые вы хотите записать.

...