How does fread() know where to look in a .wav file? [duplicate] - c

Simple question,
When i use fread:
fread(ArrayA, sizeof(Reg), sizeBlock, fp);
My file pointer, fp is moved ahead?

Answer: Yes, the position of the file pointer is updated automatically after the read operation, so that successive fread() functions read successive file records.
Clarification: fread() is a block oriented function. The standard prototype is:
size_t fread(void *ptr,
size_t size,
size_t limit,
FILE *stream);
The function reads from the stream pointed to by stream and places the bytes read into the array pointed to by ptr, It will stop reading when any of the following conditions are true:
It has read limit elements of size size, or
It reaches the end of file, or
A read error occurs.
fread() gives you as much control as fgetc(), and has the advantage of being able to read more than one character in a single I/O operation. In fact, memory permitting, you can read the entire file into an array and do all of your processing in memory. This has significant performance advantages.
fread() is often used to read fixed-length data records directly into structs, but you can use it to read any file. It's my personal choice for reading most disk files.

Yes, calling fread does indeed move the file pointer. The file pointer will be advanced by the number of bytes actually read. In case of an error in fread, the file position after calling fread is unspecified.

Yes, The fp will be advanced by the total amount of bytes read.
In your case the function fread reads sizeBlock objects, each sizeof(Reg) bytes long, from the stream pointed to by fp, storing them at the location given by ArrayA.

Yes, it does. It could be checked by using ftell() function in order to show current position (in fact, bytes read so far), take a look it:
int main() {
typedef struct person {
char *nome; int age;
} person;
// write struct to file 2x or more...
FILE *file = fopen(filename, "rb");
person p;
size_t byteslength = sizeof(struct person);
printf("ftell: %ld\n", ftell(file));
fread(&p, byteslength, 1, file);
printf("name: %s | age: %d\n", p.nome, p.idade);
printf("ftell: %ld\n", ftell(file));
fread(&p, byteslength, 1, file);
printf("name: %s | age: %d\n", p.nome, p.idade);
//...
fclose(file);
return 0;
}

Related

C redirect fprintf into a buffer or char array

I have the following function and I am wondering if there is a way to pass string or char array instead of stdout into it so I can get the printed representation as a string.
void print_Type(Type t, FILE *f)
{
fprintf(f,"stuff ...");
}
print_Type(t, stdout);
I have already tried this:
int SIZE = 100;
char buffer[SIZE];
print_Type(t, buffer);
But this is what I am seeing:
�����
Something like this
FILE* f = fmemopen(buffer, sizeof(buffer), "w");
print_Type(t, f);
fclose(f);
The fmemopen(void *buf, size_t size, const char *mode) function opens a stream. The stream allows I/O to be performed on the string or memory buffer pointed to by buf.
Yes there is sprintf() notice the leading s rather than f.
int SIZE = 100;
char buffer[SIZE];
sprintf(buffer, "stuff %d", 10);
This function prints to a string s rather than a file f. It has exactly the same properties and parameters to fprintf() the only difference is the destination, which must be a char array (either statically allocated as an array or dynamical allocated (usually via malloc)).
Note: This function is dangerous as it does not check the length and can easily overrun the end of the buffer if you are not careful.
If you are using a later version of C (c99). A better function is snprintf this adds the extra buffer length checking.
The problem with fmemopen is that it cannot resize the buffer. fmemopen did exist in Glibc for quite some time, but it was standardized only in POSIX.1-2008. But that revision included another function that handles dynamic memory allocation: open_memstream(3):
char *buffer = NULL;
size_t size = 0;
FILE* f = open_memstream(&buffer, &size);
print_Type(t, f);
fclose(f);
buffer will now point to a null-terminated buffer, with size bytes before the extra null terminator! I.e. you didn't write null bytes, then strlen(buffer) == size.
Thus the only merit of fmemopen is that it can be used to write to a fixed location memory buffer or fixed length, whereas open_memstream should be used everywhere else where the location of the buffer does not matter.
For fmemopen there is yet another undesired feature - the writes may fail when the buffer is being flushed and not before. Since the target is in memory, there is no point in buffering the writes, so it is suggested that if you choose to use fmemopen, Linux manual page fmemopen(3) recommends disabling buffering with setbuf(f, NULL);

C Fread Split Textfile into Chunks

