Thread: improper file path string handling

  1. #1
    Registered User
    Join Date
    May 2007
    Posts
    77

    improper file path string handling

    OK, so I figured out my problem with the endian swapping portion of my program, and now I'm trying to get it to handle file naming, etc. So I'm passing various portions of the file path to the program from a batch file (to make it easier to separate those portions). When I echo those portions from the batch file, they're perfect, but when I print them from the program after they're passed, they're all jumbled up. Here's the pertinent part of my code:
    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <limits.h>
    #include <stdint.h>
    
    main(int argc, char *argv[])
    {
        FILE* originalSave;
        FILE* newSave;
        long fileSize;
        long finalSize;
        uint32_t *buffer, result = 0;
        int x;
        char *savePath;
        char *name;
        char *ext;
        char *saveText;
    
        originalSave = fopen(argv[1], "rb");
        
        ext = argv[2];
        
        name = argv[3];
        
        savePath = argv[4];
        
        printf("savePath = %s\nname = %s\next = %s", savePath, name, ext);
        
        //printf("C:\\%s%s%s", savePath, name, ext);
        
        system("PAUSE");
    
        return 0;
    }
    When I do that, I get this output:
    Code:
    savePath = Documents\wii64saveSwap\ZELDA
    name = Settings\User\My
    ext = and
    But the output from the batch file is:
    Code:
    savePath = "C:\Documents and Settings\User\My Documents\wii64saveSwap\"
    name = "ZELDA MAJORA'S MASK(U)"
    ext = ".fla"
    I'm utterly confused by why it's doing that. Do you guys?

  2. #2
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    So, you typed in what,
    Code:
    myprogram C:\Documents and Settings\User\My Documents\wii64SaveSwap\ZELDA etc
    If so, then arg[1] is "C:\Documents", arg[2] is "and", arg[3] is "Settings\User\My", arg[4] is "Documents\wii64SaveSwap\ZELDA", arg[5] is "MAJORA's", arg[6] is "MASK(U).fla". If you don't want the spaces to separate your arguments, then you need to use quotes to separate your arguments, just like you do when you do when you do a copy command or any other command.

  3. #3
    Registered User
    Join Date
    May 2007
    Posts
    77
    No, that's not the problem, because otherwise I would get something like
    Code:
    savePath = C:\Documents
    name = and
    ext = Settings\User\My
    Here's what the batch file does:
    Code:
    @echo off
    :start
    
    set batPath=%~dp0
    
    set fileExt=%~x1
    set fileTitle=%~n1
    set filePath=%~dp1
    
    "%batPath%wii64converter.exe" "%1" "%fileExt%" "%fileTitle%" "%filePath%"
    
    :end
    I had already been experiencing problems with spaces before on another project I was working on, so those are already set in place. Unless you're saying I need to put in extra quotes in that...

    EDIT: and, this method of passing has worked for other programs I've written batch files for, so it must be something in the program code itself causing the problem.
    Last edited by Molokai; 10-17-2009 at 01:34 PM.

  4. #4
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    Quote Originally Posted by Molokai View Post
    No, that's not the problem, because otherwise I would get something like
    Code:
    savePath = C:\Documents
    name = and
    ext = Settings\User\My
    ... which is what you got, so I don't see why you don't think that's the problem.
    Quote Originally Posted by Molokai View Post
    Here's what the batch file does:
    Code:
    @echo off
    :start
    
    set batPath=%~dp0
    
    set fileExt=%~x1
    set fileTitle=%~n1
    set filePath=%~dp1
    
    "%batPath%wii64converter.exe" "%1" "%fileExt%" "%fileTitle%" "%filePath%"
    
    :end
    I had already been experiencing problems with spaces before on another project I was working on, so those are already set in place. Unless you're saying I need to put in extra quotes in that...
    My suggestion is (1) turn @echo back on to see what command is actually being run, and my question is (2) which compiler are you using, since I recall learning on this board before that Visual Studio-compiled programs don't do shell expansion on arguments by default, and I don't know whether quoting would fall on that list. (The example we were using was wildcard expansion.) (EDIT: That thread was here, but I just did some tests which indicate that quoting does work by default with cl, so check to make sure the quotes are there in the command line.)
    Last edited by tabstop; 10-17-2009 at 01:50 PM.

  5. #5
    Registered User
    Join Date
    May 2007
    Posts
    77
    I'm using dev-c++ to compile (using, I think, cygwin, maybe gcc, not sure).

    Turning echo back on gives me this output:
    Code:
    C:Documents and Settings\User>set batPath=C:\Documents and Settings\User\My Documents\Wii64saveSwap\
    
    C:\...>set fileExt=.fla
    
    C:\...>set fileTitle=ZELDA MAJORA'S MASK(U)
    
    ...>set filePath=C:\Documents and Settings\User\My Documents\wii64saveSwap\
    
    ...>"C:\Documents and Settings\User\My Documents\wii64saveSwap\wii64conerter.exe" "C:\Documents and Settings\User\My Documents\wii64saveSwap\ZELDA MAJORA'S MASK(U).fla" .fla "ZELDA MAJORA'S MASK(U)" "C:\Documents and Settings\User\My Documents\wii64saveSwap\"
    Everything from the batch file is being passed perfectly. This is what I get now (with a few tweaks to the passing) as the filepath output:
    Code:
    C:\Documents and Settings\User\My Documents\wii64saveSwap"ZELDA MAJORA'S MASK(U).fla
    Press any key to continue . . .
    Here's the current batch file, and the lines that are giving that output:
    Code:
    :start
    
    set batPath=%~dp0
    
    set fileExt=%~x1
    set fileTitle=%~n1
    set filePath=%~dp1
    
    "%batPath%wii64converter.exe" %1 %fileExt% "%fileTitle%" "%filePath%"
    
    :end
    Code:
    ext = argv[2];
        
        name = argv[3];
        
        savePath = argv[4];
        
        printf("%s\%s%s", savePath, name, ext);
    EDIT: Aye carumba... I finally figured it out. As the path was being passed through the batch file, it had a trailing back slash which was making the program interpret the last quote as an actual character. Adding a second back slash to the end before the quote fixed it.
    Last edited by Molokai; 10-17-2009 at 02:00 PM.

  6. #6
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    Alright, did some fooling with your batch file setup. Your batch file will do interesting things to the quotes off of your %1 argument, if that was quoted. So I got something like this:
    Code:
    bob.bat "with quotes"
    turned into
    Code:
    temp.exe ""with quotes"" ".fla" "something with spaces" "something with spaces"
    which had a net result of that %1 not being quoted at all.

  7. #7
    Registered User
    Join Date
    May 2007
    Posts
    77
    Yeah, I got that one. The batch file is all setup now.

    Now I'm getting the problem that it won't open the new file correctly... Is there some alternative to sprintf that I can use? (other than vsprintf).

  8. #8
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    An alternative to sprintf ... to do what? (I.e., I'm not exactly seeing the connection between sprintf and opening files. Are you trying to build the full path name?)

  9. #9
    Registered User
    Join Date
    May 2007
    Posts
    77
    Yes, I am trying to build the full path. That's why I was trying to pass all those different portions of the path in the first place.

    Here's my whole code as it stands now:
    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <limits.h>
    #include <stdint.h>
    
    main(int argc, char *argv[])
    {
        FILE* originalSave;
        FILE* newSave;
        long fileSize;
        long finalSize;
        uint32_t *buffer, result = 0;
        int x;
        char *savePath;
        char *name;
        char *ext;
        char *saveText;
    
        originalSave = fopen(argv[1], "rb");
        if (originalSave == NULL){
            printf("Original file unopened");
            system("PAUSE");
            return 1;
        }
        
        ext = argv[2];
        
        name = argv[3];
        
        savePath = argv[4];
        
        //printf("savePath = %s\nname = %s\next = %s\n", savePath, name, ext);
        
        //printf("%s\%s%s\n", savePath, name, ext);
        
        //system("PAUSE");
        
        //return(0);
        
        sprintf(saveText, "%s%s(Wii64)%s", savePath, name, ext);
    
        newSave = fopen(saveText, "wb");
    
        fseek(originalSave, 0, SEEK_END);
        fileSize = ftell(originalSave);
        rewind(originalSave);
        
        if (fileSize < 16384)
            finalSize = 16384;
        else if (fileSize < 32768)
            finalSize = 32768;
        else if (fileSize < 65536)
            finalSize = 65536;
        else if (fileSize < 131072)
            finalSize = 131072;
        else if (fileSize < 262144)
            finalSize = 262144;
        else if (fileSize < 524288)
            finalSize = 524288;
        
        buffer = (uint32_t*) malloc(sizeof(char)*fileSize);
        
        for (x = 0; x < fileSize/4; x++)
        {
            fread(buffer, 1, 4, originalSave);
            result = ((*buffer << 24) & 0xFF000000) | 
            ((*buffer << 8) & 0x00FF0000) |
            ((*buffer >> 8) & 0x0000FF00) |
            ((*buffer >> 24) & 0x000000FF);
            fwrite(&result, 1, 4, newSave);
        }
        
        result = 11111111;
        
        for (x = 0; x < (finalSize-fileSize); x++)
        {
            fwrite(&result, 1, 1, newSave);
        }
    
        fclose(newSave);
        fclose(originalSave);
        free(buffer);
    
        return 0;
    }
    P.S. Really sad you guys don't have the spoiler tags enabled...

    And yes, this code actually works. I've converted a file and tested its use to determine it was a successful conversion. That was before I tried dynamically determining the full path and name, etc, of the new file.

  10. #10
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    Code:
    sprintf(saveText, "%s%s(Wii64)%s", savePath, name, ext);
    Oh dear. Did you expect saveText to magically grow enough space to hold all that? Currently saveText points to somewhere in New Jersey. You probably want it to point to a chunk of memory somewhere inside your own computer.

    Also did you get your slashes straightened out at the end of your path?

  11. #11
    Registered User
    Join Date
    May 2007
    Posts
    77
    Ah, yes, of course. I needed a little allocation for that. Thank you so much. It all works perfectly now.

    And yes, I had those slashes straightened out a while ago. Darn escape characters, lol.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. char Handling, probably typical newbie stuff
    By Neolyth in forum C Programming
    Replies: 16
    Last Post: 06-21-2009, 04:05 AM
  2. Inheritance Hierarchy for a Package class
    By twickre in forum C++ Programming
    Replies: 7
    Last Post: 12-08-2007, 04:13 PM
  3. gcc link external library
    By spank in forum C Programming
    Replies: 6
    Last Post: 08-08-2007, 03:44 PM
  4. Using string operations to save part of a file path
    By JackR in forum C++ Programming
    Replies: 4
    Last Post: 05-31-2007, 03:48 PM