Thread: Extra line break added during copying

  1. #1
    Registered User Tigers!'s Avatar
    Join Date
    Jun 2009
    Location
    Melbourne, Australia
    Posts
    49

    Extra line break added during copying

    (I am so close to finishing my 1st large C programme for my new boss I can almost taste it, yet errors crop up)

    I have written a small C function to copy/move files from one location to another (on the same server). It appears to work ok except that an extra line break in added after every line.
    The original
    Code:
    "SEW_AU","PICKLIST","Delivery_no","106066841","Order_no","1142771","Customer_no","100729","FILLER","000","REPORT","PICKLIST","\TestingTiffMoves\AU\PICKLIST\0000544B.TIF"
    "SEW_AU","PICKLIST","Delivery_no","106066854","Order_no","1142781","Customer_no","100042","FILLER","000","REPORT","PICKLIST","\TestingTiffMoves\AU\PICKLIST\0000544C.TIF"
    "SEW_AU","PICKLIST","Delivery_no","106066814","Order_no","1142752","Customer_no","105617","FILLER","000","REPORT","PICKLIST","\TestingTiffMoves\AU\PICKLIST\0000544D.TIF"
    "SEW_AU","PICKLIST","Delivery_no","106066851","Order_no","1142779","Customer_no","103841","FILLER","000","REPORT","PICKLIST","\TestingTiffMoves\AU\PICKLIST\0000544E.TIF"
    After the moving
    Code:
    "SEW_AU","PICKLIST","Delivery_no","106066841","Order_no","1142771","Customer_no","100729","FILLER","000","REPORT","PICKLIST","\TestingTiffMoves\AU\PICKLIST\0000544B.TIF"
    
    "SEW_AU","PICKLIST","Delivery_no","106066854","Order_no","1142781","Customer_no","100042","FILLER","000","REPORT","PICKLIST","\TestingTiffMoves\AU\PICKLIST\0000544C.TIF"
    
    "SEW_AU","PICKLIST","Delivery_no","106066814","Order_no","1142752","Customer_no","105617","FILLER","000","REPORT","PICKLIST","\TestingTiffMoves\AU\PICKLIST\0000544D.TIF"
    
    "SEW_AU","PICKLIST","Delivery_no","106066851","Order_no","1142779","Customer_no","103841","FILLER","000","REPORT","PICKLIST","\TestingTiffMoves\AU\PICKLIST\0000544E.TIF"
    This extra line break causes later programs to fail.

    The code seems to be relatively simple
    The copy function
    Code:
    void copy(char *srcFileName, char *dstFileName)
    /* This routine takes 2 file names as parameters. It will copy the source file, srcFileName, to the destination file, dstFileName. */
    {
    FILE *fsrc, *fdst;
    char ch;
    
    fsrc=fopen(srcFileName, "rb");
    if (fsrc==NULL) {
    	printf("Couldn't open file %s for reading.", fsrc);
        exit (0);
    }
    fdst=fopen (dstFileName, "w");
    if (fdst==NULL) {
    	printf("Couldn't open file %s for writing.", fdst);
        exit (0);
    }
    
    //copying file here
    
     while(!feof(fsrc)) {
        ch = fgetc(fsrc);
      if(ferror(fsrc)) {
          printf("Read Error to %s\n", fsrc);
          clearerr(fsrc);
          break;
        } else {
          if(!feof(fsrc))
    	    fputc(ch, fdst);
          if(ferror(fdst)) {
            printf("Write Error to %s\n", fdst);
            clearerr(fdst);
            break;
          }
        }
      }
    fclose (fsrc);
    fclose (fdst);
    }
    The copy function is called from this snippet
    Code:
    if (tiffFile != NULL) {
                while (fgets(tiffLine, size, tiffFile)!=NULL) { //loop for reading a line up of "moveTIFF.dat" to end of file
    	tiffLine[strcspn ( tiffLine, "\n" )] = '\0'; // This line removes the '\n' off the string
    	sstrncpy(dest, tiffLine, size);
                    if (
                        (end_of_path = strrchr(dest, '\\')) != NULL
                        ||
                        (end_of_path = strrchr(dest, '/')) != NULL
                    ) {
                        ++end_of_path;
                        sstrncpy(tiff_file, end_of_path, size);
                        *end_of_path = 0;
                        tiff_file[size] = '\0';
    	    strncat(dest, index_file, size);
    	    copy(tiff_file, tiffLine);
                    }
                }
                fclose(tiffFile);
            }
    Why/where is the extra line break being added?
    I hope their is enough info present.
    (If I am totally up the creek and there is an easier, cleaner way to do this don't be afraid to hurt my feelings and tell me )

  2. #2
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    Why one text and one binary?

  3. #3
    Registered User Tigers!'s Avatar
    Join Date
    Jun 2009
    Location
    Melbourne, Australia
    Posts
    49
    Oh dear now you have me thinking.
    My 1st reaction is that the copy function is also being used to move TIFF files. Admittedly I have not checked the TIFF files to see if they are different.
    But you do raise a good point.
    Should both be "rb" or "w"?
    I am not familiar enough with C to adequately answer that question.
    That is why I am at this forum with all the experts

  4. #4
    Registered User
    Join Date
    Sep 2006
    Posts
    8,868
    File copying should be straight binary. Text mode will cause errors in non-text files.

  5. #5
    Registered User
    Join Date
    Aug 2006
    Posts
    100
    I don't know what platform you are writing this for, but really... there has to be an available file copy routine at the OS level. For Windows, look at SHFileOperation() (IFileOperation() for Vista).

    Doing single char reads and writes is much slower then doing block reads/writes, or (again), letting the OS handle the job.

  6. #6
    Woof, woof! zacs7's Avatar
    Join Date
    Mar 2007
    Location
    Australia
    Posts
    3,459
    Doesn't seem like something to do in C anyway

  7. #7
    Registered User Tigers!'s Avatar
    Join Date
    Jun 2009
    Location
    Melbourne, Australia
    Posts
    49
    Quote Originally Posted by rdrast View Post
    I don't know what platform you are writing this for, but really... there has to be an available file copy routine at the OS level. For Windows, look at SHFileOperation() (IFileOperation() for Vista).

    Doing single char reads and writes is much slower then doing block reads/writes, or (again), letting the OS handle the job.
    I am writing code that will be used on Win2003 server and XP machines (at least at present).
    Is SHFileOperation() a Win command rather than a C command? I am trying to avoid being that specific due to possible portability issues (plus my company is moving towards Vista/Win 7 in 2010).
    Would I be better off using fread & fwrite?

  8. #8
    Registered User Tigers!'s Avatar
    Join Date
    Jun 2009
    Location
    Melbourne, Australia
    Posts
    49
    Quote Originally Posted by zacs7 View Post
    Doesn't seem like something to do in C anyway
    do you mean that we should let the OS handle such opeartions? Doesn't that raise portability issues?
    Or do you mean something else?

  9. #9
    Registered User
    Join Date
    Apr 2006
    Posts
    2,149
    Quote Originally Posted by Tigers! View Post
    do you mean that we should let the OS handle such opeartions? Doesn't that raise portability issues?
    Or do you mean something else?
    I'm pretty sure he means this program would be easier to write in Python or Perl.
    It is too clear and so it is hard to see.
    A dunce once searched for fire with a lighted lantern.
    Had he known what fire was,
    He could have cooked his rice much sooner.

  10. #10
    Registered User
    Join Date
    Sep 2006
    Posts
    8,868
    Quote Originally Posted by Tigers! View Post
    I am writing code that will be used on Win2003 server and XP machines (at least at present).
    Is SHFileOperation() a Win command rather than a C command? I am trying to avoid being that specific due to possible portability issues (plus my company is moving towards Vista/Win 7 in 2010).
    Would I be better off using fread & fwrite?
    C is fine for this. What do you think the OS itself, is written in (C and C++ mostly).

    You want binary read and write, and you want a buffer size which matches (or ideally is a multiple of), the most probable sector size, of your target machine's hard drive. The larger, the better.

    Some hard drives have unusually large drive buffers - so that's another consideration. If it's possible, match your buffer size to this size, or a multiple of this size, as well.

    You may write code like:
    Code:
    while((ch = getchar()) != EOF)
    But that request will not be honored by the OS or hard drive, like you might think. The HD won't go out and get that one char for you. It will fill up an entire portion of it's buffer, with data from the HD, and that data (or a portion of it), will be given to the OS, in a burst of data. Your C program will then work with the data, from there.

    At no time will the HD actually go out and read one char, and send it to your OS and program, and then go back and read one more char. Your computer system is a lot smarter than that.

    Having said all this, it's unlikely that your C program will copy data as quickly as the OS can. Why? Because the OS has dedicated hardware and code (typically in assembly language) optimizations, designed expressly for this kind of operation.

    Another big factor is the transfer method which the HD is set for. I have a good sized disk buffer on my HD, and seldom copy any big files, but I was shocked at how *SLOW* this HD was, once it got beyond it's *very* fast HD buffer, when I had to move all the files over to a backup drive. I was pulling out my hair, believe me! <OMG>

    This was all caused by the transfer mode being set wrong, on the default install into WindowsXP. I was lazy and just stuck the new drive in there, without running any install program. WindowsXP recognized it, and I was up and running - but that was a big mistake for moving large files to another drive. I'm talking about 10X slower than normal!!

    The key thing, in summary is to always TEST the proposed method, before you implement it. Things that you "knew" to be true, will be false, when you least expect it. I hate to sound so old-fashioned, but for a lot of repetitive copying of files, I still like BAT files.

  11. #11
    Registered User Tigers!'s Avatar
    Join Date
    Jun 2009
    Location
    Melbourne, Australia
    Posts
    49
    After a bad night's sleep and some more thought I will use DOS to do the file moving/copying/deleting as it does seem much cleaner (and easier).
    I have had a look through the threads for ways to include DOS commands or batch files in C. There didn't seem to be much though a search does depend upon what you ask.
    Is there an approved method e.g. put the DOS commands or or call a batch file?
    What is the syntax for either method?

  12. #12
    Registered User
    Join Date
    Sep 2006
    Posts
    8,868
    Quote Originally Posted by Tigers! View Post
    After a bad night's sleep and some more thought I will use DOS to do the file moving/copying/deleting as it does seem much cleaner (and easier).
    I have had a look through the threads for ways to include DOS commands or batch files in C. There didn't seem to be much though a search does depend upon what you ask.
    Is there an approved method e.g. put the DOS commands or or call a batch file?
    What is the syntax for either method?
    Surely you jest about Googling "bat files". I see page after page of entries, and just finished a very long and exhaustive tutorial, I found with google.

    This is an example of a simple bat file. Before you use a bat file, you MUST know and TEST it that it's working as expected.

    Code:
    @echo off
    echo ****************************
    echo Welcome to solver1.bat
    echo Starting bb_sudoku_v05c.exe
    echo ****************************
    for %%a in (Q*.*) do call solver2 %%a
    echo.
    echo Done!
    pause
    Here, this directory had hundreds of files with sudoku grids for the Quest 16 project. Each begins with a 'Q' and a number is appended on: Q163 for instance.

    The "for" starts a for loop, which uses %%a as replaceable parameters, finding each file beginning with a Q, "in (Q*.*)", and then calling the program 'solver2 with that file name:

    solver2 <Q163 is what the command line in a console window, would be like.

    (The < was implied)

    maybe Google "Bat file tutorial", for better luck.

    The first % is the first chars in the filename, the second % is the filename extension.

    Bat files are very powerful, but be SURE to test your in a directory that can't be harmed, and I would say don't let them work across any of your system directories, when possible.

    Like with any file utility program, you have to be careful.

  13. #13
    Registered User Tigers!'s Avatar
    Join Date
    Jun 2009
    Location
    Melbourne, Australia
    Posts
    49
    Quote Originally Posted by Adak View Post
    Surely you jest about Googling "bat files". I see page after page of entries, and just finished a very long and exhaustive tutorial, I found with google.
    I meant search the C programming forum for how to include either batch files or DOS commands in C code.
    A google search is so comprehensive that the wheat is drowned in the chaff

    Can batch files be called from C or DOS commands included?

  14. #14
    Registered User
    Join Date
    Sep 2006
    Posts
    8,868
    Oh yes.

    That bat file I posted was called by my C program. If your directory is not in the DOS path, it won't work, of course.

    I used
    Code:
    system("solver1");
    IIRC

    What's in the DOS path: default is Root (C:/) or (C:\\), Windows, Windows\system, and Documents and Settings for WindowsXP. You can add to that, as well.

    Check your windows help file, there's a lot of info. If you get stuck, remember to use the /? to get help in the console window, for any DOS commands:

    dir /? <enter>

    Lists all the basics for using the dir command.

  15. #15
    Registered User
    Join Date
    Aug 2006
    Posts
    100
    Quote Originally Posted by Tigers! View Post
    I am writing code that will be used on Win2003 server and XP machines (at least at present).
    Is SHFileOperation() a Win command rather than a C command? I am trying to avoid being that specific due to possible portability issues (plus my company is moving towards Vista/Win 7 in 2010).
    Would I be better off using fread & fwrite?
    Exactly how portable do you want to be? No matter what, you are going to require a rebuild for different target platforms, and the platform localization code can be easily isolated.
    Using system() calls is no more portable then calling the base file systems handlers. Once you start hardcoding in system commands, or batch (or command, or shell) script names, you've already broken portability.

    Writing portable code, really just involves isolating out platform specific parts, so they are easy to adapt for each target platform.

    If you are going to start wrapping shell (system() ) calls in C, and call it a C program, you are wasting time and effort.

    Just use a shell script directly (batch, cmd, whatever).

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Number to Word (Billions)
    By myphilosofi in forum C Programming
    Replies: 34
    Last Post: 02-04-2009, 02:09 AM
  2. Another syntax error
    By caldeira in forum C Programming
    Replies: 31
    Last Post: 09-05-2008, 01:01 AM
  3. MDICLIENT Problem
    By loko in forum Windows Programming
    Replies: 7
    Last Post: 01-16-2005, 10:42 PM
  4. Keypress reading
    By geek@02 in forum Windows Programming
    Replies: 1
    Last Post: 06-16-2004, 12:16 PM
  5. A simple array question
    By frenchfry164 in forum C++ Programming
    Replies: 7
    Last Post: 11-25-2001, 04:13 PM