Copy a file in C - c

I try to copy a file in a new file but it doesn't work because the input is 5133KB and the output is 614byte... what's wrong? Thank you in advance.
#include <stdio.h>
int main(void)
{
FILE * input = fopen("input.wav", "r");
FILE * output = fopen("output.wav", "w");
char buffer;
int bytesRead = 1;
while(bytesRead=fread(&buffer,1,1,input))
{
fwrite(&buffer,1,1,output);
}
fclose(input);
fclose(output);
return 0;
}

You may need to open the file in binary mode on your system. From C.2011, ยง7.21.5.3:
rb open binary file for reading
wb truncate to zero length or create binary file for writing
So:
FILE * input = fopen("input.wav", "rb");
FILE * output = fopen("output.wav", "wb");
The reason is that on some systems, certain embedded binary characters may cause the text mode processing to believe the end of file has been encountered, even though there are actually more bytes in the file.

Related

Check if a file is empty or not

How can I check if a text file has something written or not. I tried:
LOGIC checkfile(char * filename)
{
FILE *pf;
pf=fopen(filename,"wt");
fseek(pf,0,SEEK_END);
if(ftell(pf)==0)
printf("empty");
}
This function returns empty everytime, even in my text file I have few words or numbers written.
The problem is that you opened the file for writing. When you do that, everything in the file is lost, and the length of the file is truncated to 0.
So you need to open the file for reading. And the easiest way to see if the file is empty is to try to read the first character with fgetc. If fgetc returns EOF, then the file is empty.
First of all: DO NOT OPEN THE FILE FOR WRITING!
second: for knowing about file status in C you can use fstat which is in sys headear file!
You can use struct stat for using this function
here is a simple example:
#include <sys/stat.h>
int main(void)
{
int fields = 0;
int size = 0;
// Open the file test.txt through open()
// Note that since the call to open directly gives
// integer file descriptor so we used open here.
// One can also use fopen() that returns FILE*
// object. Use fileno() in that case to convert
// FILE* object into the integer file descriptor
if(fields = open(file_path, "r")){
struct stat buf;
fstat(fields, &buf);
size = (int)buf.st_size;
}
printf("size of file is %d", size);
return 0;
}
Note: I just include a header file that related to fstat. You can add other header files yourself
What about using fscanf to read the file, and check if something was actually read?
FILE *fp;
char buff[255] = "";
fp = fopen(filename, "r");
fscanf(fp, "%s", buff);
if (!*buff)
printf("Empty\n");
else
printf("%s\n", buff);
fclose(fp);

convert Ascii code file into binary file

I have a problem of converting ASCII code file into binary file. The code is able to read file and print data into other file as ASII code ( using fprintf); however, when I try to convert from ASII code to binary file ( using fwrite), and then use (fread) the file again. It doesn't generate the right answer. My doubt is the fwrite function doesn't work probably. Could you please advise on how to fix this problem? Thank you very much.
============================================
Code to convert from ASCII to binary file
===========================================
# include <stdio.h>
# include <stdlib.h>
# include <string.h>
typedef struct _FileData
{
int a;
double b;
char dataStr[56];
}FileData;
int main()
{
// open read file
FILE * infile=fopen("output.txt", "r");
if(infile==NULL)
{
printf("Error opening file");
exit(1);
}
// open write file
FILE * outfile = fopen("out_file.txt","wb");
if( outfile==NULL)
{
printf("Error writting on file");
exit(1);
}
FileData input; // pointer for read file
FileData output; // pointer for write file
while( fscanf(infile,"%d %lf %[^\n]s",&input.a,&input.b,&input.dataStr)==3)
{
/*printf("%d\n",input.a);
printf("%.3lf\n",input.b);
printf("%s\n",input.dataStr);*/
//fprintf(outfile,"%d\n %.3lf\n %s\n",input.a,input.b,input.dataStr);
fwrite(&output,sizeof(FileData),1,outfile);
}
fclose(infile);
fclose(outfile);
return 0;
}
==============================================================
Code to convert from binary file to ASCII code file
=============================================================
# include <stdio.h>
# include <stdlib.h>
# include <string.h>
typedef struct FileData
{
int a;
double b;
char dataStr[56];
}FileData;
int main()
{
FILE * infile=fopen("out_file.txt", "rb");
if(infile==NULL)
{
printf("Error opening file");
}
FileData input;
while(fread(&input,sizeof(struct FileData),sizeof(struct FileData),infile))
{
printf("%d\n",input.a);
printf("%.3f\n",input.b);
printf("%s\n",input.dataStr);
}
return 0;
}
===========================================================
Data
==========================================================
47
34.278
This is a line of text
48
23.678
This a very very long line
fread(&input,sizeof(struct FileData),sizeof(struct FileData),infile)
should be changed to
fread(&input,sizeof(struct FileData),1,infile)
You want to write 1 struct of size sizeof(struct FileData)
Also check the answer of mash5 where he suggests writing variable input instead of output while writing with fwrite.
In your ASCII conversion code, the input file is read into one variable input
fscanf(infile,"%d %lf %[^\n]s",&input.a,&input.b,&input.dataStr)
but a different, uninitialized, variable output is being written to the output file:
fwrite(&output,sizeof(FileData),1,outfile);
Perhaps you should write
fwrite(&input,sizeof(input),1,outfile);
instead?