i've got a Textfile of Unknown Size and have to send it via Sockets from my Server to the Client in Chunks of a certain (variable Size).
How can i use Fread for that Task? I read alot about Fread but im Struggeling with the kind of Pointer i should pass that function in my Case?
size_t fread ( void * ptr, size_t size, size_t count, FILE * stream );
How can i use fread for that task?
Simply keep sending chunks (of fixed size) from the Server to the Client, until there is nothing else to be sent by the Serve.
What kind of pointer I should pass that function in my case?
Anything.
Check fread()'s example, where the buffer that is passed in fread() is of type char, and fread() simply allows for it, since the first argument of that function is:
size_t fread ( void * ptr, size_t size, size_t count, FILE * stream );
So just pass the array you are using to store the data (the chunks) to the function.
To read file as chunks and send them to socket you'll have to decide a size of the chunk.
For example: 4096 is perfect size that's not too big or not too small!
Example
We choose 4096 bytes as the chunk size. It's btw customizable.
Send the chunk data to the Client when received from file.
#include <stdio.h>
int main(ssize_t argc, char** argv)
{
// We're going to use "rb" because in (WINDOWS) you need it!
FILE* fp = fopen(argv[1], "rb");
char byte_buffer[4096];
size_t bytes_read = 0;
while(( bytes_read = fread(&byte_buffer, 4096, 1, fp) )> 0)
send_data_chunk_to_client_somehow(/* your parameters here */);
}
The text file should be read in chunks and send them to the Client.
fread(3) ― Binary stream I/O
fread(3) is compatible with both text and binary streams, it's a part of ANSI C. The POSIX read(3) is a equivalent to the function and faster than it.
size_t fread(void* ptr, size_t size, size_t nmemb, FILE* fp);

Strange value when reading from binary file with fread() in C

I have an issue that I can't solve...
I used fwrite to write an int value (among other values that come from a struct) into a file that I've opened using fopen(file, "wb");
This worked fine, and when I view the contents of the file, I can see the HEX value of the int that I've "written" (and all the other values as well).
Next, I try to read the file. So, I open the file using fopen(file, "rb"); and start reading it using fread. The first int value is read correctly (e.g. 7) and all the other values after it - which belong to the first struct that I've written.
I then try to read the next struct and when I try to read the first int value, I receive a very strange number (e.g. 1140850688) but it should be 39 instead.
So the question is: Why is this happening? And how can I solve it?
My struct looks like this:
struct a {
int a1;
char* a2;
struct b* a3;
unsigned char a4;
int a5;
char* a6;
}
And the fread call looks like this: fread(&(tmpA->a1), sizeof(int), 1, file);
EDIT:
The fwrite part:
fwrite(&(tmpA->a1), sizeof(int), 1, file);
fwrite(tmpA->a2, sizeof(char), strlen(tmpA->a2), file);
fwrite(tmpA->a3, sizeof(struct b), 1, file);
fwrite(&(tmpA->a4), sizeof(unsigned char), 1, file);
fwrite(&(tmpA->a5), sizeof(int), 1, file);
fwrite(tmpA->a6, sizeof(char), strlen(tmpA->a6), file);
The fread is almost the same.
I suspect your problem is on this line
fwrite(tmpA->a3, sizeof(struct b), 1, file);
where you are writing a struct. This struct will have padding bytes, as per this wikipedia article which will offset the rest of your data. You will likely have to come up with a better way of writing that struct to memory. This page provides additional explanation.
You can check to see if this is indeed the problem by checking if a4 has the value you expect, or by comparing the size of the entire struct versus the sum of the sizes of its members.
Also, these lines look dangerous:
fwrite(tmpA->a2, sizeof(char), strlen(tmpA->a2), file);
fwrite(tmpA->a6, sizeof(char), strlen(tmpA->a6), file);
they say that the length of the string being printed may vary in your stored data. strlen will give you the length of your string without counting the terminating \0 so there is no good way to know where a string ends once you've written it. I can't imagine how you plan on reading the string back in.
If you wrote a struct from a file, you should read a struct back; trying to read an int is not going to work. However, it rarely, if ever, makes sense two write out as binary a struct that contains pointers. You should either make them arrays of fixed size, or serialize them separately from your struct.
EDIT : (in response to posted code) Most likely the problem has to do with writing an unknown number of characters in the second call of fwrite. When you serialize a C string, you should write out the number of characters before writing the characters themselves, so that when you read you'd know how much characters to allocate and to read back:
int len = strlen(tmpA->a2);
fwrite(&len, sizeof(int), 1, file);
fwrite(tmpA->a2, sizeof(char), len, file);
...
fread(&(tmpA->a1), sizeof(int), 1, file);
tmpA->a2 = malloc(tmpA->a1+1);
fread(tmpA->a2, sizeof(char), tmpA->a1, file);
tmpA->a2[tmpA->a1] = '\0';

