I am trying to solve a problem which requires me to read a file and generate another file which has the same contents as the original but every fourth byte removed.I tried it doing this way ...
int main()
{
FILE *p;
FILE *q;
int i=0,k=0;
char c;
p = fopen("C:\\Users\\Teja\\Desktop\\Beethoven.raw","rw");
q = fopen("C:\\Users\\Teja\\Desktop\\Beethoven_new.raw","w+");
printf("%x is the EOF character \n",EOF);
while((c=fgetc(p))!=EOF)
{
if(i==3){
i=0;
printf("Removing %x %d \n",c,k++);
}
else{
printf("Putting %x %d \n",c,k++);
fputc(c,q);
i++;
}
}
fclose(p);
fclose(q);
return 0;
}
The file that i was trying to read is a .raw file and it is around 10-15 MB. I notice that the above code stops reading the file after typically 88 bytes. Is there any way to read large files or am i doing anything wrong ?
In addition to what has already been pointed out, a note on opening files: It sounds like your file in a binary file, which means you must add a b to the mode string. Additionally, rw is not a mode, since you only read from p you want rb, and since you only write to q you want wb or wb+.
By the way, the reason why you need fgetc to return an int is because fgetc must return 257 unique values: all the possible values of char, that is 0x00 thru 0xFF as well as something unique to signify EOF, usually -1
Change
char c;
to
int c;
as the return type of fetgetc() is an int and not char.
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 have a text file like this
987jgkfl
12358ldjkdju
7579jngj
8uuujkl
09698fjfj
I have a structure like this
struct emprec
{
int empid;
int todo;
char name[20];
};
I write the values of the struct into file like this
fd = fopen("/home/tarun/Desktop/test34.txt","a+");
fprintf(fd,"%d",temp2.empid);
fprintf(fd,"%s",temp2.name);
count++;
fclose(fd);
But when i read from the file i am getting the garbage value
while(i<=count)
{
fread(&temp5,sizeof(temp5),1,fd);
//fscanf(fd,"%d,%s",&temp5.empid,temp5.name);
//int k = strlen(temp5.name);
//printf("Value of k is %d\n",k);
//temp5.name[7]= '\0';
//fread(&temp5.empid,sizeof(temp5.empid),1,fd);
//fread(temp5.name,20,1,fd);
printf("\n%d %s",temp5.empid,temp5.name);
i++;
}
fclose(fd);
Please tell me where am i going wrong
Like say nemetroid :
You're writing a textual representation (with
fptrinf) of your struct but attempting to read a binary representation
(with fread).
For example, suppose you want write an int in a file. By doing like this :
fd = fopen("file","a+");
fprintf(fd,"%d",42);
You will write the character '4' and the character '2'. In ASCII, '4' is 0x34 and '2' is 0x32.
If you want to read that file and try to put it in an 4 bytes integer by doing like this :
int a = 0;
fread(&a,sizeof(a),1,fd);
The variable 'a' will contain the data on the file :
a = 0x00003234
And not 42 (0x0000002a) as you expect.
There were some calls that was missing from your code:
fflush()
Used to flush the file's buffer, you have to call this if you performed writes to the file and now you want to read
fseek
Used to set the file position indicator. In your case, the file position indicator was at the end of the file. Use fseek() to set the file position to where you started writing and than start reading.
fscanf function corresponds to fprintf. fread corresponds to fwrite. It means if you want to dump the structure using fprintf, then read it using fscanf. if you want to read the structure using fread then dump it using fwrite. Referring manpages of these functions should help.
Hi guys how to read entire digits from file? I mean my input file is 100-4/2 and i wrote this code while(fscanf(in,"%s",s)!=EOF) but it read like this 1 0 0. I want read like 100. How to solve this?
It's probably because you are using one-byte character(ANSI) set while the file is written with two-byte characters(Unicode). If you have created the file with the same program that is reading it it's going to read it right, but if not, you can open the file you are reading in notepad, then click save as, and there you can choose ANSI or Unicode.
You can read the whole line at once using getline() or similar method (also you can read as you are doing if there is only one line, then when EOF is true, whole line is read). Then you can parse the line to extract numbers and operators.
Use "%d" for integers
int value;
if (scanf("%d", &value) != 1) /* error */;
printf("Value read is %d.\n", value);
The below is simple program is self explanatory, which reads a file character by character, for each iteration stores this character into a temporary variable temp. and when the value in temp is a numerical character it simply copies this value in array named s.
int main()
{
char s[10]="\0";//initialzing array to NULL's and assuming array size to be 10
int i=0,temp=0;
FILE *fp=fopen("t.txt","r"); //when file has 100-4/2
if(fp==NULL)
{
printf("\nError opening file.");
return 1;
}
while( (temp=fgetc(fp))!=EOF && i<10 ) //i<10 to not exceed array size..
{
if(temp>='0' && temp<='9')//if value in temp is a number (simple logic...)
{
s[i]=temp;
i++;
}
}
printf("%s",s);//outputs 10042
return 0;
}
I was trying to copy the contents of one music file(.mp3) to create another music(.mp3) file. I tried this,
#include<stdio.h>
#include<conio.h>
int main()
{
FILE *a, *b;
char c;
a = fopen("linkinpark.mp3","rb");
b = fopen("linkinpark1.mp3","wb");
while((ch = getc(a)) != EOF)
fprintf(b,"%c",ch);
fclose(a);
fclose(b);
return 0;
}
May be i am making some mistake like using a char variable and writing it in a binary file and also linkinpark1.mp3 is created but its corrupted.
What could be its possible solution?
getc() returns either an int, not a char. It needs to return int because it returns either the next byte read from the stream as a value between 0 and 255, or the value EOF, which is typically -1. Since there are 257 possible outputs, you need to be able to distinguish between the byte 255 and the sentinel EOF, but your code is conflating the two. Hence, once you hit the first byte with value 255, it erroneously cuts the file off short.
If you change c to be int instead of char, it should work correctly.
I'm wanting to read hex numbers from a text file into an unsigned integer so that I can execute Machine instructions. It's just a simulation type thing that looks inside the text file and according to the values and its corresponding instruction outputs the new values in the registers.
For example, the instructions would be:
1RXY -> Save register R with value in
memory address XY
2RXY -> Save register R with value XY
BRXY -> Jump to register R if xy is
this and that etc..
ARXY -> AND register R with value at
memory address XY
The text file contains something like this each in a new line. (in hexidecimal)
120F
B007
290B
My problem is copying each individual instruction into an unsigned integer...how do I do this?
#include <stdio.h>
int main(){
FILE *f;
unsigned int num[80];
f=fopen("values.txt","r");
if (f==NULL){
printf("file doesnt exist?!");
}
int i=0;
while (fscanf(f,"%x",num[i]) != EOF){
fscanf(f,"%x",num[i]);
i++;
}
fclose(f);
printf("%x",num[0]);
}
You're on the right track. Here's the problems I saw:
You need to exit if fopen() return NULL - you're printing an error message but then continuing.
Your loop should terminate if i >= 80, so you don't read more integers than you have space for.
You need to pass the address of num[i], not the value, to fscanf.
You're calling fscanf() twice in the loop, which means you're throwing away half of your values without storing them.
Here's what it looks like with those issues fixed:
#include <stdio.h>
int main() {
FILE *f;
unsigned int num[80];
int i=0;
int rv;
int num_values;
f=fopen("values.txt","r");
if (f==NULL){
printf("file doesnt exist?!\n");
return 1;
}
while (i < 80) {
rv = fscanf(f, "%x", &num[i]);
if (rv != 1)
break;
i++;
}
fclose(f);
num_values = i;
if (i >= 80)
{
printf("Warning: Stopped reading input due to input too long.\n");
}
else if (rv != EOF)
{
printf("Warning: Stopped reading input due to bad value.\n");
}
else
{
printf("Reached end of input.\n");
}
printf("Successfully read %d values:\n", num_values);
for (i = 0; i < num_values; i++)
{
printf("\t%x\n", num[i]);
}
return 0
}
You can also use the function strtol(). If you use a base of 16 it will convert your hex string value to an int/long.
errno = 0;
my_int = strtol(my_str, NULL, 16);
/* check errno */
Edit: One other note, various static analysis tools may flag things like atoi() and scanf() as unsafe. atoi is obsolete due to the fact that it does not check for errors like strtol() does. scanf() on the other hand can do a buffer overflow of sorts since its not checking the type sent into scanf(). For instance you could give a pointer to a short to scanf where the read value is actually a long....and boom.
You're reading two numbers into each element of your array (so you lose half of them as you overwrite them. Try using just
while (i < 80 && fscanf(f,"%x",&num[i]) != EOF)
i++;
for your loop
edit
you're also missing the '&' to get the address of the array element, so you're passing a random garbage pointer to scanf and probably crashing. The -Wall option is your friend.
In this case, all of your input is upper case hex while you are trying to read lower case hex.
To fix it, change %x to %X.
Do you want each of the lines (each 4 characters long) separated in 4 different array elements? If you do, I'd try this:
/* read the line */
/* fgets(buf, ...) */
/* check it's correct, mind the '\n' */
/* ... strlen ... isxdigit ... */
/* put each separate input digit in a separate array member */
num[i++] = convert_xdigit_to_int(buf[j++]);
Where the function convert_xdigit_to_int() simply converts '0' (the character) to 0 (an int), '1' to 1, '2' to 2, ... '9' to 9, 'a' or 'A' to 10, ...
Of course that pseudo-code is inside a loop that executes until the file runs out or the array gets filled. Maybe putting the fgets() as the condition for a while(...)
while(/*there is space in the array && */ fgets(...)) {
}