Link to home
Start Free TrialLog in
Avatar of Loysi
Loysi

asked on

Dos Copy Command

How can I write a C program to perform like the Dos Copy Command where I can Copy several Files and
Direct output to one single out file. As in "Copy *.txt > test.txt."

Basically the purpose is to append one file Stream to another file stream

Avatar of mnashadka
mnashadka

Did you try something like (since you're on Unix):
system("cat *.txt > test.txt");

Hope this helps.
Dear Loysi,
 U can try following code.
First create the batch file like:

file name: - test.bat
-----------------------
cd..
cd Yog
copy *.txt yogs.txt
------------------------------
Then  write following c++ code.
#include<stdio.h>
#include <stdlib.h>
void main()
{
//specify the requried path of batch file created above.
char *path = "c:\\Yog\\test"
    system(path);
}
//In yogs.txt u can get all files data. And u can read using simple Files .

I think this will help u .
Avatar of Loysi

ASKER

mnashadka: Yes! I tried that cat does not work very well with wildcards, and it hung the system. I guess I have to do it the only way I can think off read each file using the findfirst/findnext function and write to the desired output file.
I'm sorry Loysi.  I thought you were working on Unix.
Sorry Loysi ,
As I told u already I don't know unix. I cann't.
bye
Avatar of Loysi

ASKER

mnashadka: Yes I am trying to write the program to work on unix. I have not yet checked to see if my complier supports the findfirst/findnext fuctions.
I don't understand why the cat thing would hang your system.  Did you try that from the command line?  If nothing else, you could use opendir, readdir, and closedir to go through the files in the directory and check the last 4 characters of the struct dirent to see if it's a text file, then open it and write the contents to another file.  I think that stuff's declared in <dirent.h>.
Avatar of Loysi

ASKER

mnashadka: Yeah! I tried the cat command on the command line. I will try your suggestions to use opendir, readdir and closedir to go throug the files.
I don't understand why cat would hang. That indicates something wrong with your computer. Can you cat a single file? Try:
for I in `ls -1 *.txt`; do cat $I >> test.txt; done

If this still does not work, try replacing cat $I with cp $I /dev/tty.
Sorry, last suggestion will not work...
Are you looking for something OTHER than what has been posted?
Avatar of Loysi

ASKER

Triskelion: Do you have any other suggestions?
>>Triskelion: Do you have any other suggestions?
Nothing that (in some way) hasn't already been stated.
I personally would try the 'cat' and redirect solution through the system() call.  That way, you won't have to handle the wildcards yourself.

You can take the parameters from the command-line and parse them however is necessary to pass them to cat.

The real problem comes in trying to emulate the dos copy quirks like:
  copy /b fred.dat +,,
{emulates the 'touch' command in DOS)

What about the /Y /A /B /V

Potential problems
   Does 'cat' handle binary files?
Avatar of Loysi

ASKER

Triskelion: Thanks! I was trying to avoid using cat because on 2 occasions It hung the system when I used it on the command line.

I would imagine this may not happen if used within a program doing a system() call.

The reason I think my system hung is because I telnet to the AIX environment and executed the cat *.txt > test.txt from the command line.
I was trying to avoid this happening when doing a system call within the program execution.  Then again this is not to say that cat will not work. It has worked for me on small files quite successfully.

 I basically ended up writing a program using the opendir, readdir, closedir functions.  

I was really looking for a Solution in C like the fstream Class in C++ to append 2 or more filestreams to one. I guess there is no easy way then reading each file and writing to an output file. I am impressed with the way the Dos copy command works.
cat with redirection works on binary files, yes.
So you'd like to implement this in C? Good for learning, but basically reinventing the wheel. Try this. Let me know if this is close to what you want, and I will follow up with comments, if necessary. Use it as i.e. mycopy file1.txt file2.txt > output.txt. No wildcard support for now. I compiled on Windows, but this testcase is ANSI complian; should compile and run on Unix. Any problems let me know.

/* mycopy.c */
#include <sys/types.h>
#include <sys/stat.h>
#include <stdio.h>
#include <stdlib.h>
#include <io.h>
#include <fcntl.h>

#define __STDOUT_ 1
long getSize( char * );
int append( int, char * );

int main( int argc, char *argv[] )
{
    int i;
   
    if( argc <= 1 ){
        printf( "Usage:\n" );
        printf( "mycopy srcfile1.ext srcfile2.ext ... > destfile.ext\n" );
        printf( "mycopy srcfile1.ext srcfile2.ext ... >> destfile.ext\n" );
        return -1;
    }

    setmode( __STDOUT_, O_CREAT | O_WRONLY | O_APPEND | O_TEXT );

    /* Append source files to destination, one by one */
    for( i = 1; i<argc; i++ ){
        append( __STDOUT_, argv[i] );
    }

     return 0;
}

/* Get file size */
long getSize( char *fname )
{
    struct stat buf;
    char err[128];

    if(  _stat( fname, &buf ) != 0 ){
        sprintf( err, "getSize: Can't open \"%s\"\n", fname );
        perror( err );
        return -1;
    }
    else{
        return buf.st_size;
    }
}

int append( int dest_fd, char *src_fname )
{
    int   src_fd;
    int   src_fsize;
    int   bytes;
    char *src_fdata;
    char  err[128];

    /* Open source file */
    src_fd = open( src_fname, O_RDONLY );
    if( src_fd == -1 ){
        sprintf( err, "append: Can't open \"%s\"\n", src_fname );
        perror( err );
        return -1;
    }
   
    /* Get source file size */
    src_fsize = getSize( src_fname );
    if( src_fdata > 0 ){
        src_fdata = (char *)malloc( src_fsize+1 );
    }
    else{
        close( src_fd );
        return -1;
    }
   
    /* Read data from source file */
    bytes = read( src_fd, src_fdata, src_fsize );
    if( bytes == -1 ){
        sprintf( err, "append: Can't read \"%s\"\n", src_fname );
        perror( err );
        close( src_fd );
        free( src_fdata );
        return -1;
    }
    else{
        src_fdata[bytes] = '\0';
    }
   
    /* Append data from source to destination file */
    bytes = write( dest_fd, src_fdata, bytes );
    if( bytes == -1 ){
        sprintf( err, "append: Can't write to STDOUT\n" );
        perror( err );
        close( src_fd );
        free( src_fdata );
        return -1;
    }

    /* Close source file descriptor and free memory allocated by in_fdata */
    close( src_fd );
    free( src_fdata );
   
    return 0;
}
Any feedback? Questions?
Rgds.
I tryed this it was fine.

cat *.txt > test.txt

But then I tryed it again and got the error
cat: test.txt: input file is output file

if your unix does not catch this you could end up with an infanate sized test.txt if you press ctrl-C before to long you could stop it but if you / drive fills up the system could hang. you can use ulimit to set artificial limits on what you can do.


Did anything work?
ASKER CERTIFIED SOLUTION
Avatar of bearware
bearware
Flag of United Kingdom of Great Britain and Northern Ireland image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of Loysi

ASKER

I asked this question a long time ago. and I would like to close this question. I resolved this problem a long time ago. However I would like to award points to several experts who gave me valuable information: each in their own class.

Triskelion 50
Kulina 50
mnashadka 50

I am not sure how to do this?
Very kind of you. Thanks.

A way to do this is to post three dummy questions in C Programming topic area, 50 points each. Give each question a title such as "Points for <username>...", and include a link to this question for cross-refeencing purposes.
Regards.