fwrite creates an output file that is bigger than the input file

I want to read a file bytewise into an array and then write the data of the array reversed
in a new file (program takes filename over command line argument). Tried it with an txt-file
and it worked, but if I try it on a jpg-file the new file is bigger than the original!
The determined file size saved in long size; is also correct for jpg-files and write loop
get size-time executed writing one char (char is one byte big, I am right?).
Does anybody know how the output file can get bigger than size*byte?
It doesn't seem logical to me!
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc,char* argv[])
{
FILE *file;
char *buffer;
long size;
char filename[32];
if(argc>1)
{
//determine file size
file=fopen(argv[1],"r");
fseek(file,0,SEEK_END);
size=ftell(file);
rewind(file);
if(size>33554432) //32MB
{
fclose(file);
return 0;
}
//create buffer and read file content
buffer=malloc(33554432);
fread(buffer,1,size,file);
fclose(file);
//create new file name and write new file
strcpy(filename,argv[1]);
strcat(filename,"_");
file=fopen(filename,"w");
{
long i;
for(i=size-1;i>=0;i--)
{
fputc(buffer[i],file);
}
}
fclose(file);
free(buffer);
}
return 0;
}
The comments you're receiving are implying something: the newline character \n works differently in text mode on Windows compared with some other systems.
fputc('\n', file) on Windows actually writes two bytes if file was opened in text mode "w", as if you did fwrite("\r\n", 1, 2, file). This means for any \n byte read by fread, you're writing two bytes back.
If you want to write binary data back, you need to open your output file using the mode "wb" to fopen(). You also need to open it for reading in binary mode, "rb".

program crashes due to file format

i was trying this problem from usaco. when i use txt file while using file the program is working fine. but when for the submission requirement i change the format to beads.in and beads.out the program crashes. what;s the problem?
here's my code:
#include <stdio.h>
#include<string.h>
main () {
FILE *fin = fopen ("beads.in", "r");
FILE *fout = fopen ("beads.out", "w");
int n;
char str[400];
char now,rev_now;
int pos,forward,reverse,sum,max=0,i,j,k;
fscanf(fin,"%d\n%s",&n,str);
n--;
for(pos=0;pos<=n;pos++){
now=str[pos];
if(pos==0)k=n;
else k=pos-1;
rev_now=str[k];
forward=2;
int flag1=0,flag2=0,reverse=2;
for(i=pos,j=k;;){
if(i==n)i=-1;
if((str[i+1]==now||str[i+1]=='w')&&flag1==0){
i++;
forward++;
}
else{
flag1=1;
}
if(j==0)j=n+1;
if((str[j-1]==rev_now||str[j-1]=='w')&&flag2==0){
j++;
reverse++;
}
else{
flag2=1;
}
if(flag1==1 && flag2==1)break;
}
sum=forward+reverse;
if(max<sum){max=sum;}
}
fprintf(fout,"%d\n",max);
return 0;
}
are you sure beads.in and beads.out are created already..
According to man page
r Open text file for reading. The stream is positioned at the
beginning of the file.
w Truncate file to zero length or create text file for writing.
The stream is positioned at the beginning of the file.
May be beads.in is not created in prior to fopen. It's better if you check the status of the fopen, use perror.
You mention that it works with a text file. I'm guessing that beads.in is not a text file, but rather a binary file. If that is the case, then #KVD's suggestion above to use: fopen ("beads.in", "rb"); and fopen ("beads.out", "wb"); should work. The reason the program would crash with binary input data is because you are asking fscanf to copy data into your str buffer until it encounters a newline character. More than likely, the beads.in file has more than 400 characters which will cause a buffer overflow and start overwriting the program stack.

