Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game. |
Notices |
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
Are you new to LinuxQuestions.org? Visit the following links:
Site Howto |
Site FAQ |
Sitemap |
Register Now
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
|
|
10-27-2005, 07:19 AM
|
#1
|
Member
Registered: Mar 2004
Location: UK
Distribution: Fedora, OpenSuse
Posts: 91
Rep:
|
copying files(s) in c
I have another programming question, whilst I learn C. I am trying to copy a file from one location to another in binary, as I do not know what 'type' of file it is. I have written the following function, that when trying to write to file, i get a segmentation fault.
Code:
void doc_to_workspace(char* filename,char* workspacefile)
{
int *fpw;
int *fpr;
FILE *filew;
FILE *filer;
/*Open files for copying*/
if((fpw = fopen(workspacefile,"wb")) == NULL){
fprintf(stderr,"Can not copy file to workspace - File write Error\n");
}
if((fpr = fopen(filename,"rb"))==NULL){
fprintf(stderr,"Can not copy file to workspace = File read Error\n");
}
/*Read file by 1MB chunks and write to workspace location*/
int len =0;
while((len = fread(FILEBUF,1,sizeof(FILEBUF),filer))>0){
fwrite(FILEBUF,1,len,filew);
}
/*close file connections*/
fclose(filer);
fclose(filew);
}
Any ideas on where I am going wrong with this, I have to confess I am not 100% sure what I am doing so it has been a bit of trial and error. Just to note FILEBUF = 1048576.
Any help with this or generally with my C programming style etc, is gratefully received.
Thanks....
|
|
|
10-27-2005, 09:07 AM
|
#2
|
Senior Member
Registered: Aug 2002
Location: Groningen, The Netherlands
Distribution: Debian
Posts: 2,536
Rep:
|
Re: copying files(s) in c
Quote:
Originally posted by climbingmerlin
I am trying to copy a file from one location to another in binary, as I do not know what 'type' of file it is.
|
In UNIX/Linux there's no difference at all between "binary" and "text" files. The mode option "b" or "t" is only there for compatability with OS's that do handle text and binary differently.
Fixed your code (but didn't test it). Changes in red.
Code:
#include <stdio.h>
/* ... */
void doc_to_workspace(char* filename,char* workspacefile)
{
/* int *fpw; // remove */
/* int *fpr; // remove */
FILE *filew;
FILE *filer;
/*Open files for copying*/
if((filew = fopen(workspacefile,"wb")) == NULL){
fprintf(stderr,"Can not copy file to workspace - File write Error\n");
}
if((filer = fopen(filename,"rb"))==NULL){
fprintf(stderr,"Can not copy file to workspace = File read Error\n");
}
/*Read file by 1MB chunks and write to workspace location*/
int len =0;
while((len = fread(FILEBUF, sizeof(FILEBUF), 1,filer))>0){
fwrite(FILEBUF, len, 1,filew);
}
/*close file connections*/
fclose(filer);
fclose(filew);
}
|
|
|
10-27-2005, 09:35 AM
|
#3
|
Member
Registered: Mar 2004
Location: UK
Distribution: Fedora, OpenSuse
Posts: 91
Original Poster
Rep:
|
Thanks for your reply... I have changed the code a little, it reads the file and writes it to the new location, however it loops constantly... didn't realise it till a 20K file took up almost 800MB!!! The problem is that it is not finding the end of the file.
Any ideas on how I can do that? Here is my reworked code.
Code:
void doc_to_workspace(char* filename,char* workspacefile)
{
FILE *filew;
FILE *filer;
char buf[FILEBUF];
/*char buf[1024];*/
/*Open files for copying*/
if((filew = fopen(workspacefile,"wb")) == NULL){
fprintf(stderr,"Can not copy file to workspace - File write Error\n");
}
if((filer = fopen(filename,"rb"))==NULL){
fprintf(stderr,"Can not copy file to workspace = File read Error\n");
}
/*Read file by 1MB chunks and write to workspace location*/
/*int len =0;*/
while((fread(&buf,sizeof(buf),1,filer)) !=feof){
fwrite(&buf,sizeof(buf),1,filew);
}
/*close file connections*/
fclose(filer);
fclose(filew);
}
Again any help will be gratefully received... I am starting to gain a lot of respect for C programmers!
|
|
|
10-27-2005, 10:21 AM
|
#4
|
Member
Registered: Mar 2004
Location: UK
Distribution: Fedora, OpenSuse
Posts: 91
Original Poster
Rep:
|
One thing that I forgot to point out that, the size of file(s) that I am copying range from 40K to 20GB....
|
|
|
10-27-2005, 10:38 AM
|
#5
|
Member
Registered: Oct 2005
Location: Chicago, USA
Distribution: Slackware & Fedora
Posts: 66
Rep:
|
First off, you didn't read Hko's entire code.
First mistake: You are not reading the right count in fread.
Second, the function feof is a function address!! So comparing a size_t to void * is syntactically correct C but semantically wrong. To use feof correctly, you pass it the file pointer feof( FILE *fptr );
Having a local variable of 1MB is fairly large to place on the stack! Consider making it either static (so that is not on the stack), use a global variable (so that is in the data segment), or dynamically allocate the buffer (heap). Of those, the dynamic allocation is the most error prone but the best memory usage in that you are not permaneantly reserving a megabyte of memory but rather asking the OS for dynamically allocated memory temporarily.
You should change your code like:
Code:
void doc_to_workspace(char* filename,char* workspacefile)
{
FILE *filew;
FILE *filer;
char *buffer;
size_t count; /* Using size_t makes robust C code that is portable and avoids implicit type conversions. */
/*Open files for copying*/
if( ! ( buffer = (char *)malloc( sizeof( char ) * FILEBUF ) ) ) {
fprintf(stderr,"Can not allocate memory for workspace - Memory allocation Error\n");
}
else if((filew = fopen(workspacefile,"wb")) == NULL){
free( buffer ); /* Cleanup! */
fprintf(stderr,"Can not copy file to workspace - File write Error\n");
}
else if((filer = fopen(filename,"rb")) == NULL){
fclose( filew ); /* Cleanup! */
free( buffer ); /* Cleanup! */
fprintf(stderr,"Can not copy file to workspace = File read Error\n");
}
else
{
/* Read file by FILEBUF sized chunks and write to workspace location. */
/* If less than FILEBUF characters read, then no problem, write the partial out. */
/* If 0 bytes read, then consider the copy operation done. If this is a device, then this should be changed. */
while( ( count = fread( buffer, sizeof( char ), FILEBUF, filer ) ) > 0 )
if( fwrite( buffer, sizeof( char ), count, filew ) != count )
break; /* Error, could not write the full length. */
/*close file connections*/
fclose(filer);
fclose(filew);
free( buffer ); /* Cleanup! */
}
}
Last edited by naf; 10-27-2005 at 10:40 AM.
|
|
|
10-27-2005, 11:11 AM
|
#6
|
Member
Registered: Mar 2004
Location: UK
Distribution: Fedora, OpenSuse
Posts: 91
Original Poster
Rep:
|
To both Hko and naf thanks.... I now have a working function that copies files
Can you suggest other ways of understanding memory management as, I am not sure if it is me but I do find the use of malloc() calloc() and the use of pointers rather confusing. I am finding C enjoyable but at the same time a frustrating lanaguage to learn!
If anyone has any tips to give at improving my C code, as I know it is messy and probably not following any coding standards, I would again be extremely grateful.
|
|
|
10-27-2005, 11:36 AM
|
#7
|
Member
Registered: Oct 2005
Location: Chicago, USA
Distribution: Slackware & Fedora
Posts: 66
Rep:
|
I usually like going with the authors of the language:
The C Programming Language, 2nd Edition
Brian W. Kernighan, Dennis M. Ritchie
ISBN 0131103628
The C++ Programming Language
Bjarne Stroustrup
ISBN 0201889544
For UNIX like programming, I like the book by the late Stevens:
Advanced Programming in the UNIX Environment, 2nd Edition
W. Richards Stevens
ISBN 0201433079
There are plenty of good online tutorials too if you don't want to spend money.
Learn the glib memory management for some interesting insights.
http://developer.gnome.org/doc/API/2.0/glib/index.html
|
|
|
10-27-2005, 03:00 PM
|
#8
|
Member
Registered: Mar 2005
Distribution: Breezy Badger
Posts: 248
Rep:
|
I don't think your style is bad. You squash the code up more than I do but that depends on the person writing it -- everybody does it differently. You also know how to comment too.
I've seen much, much worse on these forums.
|
|
|
All times are GMT -5. The time now is 03:18 PM.
|
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.
|
Latest Threads
LQ News
|
|