I want to read the 4 first bytes from a binnary file which is a song.wav type. In a .wav file the 4 first bytes must be 52-46-49-49 and I have to read them to check later if they are true.
The thing is that I have a compile arror at the fread line which says invalid conversion from "unsigned char" to "void" and initialzing argument 1 of 'size_t fread(void*,size_t,size_t,FILE*) and i dont know what it means.
I saw in a previous topic tha this is the way that fread must be done if i want to read byte by byte. If anyone has any idea of how i can read byte by byte and store them in an array that be great. Thank you.
void checksong(char *argv[]){
FILE *myfile;
int i;
unsigned char k[4];
myfile=fopen(argv[2],"r");
i=0;
for(i=0; i<4; i++){
fread(k[i],1,1,myfile);
}
for(i=0; i<4; i++){
printf("%c\n", k[i]);
}
return ;
}
It is a single error:
Invalid conversion from unsigned charto void* initializing argument 1 of
size_t fread(void*,size_t,size_t,FILE*)
It means k[i] is an unsigned char, and not a pointer. You should use &k[i] or k+i.
However, you don't really need to read byte by byte. You can read 4 bytes, no loops involved:
fread(k, 4, 1, myfile);
Printing the numbers:
for (i=0; i<4; i++)
printf("%d\n", k[i]);
In order to read exactly one byte and store it into k at index i, you need to provide the address of element i
for(i=0; i<4; i++){
fread(&k[i],1,1,myfile);
}
However, you'd rather read the whole 4 bytes in one go if you're interested in them 4. So no for loop at all, and just do:
fread(k,1,4,myfile);
It is also good practice to test the return code of fread (and any I/O operation for that matter) in case it fails. man fread for more information.
You can use just
char buffer[4];
fread(buffer,1,4,myfile);
you need not to use fread() Even the fgetc() works well. Simple coding. SImple as reading a text file.
#include <stdio.h>
int main(int argc, char** argv)
{
FILE* f = fopen("lak", "rb");
fseek(f,0,SEEK_END);
long lsize=0,i=0;
lsize = ftell(f);
rewind(f);
while(i<lsize){
int first = fgetc(f);
i++;
printf("first byte = %x\n", (unsigned)first); //you can do anything with
//first now
}
fclose(f);
return 0;
}
Related
Can some one explain me how to read content from a binary file?
I have done this:
FILE *fp;
int a[50];
fp=fopen("x.exe","rb");
while(fread(&a,sizeof(a),1,fp)==1)
{
printf("%d",a);
}
suppose that file only contain integer values.
Also I tired writing into a file using structures, and I can easily read&write contents of it, but when I try reading some other binary file I just got garbage value.
Or is it impossible to read a .exe file compliled and linked?
the correct way is:
int myreadfile(void)
{
FILE *fp;
int i, n;
unsigned char a[50];
if (!(fp=fopen("x.exe","rb"))) return(0);
while(n=fread(a,1,sizeof(a), fp))
{
for (i=0; i<n; i++)
printf("%02x ",a[i]);
printf("\n");
}
fclose(fp);
return 1;
}
Note that the buffer is of type unsigned char. That is because
a) you don't know if the file is a complete number of ints (but it is of char, i.e. bytes) and
b) in the printf call, the char will be converted to intand would the high bit of the char be a 1, it would be sign-extended, which we don't want.
Also, fread does not try to read a whole buffer but just any number of bytes still in the file (to a maximum of the buffer).
I need to be able to make sure my array is correctly receiving values from the file card.raw through fread.
I am not confident about using arrays with pointers, so if anybody could help me with the theory here, it would be GREATLY appreciate it. Thanks in advance.
The code is supposed to take literally one block of size 512 bytes and stick it into the array. Then I am just using a debugger and printf to examine the arrays output.
/**
* recover.c
*
* Computer Science 50
* Problem Set 4
*
* Recovers JPEGs from a forensic image.
*/
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
int main(int argc, char* argv[])
{
//Size of EACH FAT JPEG in bytes
#define FILESIZE 512
unsigned char* buffer[FILESIZE];
///Step 1: Open jpeg
FILE* readfrom = fopen("card.raw", "rb");
if (readfrom == NULL)
{
printf("Could not open");
}
///Step 2: Find Beginning of JPEG. The first digits will be 255216255 Then 224 or 225
fread(&buffer, FILESIZE, 1, readfrom);
for(int x = 0; x < FILESIZE; x++)
{
printf("%d = %c\n", x, buffer[x]);
}
fclose(readfrom);
}
Use return values from input functions. fread() reports how many elements were read - code might not have read 512. Swap FILESIZE, 1 to detect the number of characters/bytes read.
// fread(&buffer, FILESIZE, 1, readfrom);
size_t count = fread(&buffer, 1, FILESIZE, readfrom);
Only print out up to the number of elements read. Recommend hexadecimal (and maybe decimal) output rather than character.
for(size_t x = 0; x < count; x++) {
// printf("%d = %c\n", x, buffer[x]);
printf("%3zu = %02X % 3u\n", x, buffer[x], buffer[x]);
}
If the fopen() failed, best to not continue with for() and fclose().
if (readfrom == NULL) {
printf("Could not open");
return -1;
}
The second parameter is size, in bytes, of each element to be read.
The third parameter is Number of elements each one with a size of the <second parameter> bytes.
So, swap your second and first parameters.
Replace unsigned char* buffer[FILESIZE]; with unsigned char buffer[FILESIZE];. For now, you have an array of unsigned char *, when you need unsigned char. Because buffer is already a pointer, you don't need to take its address. In fread call, replace &buffer with buffer.
It must go like this: fread(buffer, 1, FILESIZE, readfrom);
One more thing: add return with a specific error code after printf("Could not open");, because if file hasn't been open, you cannot read from it, can you? And add return 0; in the end of main.
And take your #define out of main.
Read more about fread here: http://www.cplusplus.com/reference/cstdio/fread/
I wrote a small program to get the magic number from an .au file and print it to console, but every time I try, instead of getting the intended .snd, I get .snd$ instead.
I'm not sure why this is happening, considering that I'm only reading in 4 bytes, which is what the magic number is comprised of. So, where is the extra character coming from?
#include <stdio.H>
int main()
{
FILE *fin;
int r;
char m[4], path[20];
scanf("%s", path);
fin = fopen(path, "r");
r = fread(&m, sizeof(char), 4, fin);
printf("magic number is %s\n", m);
return 0;
}
You're printing it as though it were a string, which in C, means that it's NUL-terminated. Change your code like this and it will work as you expect:
char m[5];
m[4] = '\0'; /* add terminating NUL */
Also, you should be aware that scanf is a dangerous function. Use a command line argument instead.
The problem is not how you are reading.
The problem is that your variable is only 4 chars length, and it needs a null character to indicate the end.
printf with %s will print the content of the variable until reach a null character, until that it can print garbage if your variable is not correctly ended.
To fix you can have a bigger variable and set the [4] char with null.
How the new code should look like:
#include <stdio.H>
int main()
{
FILE *fin;
int r;
char m[5], path[20];
scanf("%s", path);
/*Scanf can be dangerous because it can cause buffer overflow,
it means that you can fill your variable with more bytes than it supports, which can end up being used for buffer overflow attacks:
See more: http://en.wikipedia.org/wiki/Buffer_overflow */
fin = fopen(path, "r");
r = fread(&m, sizeof(char), 4, fin);
m[4] = '\0';
printf("magic number is %s\n", m);
return 0;
}
code doesnt accept values from file since when i print some garbage pops up
the file is a textfile with a letter representing a status, and theres a number. there are 5 sets of these , each on new line the letter and the number is seperated with a space, i need to get the numbers in one array
#include <stdio.h>
#include <stdlib.h>
typedef struct {
char status;
int number;
} information;
int main() {
int array[5] = {0};
int i;
FILE *pointer = fopen("transaction22.txt", "r");
information information1;
for (i = 0; i < 5; i++) {
fread(&information1, sizeof(information1), 1, pointer);
array[i] = information1.number;
printf("%d", information1.number);
}
return 0;
}
You can use fscanf instead of fread as:
fscanf(pointer, "%s %d", info1.status, &info1.number);
where status will be defined as char status[2]; inside struct information.
fread is used for reading raw bytes (blocks of data) from a file.
Now, you are using a text file and trying to read sizeof(info) amount of data which is 5 bytes of data (assuming 32-bit int), therefore what you get after first fread is:
info1.status (1 byte) info1.number (4 bytes)
Byte 1 SPACE + number + NEWLINE + [One more byte]
read by fread (next four bytes read by fread)
Thus info1.number is storing a garbage value.
Also the successive fread call starts reading after the data read by previous fread.
Better to use a character array like c[5]. and replace this is with struct. variable in fread ..like in for loop
fread(c,sizeof(c),1,pointer)
than use
print("%s\n",c);
I'm trying to read the following binary (01100001) from a file and convert it to ascii code (97), but when using fread i'm getting a very big numbers.
the file "c:/input.txt" contain only the following line -01100001
printf of the array values print big numbers, such as 825241648
My code:
int main()
{
unsigned int arr[8];
int cnt,i,temp=0;
FILE * input;
if(!(input=fopen("C:/input.txt","r")))
{
fprintf(stderr,"cannot open file\n");
exit(0);
}
cnt = fread(arr,1,8,input);
for(i=0;i<cnt;i++)
{
printf("%d\n",arr[i]);
}
return 0;
}
any idea why?
arr is an array of integers. But you read only 8 bytes into it. So your first integer will have some large value, and so will your second, but after that they will have garbage values. (You made arr an "automatic" variable, which is allocated on the stack, so it will have random garbage in it; if you made it a static variable it would be pre-initialized to zero bytes.)
If you change the declaration of arr so that it is of type char, you can read your string in, and your for loop will loop over those bytes one at a time.
Then you can write a string-to-binary translator, or alternatively you could use strtol() to do the conversion with the base set to 2. strtol() is not available in all compilers; GCC is fine but Microsoft C doesn't have it.
Pl. see if the code (Compiled using gcc on Linux) below works for this.
#include<stdio.h>
#include<stdlib.h>
int main()
{
char arr[8];
int cnt,i,temp=0;
FILE * input;
if((input=fopen("data","r"))==NULL)
{
fprintf(stderr,"cannot open file\n");
exit(1);
}
//Read the 8 bytes in a character array of size 8
cnt = fread(arr,1,8,input);
for (i = 0; i < cnt; i++)
{
//Now change it to 0/1 form by substracting 48
arr[i] = arr[i] - '0';/* Ascii of 0 = 48*/
//Also Left shift..
arr[i] = arr[i] << (cnt - (i+1));
//Now Bit wise OR with the integer...
temp = temp | arr[i];
}
printf("The ascii value is %d and the character is %c\n", temp, temp);
return 0;
}
You first declare unsigned int arr[8]; which means 8 integers or more precisely 8*4=32 bytes. After that you read 8 bytes and then again try to output 8 integers. I suppose you want to read 8 bytes and output them as numbers? If you change type int to char, code might work. If file size is 32 bytes and contains integers, you may want to change fread() like this: fread(arr,sizeof(int),8,input);