C: can't write data on file

i want to open a file, write some data on it so i have to use (Fopen) " i can't use open because i need fopen in some other things "
now if i want to write on the file using fwrite it just don't i don't know why this is what i referred to in my code #option1, but if i get the file descriptor and use normal write method everything works fine see #option 2 below.
anyone can help me to make fwrite works ?
char file_data[256] // has some values
int file_size = strlen(file_data);
FILE *file;
file = fopen(MY_FILE_NAME, "w+");
if(!file){//edited
return false;
}
#option 1//this is not working
fwrite(file_data,1,file_size,file);
#end of option 1
#option 2//this works
int fd = fileno(file);
int x = write(fd,file_data,file_size);//
#end of option 1
EDIT
my file_data is something like this
4 bytes is reserved for an integer (required)
200 bytes is reserved for a string (optional)
buffered IO operations use a buffer that is managed by the C lib. Your "problem" is that fwrite is buffered meaning that in order to write to the file you most likely need to flush it with fflush() or just close the file.
First of all:
if(!file < 0 ){
return false;
}
file is either NULL (on failure) or not (on success) - there's no point in testing it against 0 as it's a pointer (therefore, unsigned).
Your fwrite call seems OK, but you should make sure that the amount you're trying to write is correct (is there a null-terminated string inside file_data?).
Another problem you may be facing is that you don't close or flush the file - this may cause some data to remain in the file-buffer and not be written to the disk.
If you want to check the fopen() return value, do like this:
if (file == NULL) return false;
then, if you want to write a string fputs() is preferable, IMHO, because it communicates better that what you're writing is a string.
Since, according to your last edit, you aren't writing ASCII strings, this is what you should code:
#include <stdio.h>
struct String
{
int size;
char data[200];
};
int main()
{
struct String s;
FILE* file = NULL;
file = fopen("filename", "wb+");
memset(&s, '\0', sizeof(s));
strcpy(s.data, "Hello, world!");
s.size = strlen(s.data);
fwrite(&s, 1, sizeof(s), file);
if (!file) return 1;
fclose(file);
}
At first sight, the mistake seems to be at line #2:
int file_size = strlen(file_data);
This only works if there exists a terminal nul character. So file_size must be either provided for example as a function argument or the you must use the full size of the array.
The following should work:
int write_in_my_file(int data_int, const char* data_str)
{
size_t written;
FILE* file = fopen(MY_FILE_NAME, "wb+"); /* SuperJulietta */
if (!file) return false;
written = fwrite(&data_int, sizeof(data_int), 1, file);
if (written == sizeof(data_int))
{
if (opt_str) fputs(opt_str, file);
}
fclose(file);
return written == sizeof(data_int);
}
Note: this code was not compiled, and error handling is partial.
Edit : if you don't close the file, you'll have to call fflush instead.
You have to put a fflush(file); after the fwrite to force the writing of the data or you can also remove the buffer completely by doing a setbuf(file, NULL); after your fopen call.
I think you need to either do fclose(file) or fflush(file). because fopen is buffered IO so It does not write immidiately, so to ensure that file write is done, you need to do this.
I guess your fwrite code is not the problem.
Whenever the first byte in your file_data is \0 then you write nothing. Since the data is not a string, write 256 bytes. This code works:
#include <stdio.h>
#include <string.h>
#define MY_FILE_NAME "sample.bin"
#define SAMPLE_DATA "Content Content"
int main()
{
char file_data[256];
int file_size = sizeof(file_data);
// fill in some sample data
memcpy(file_data, SAMPLE_DATA, sizeof(SAMPLE_DATA));
FILE *file = fopen(MY_FILE_NAME, "w+");
if (file) {
fwrite(file_data, 1, file_size, file);
fclose(file);
}
}
You see, this is your fwrite. I use sizeof instead of strlen to determine the amount of bytes that will be written...
BR
fwrite is used for binary output, so you have to open file with "wb"

Resources