Does fread move the file pointer?

Simple question,
When i use fread:
fread(ArrayA, sizeof(Reg), sizeBlock, fp);
My file pointer, fp is moved ahead?
Answer: Yes, the position of the file pointer is updated automatically after the read operation, so that successive fread() functions read successive file records.
Clarification: fread() is a block oriented function. The standard prototype is:
size_t fread(void *ptr,
size_t size,
size_t limit,
FILE *stream);
The function reads from the stream pointed to by stream and places the bytes read into the array pointed to by ptr, It will stop reading when any of the following conditions are true:
It has read limit elements of size size, or
It reaches the end of file, or
A read error occurs.
fread() gives you as much control as fgetc(), and has the advantage of being able to read more than one character in a single I/O operation. In fact, memory permitting, you can read the entire file into an array and do all of your processing in memory. This has significant performance advantages.
fread() is often used to read fixed-length data records directly into structs, but you can use it to read any file. It's my personal choice for reading most disk files.
Yes, calling fread does indeed move the file pointer. The file pointer will be advanced by the number of bytes actually read. In case of an error in fread, the file position after calling fread is unspecified.
Yes, The fp will be advanced by the total amount of bytes read.
In your case the function fread reads sizeBlock objects, each sizeof(Reg) bytes long, from the stream pointed to by fp, storing them at the location given by ArrayA.
Yes, it does. It could be checked by using ftell() function in order to show current position (in fact, bytes read so far), take a look it:
int main() {
typedef struct person {
char *nome; int age;
} person;
// write struct to file 2x or more...
FILE *file = fopen(filename, "rb");
person p;
size_t byteslength = sizeof(struct person);
printf("ftell: %ld\n", ftell(file));
fread(&p, byteslength, 1, file);
printf("name: %s | age: %d\n", p.nome, p.idade);
printf("ftell: %ld\n", ftell(file));
fread(&p, byteslength, 1, file);
printf("name: %s | age: %d\n", p.nome, p.idade);
//...
fclose(file);
return 0;
}

How can I return file contents from a function?

I am writing a C library. I want to return the contents of a file from this function to the caller.
How can I convert the file contents to char[]?
fopen is crashing since I am using perl.h in my C code.
Is there any other way to convert file into a char array apart from opening & reading the file?
Here is my code:
FILE* fp = fopen("console.txt", "r");
char message[1024];
strcpy(message,"\n");
char buf[80];
while(!feof(fp))
{
fgets(buf, sizeof(buf)-1, fp);
strcat(message, buf);
}
Get the file size (see How can I get a file's size in C?)
Allocate memory to store contents of the file (see malloc).
Read contents of the file into allocated memory (see read).
Return a pointer and a length of data in bytes to the user.
Don't forget to check for errors in between those steps.
You need to do a few things
Determine size of file (checkout fstat/stat)
You need to malloc enough memory to hold the file
You can then use fread to read the conents of the file into your array (dont forget to open the file in binary mode)
Return you pointer (and dont forget that it has to be freed after by the function caller)
Try this code. The function returns the string with file content, just print it.
#include <stdio.h>
#include <stdlib.h>
char *readFile(char *filename)
{
char * buffer = 0;
long length;
FILE * f = fopen (filename, "r");
if (f)
{
fseek (f, 0, SEEK_END);
length = ftell (f);
fseek (f, 0, SEEK_SET);
buffer = malloc (length);
if (buffer)
{
fread (buffer, 1, length, f);
}
fclose (f);
}
return buffer;
}
int main()
{
char *content=readFile("D://test1.xml");
printf("%s",content);
return 0;
}
Bit more information is required to give a good answer as the contents and nature of the file is required.
But generally,
If it is a text file see the stdio library - you can get the length, create an array and fill it. Otherwise (binary files) parsing it would be a good idea and return a data structure - a lot more useful

Resources