Thread: The C system command with long filenames in windowsXP

  1. #16
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    It's hard to belive that someone who's been "programming in hex before I(sic) was born" can be so ........ing stupid.


    Quzah.
    Hope is the first step on the road to disappointment.

  2. #17
    Fountain of knowledge.
    Join Date
    May 2006
    Posts
    794
    Quote Originally Posted by dwks
    To the OP: are you sure that in both versions you escaped your backslashes? It sounds suspicious that it works in a batch file but not in a C program. This was Dave_Sinkula's original point: \* isn't a vaild escape sequence.
    Code:
    system("dir 2e6d1\*.log /b /s  >dirs.doc");
    ->
    Code:
    system("dir 2e6d1\\*.log /b /s  >dirs.doc");

    Err....Possibly, you may well be right, but if you look at the original rwo lines:-

    Code:
    system("dir 2e6d1\*.log /b /s  >dirs.doc");
    and
    Code:
    system("dir 2e6d1763e3000000\*.log /b /s  >dirs.doc");
    You will see they both contain the same escape sequence, I am sure of this because
    the "system" command's arguements are generated by the program based upon the folders
    name as follows:-

    Code:
    sprintf(xstring, "dir %s\\*.log /b /s  >dirs.doc",var2);
    xret=system(xstring);
    You can see I have a valid escape sequence in the sprintf bit ("var2" is the lazily names folder name!!), I don't think I have to have a futher escape sequence for the system() function.
    But anyway it worked on short names but not long names so that would rule out the escape
    sequence problem.


    Anyway..... I seem to have got the program working (after a long struggle!!), although it still
    has a slight problem when it tries to create a directory which already exists.

    Perhaps I should explain what the program does, or more to the point why I am writing it.
    When I play online poker the history of each game is stored in a file in a folder which contains all
    the hand history files for that day, so a folder can have hundreds of files in it. Unfortunately the folders have obscure file names such as "0a8c06004351b0ed66b4ecbf0000000" which is problem when you have hundreds of such folders so I wanted to change to folder name to
    the date on which the games were played, for example today would have a folder named "20060910" (sept 10 2006).
    I can grap the date because each hand history has the date on the first line as follows:-

    -----------------------
    Game #3099446304: Hold'em FL (£0.35/£0.70) - 2006/07/24 - 02:04:59 (UK)
    Table "Pisces" Seat 4 is the button.
    Seat 1: player1 (£14.85 in chips)
    Seat 2: pplayer2 (£19.36 in chips)
    Seat 3: anotherpe (£20 in chips)
    Seat 4: namedchanhged (£17.50 in chips)
    Seat 5: chamged (£45.42 in chips)
    Seat 6: another (£19.22 in chips)
    another: posts small blind £0.20
    changed: posts big blind £0.35
    etc....
    ------------------------------

    However sometimes more than one folder is used to hold the files on a particular day if you play
    loads of games. This means my program tries to rename to a folder which already exists
    which is a (the last) problem I have to fix

    Anyway it works now apart from the above problem!!

    As it was it would only save about 3 months hand history because it deleted older folders and resused the names, but now I will have a folder for each date.

    Here is the ugly crap code, it's full of debug stuff and bodged/redundant code and requires
    some othe batch files to get it working, but it does the job. Hope you understand it because I don't!!


    Code:
    
    #include <stdio.h>
    
    #define TRUE 1
    #define FALSE 0
    #define MINUS -1
    #define POSITIVE 0
    #define MAXLIST 2100
    
    int filelist, filelist2, xret, nodate;
    char *dateptr;
    FILE *ptr1, *d_log_ptr, *dirsptr, *logptr, *moredirs_bat_ptr;
    char newname[20];
    char var2[2010];
    char var3[2010];
    char xstring[2010];
    
    main(argc,argv)
    	int  argc;
    	char *argv[]; 
    {
    	printf("\n  NEW      H33321");
    	if (	(d_log_ptr=fopen("d.log","r")) == NULL) {
    			
    			puts("file2 does not exist");
    			printf("\nHa");
    			exit(2);	/* an early file does not exist	*/
    	}
    	
    	
    	if (	(moredirs_bat_ptr=fopen("moredirs.bat","w")) == NULL) {
    			
    			puts("\nCant dirs batch file");
    			printf("\nHb");
    			exit(2);	/* an early file does not exist	*/
    	}
    	
    
    			fprintf(moredirs_bat_ptr,"del dirs.doc\n");
    	do {  /* for each file in directory list */
    			filelist=fscanf(d_log_ptr,"%[^\n]\n",var2);  
    			printf("\nfilelist <%d>",filelist);
    			/* if (filelist==-1) break; */
    			sprintf(xstring, "dir %s\\*.log /b /s  >dirs.doc",var2);
    			printf("\n%s",xstring);
    			fclose(moredirs_bat_ptr);
    			xret=system(xstring);
    			printf("\nxret <%d>",xret);
    			/* open a list of logfiles in a directory */
    			if (	(dirsptr=fopen("dirs.doc","r")) == NULL) {
    				puts("dirs.doc does not exist");
    				exit(2);	/* an early file does not exist	*/
    			}
    			printf("\nH21");
    			
    			nodate=0;
    			while(1) {
    				filelist2=fscanf(dirsptr,"%[^\n]\n",var3);  
    				printf("\n TRY filelist2 <%d><%d>", filelist2, EOF);
    				if (filelist2==EOF) {
    					nodate=1;
    					printf("\n*********break ***");
    					break;
    				}
    				printf(" Dirsptr<%s>",var3);
    				printf("\n dirsptr code <%d>",filelist2);
    				/* open the log file */
    				if (	(logptr=fopen(var3,"r")) == NULL) {
    					puts("logfile does not exist");
    					printf("\nHc");
    					exit(2);	/* an early file does not exist	*/
    				}
    				filelist2=fscanf(logptr,"%[^\n]\n",var3);  
    				fclose(logptr); /* we only want first line */
    			
    				printf("\nvar3log<%s>",var3);
    				dateptr=strstr(var3," - ");
    				if (( strncmp(dateptr+3," ",1)) ==0) 
    				{
    					printf("\n DUFF DATE ");
    				
    					continue; /* invalid date */
    				}
    				else break;
    			}
    			fclose(dirsptr); /* close it we have read the line we want */
    		
    		if (nodate==1) continue;
    		
    		
    		printf("DATE <%4.4s%2.2s%2.2s>\n",dateptr+3 ,dateptr+8,dateptr+11);
    		
    		sprintf(newname,"%4.4s%2.2s%2.2s",dateptr+3 ,dateptr+8,dateptr+11);
    		printf("newname <%s>",newname);
    		rename(var2,newname);
    		
    		fclose(logptr);
    
    	}
    			
    	while (  filelist!=-1);
    	
    	fprintf(moredirs_bat_ptr,"go.bat \n");
    	fclose(d_log_ptr);
    	fclose(moredirs_bat_ptr);
    }/*main */
    A great example of how not to write code

  3. #18
    Fountain of knowledge.
    Join Date
    May 2006
    Posts
    794
    In summary I think the original problem was that the command line interpreturer invoked
    by the system() command in the program was not the same one invoked when when you run
    command.com (or a .bat (batch) file), the system command used 8 character filenames whilst
    running 'command.com' from START/RUN 'menu' could cope with long filenames.

    Anyway I am off to play poker as I am too drunk to code now!! (last couple of nights have been very profitable).
    I wouuld add that hand history analysis programs don't really help you play poker, it is too complicated. I just liked the challange of writing the program(s).

  4. #19
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    > if I was running Unix I would have done this in 2 minutes.
    So get cygwin installed and use bash - problem solved.
    You can quite happily do anything anywhere on the filesystem, it isn't restricted to some virtual playpen inside cygwin itself.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  5. #20
    Yes, my avatar is stolen anonytmouse's Avatar
    Join Date
    Dec 2002
    Posts
    2,544
    djgpp is a DOS compiler. If you want to program for Windows, get yourself a Windows compiler (Dev-C++, MinGW, Code-Blocks, MSVC, etc).

  6. #21
    Fountain of knowledge.
    Join Date
    May 2006
    Posts
    794
    Quote Originally Posted by anonytmouse
    djgpp is a DOS compiler. If you want to program for Windows, get yourself a Windows compiler (Dev-C++, MinGW, Code-Blocks, MSVC, etc).
    I think I tried Dev-C++, I ended up using gcc. I found it much more usable barring the long filename thing. I recall having some probs with DevC++ but I forget what they were.

  7. #22
    erstwhile
    Join Date
    Jan 2002
    Posts
    2,227
    Dev-cpp uses MinGW - the windows port of gcc.
    CProgramming FAQ
    Caution: this person may be a carrier of the misinformation virus.

  8. #23
    Fountain of knowledge.
    Join Date
    May 2006
    Posts
    794
    Quote Originally Posted by Ken Fitlike
    Dev-cpp uses MinGW - the windows port of gcc.
    Well I used to have it on my old machine but I put gcc on my new machine, I can't remember what the probs with Dev-cpp were for me. I think I found it difficult to use, and maybe I was having some probs with librarys or something like that. Also I am not too keen on the GUI development enviroment. I like to use my own editor etc.. I think I had the Borland C as well but that was a pile of **** as far as I can remember.

    Maybe I will give it another try, but other than the long filename prob gcc has been fine for me,
    it is more of the 'old type' enviroment that I am used to, where I feel in control and know what is happening!! I don't like learning new tricks.

    Anyway I have finished the program now and it works fine as long as I shorten the folder names before starting, as I am renaming them anyway thats not an issue.
    The prog converts a unwieldy set of folders such as this:-

    b3bd23002b68ab4fe9e7708100000000
    4dd02300f234f5d7d51c796200000000
    7ad82300ca64e99cc6747bcc00000000
    250925000c4f0eabeac2557800000000
    76292600d33a631f4095b60900000000
    c63d2700a224fb719a43951900000000
    493f2800487ccd48decdda8000000000
    ddf92d00007dfe47616188c500000000
    e0ab3d002005dc95b588a8ec00000000
    e0df3f00dab1169f326c24ea00000000
    e9da2300392600504a1ead7800000000
    eb62080051d22c2cbf998b1600000000
    ebbb15003f1816c736982ae900000000
    edf70d00c55a59ac818c8e6700000000
    ef000100e1317cbae329c34500000000
    fa560600c182b79f2e1e13e900000000
    fd4644008bb7465aa4aa823a00000000
    fdca2400f274c4068648424100000000
    0d832000bc1972cef133b9b100000000
    0e0d41004142ead0d0942b8900000000
    0f291f0094b9279fd80aad4700000000
    1a491100e9568bed0cdc9fb300000000
    2e6d13005dcb48ded0b326d000000000
    2e97190091b33a9efef0c98500000000
    2eca25000b683be99f59827900000000
    3a8108004b77f1c2064561e300000000
    3b2e1d0006b58aa25e750a5000000000


    Into something more managable like this:-

    20060301
    20060308
    20060224
    20060321
    20060212
    20060210
    20060127
    20060427
    20060426
    20060425
    20060424
    20060423
    20060423_04
    20060423_01
    20060810
    20060810_02
    20060809
    20060808
    20060808_04
    20060807
    20060806
    20060805
    20060805_01
    20060804
    20060803
    20060802
    20060801
    20060731
    20060730
    20060729
    20060728
    20060727
    20060727_02
    20060726

    In year, month, date format, sometimes there is more than one folder with the same date so
    the bit after the _ is the hour it was created.

    This is the modified and tidied up prog

    Code:
    #include <stdio.h>
    #define TRUE 1
    #define FALSE 0
    #define MINUS -1
    #define POSITIVE 0
    
    
    int filelist, filelist2, xret, nodate;
    char *dateptr;
    FILE *ptr1, *d_log_ptr, *dirsptr, *logptr, *moredirs_bat_ptr;
    char newname[20];
    char newname2[20];
    char var2[2010];
    char var3[2010];
    char xstring[2010];
    
    main(argc,argv)
    	int  argc;
    	char *argv[]; 
    {
    
    	if (	(d_log_ptr=fopen("d.log","r")) == NULL) {
    			puts("file2 does not exist");
    			exit(2);	/* an early file does not exist	*/
    	}
    
    	do {  /* for each file in directory list */
    			filelist=fscanf(d_log_ptr,"%[^\n]\n",var2);  
    			if (filelist==-1) break; 
    			sprintf(xstring, "dir %s\\*.log /b /s  >dirs.doc",var2);
    			xret=system(xstring);
    			/* open a list of logfiles in a directory */
    			if (	(dirsptr=fopen("dirs.doc","r")) == NULL) {
    				puts("dirs.doc does not exist");
    				exit(2);	/* an early file does not exist	*/
    			}
    			nodate=0;
    			while(1) {
    				filelist2=fscanf(dirsptr,"%[^\n]\n",var3);  
    				if (filelist2==EOF) {
    					nodate=1;
    					break;
    				}
    				/* open the log file */
    				if (	(logptr=fopen(var3,"r")) == NULL) {
    					puts("logfile does not exist");
    					exit(2);	/* an early file does not exist	*/
    				}
    				filelist2=fscanf(logptr,"%[^\n]\n",var3);  
    				fclose(logptr); /* we only want first line */
    				dateptr=strstr(var3," - ");
    				if (( strncmp(dateptr+3," ",1)) ==0) 
    				{
    					continue; /* invalid date */
    				}
    				else break;
    			}
    			fclose(dirsptr); /* close it we have read the line we want */
    		
    		if (nodate==1) continue;
    		sprintf(newname,"%4.4s%2.2s%2.2s",dateptr+3 ,dateptr+8,dateptr+11);
    		if (rename(var2,newname) !=0 ) {
    			sprintf(newname,"%s_%2.2s",newname, dateptr+16);
    			if ( rename(var2,newname) !=0 ) {
    				printf("\n error");
    			}
    		}
    			fclose(logptr);
    	}
    	while (  filelist!=-1);
    }/*main */

    You need to run a batch file in the folder first to create a list of folders (d.log), or run it from dos.

    dir /b /od /x *. >d.log

    You might find the program useful if you play poker on any poker site which uses cryptologic
    software. Seems to work fine
    Last edited by esbo; 09-10-2006 at 07:44 PM.

  9. #24
    Fountain of knowledge.
    Join Date
    May 2006
    Posts
    794
    I guess I could add a signal handler incase it gets stuck in a loop, but I don't think there any bugs in it!!

  10. #25
    Frequently Quite Prolix dwks's Avatar
    Join Date
    Apr 2005
    Location
    Canada
    Posts
    8,057
    There are several problems with your program that I can see. From http://opengroup.org/onlinepubs/0079...sh/fscanf.html:
    RETURN VALUE
    Upon successful completion, these functions return the number of successfully matched and assigned input items; this number can be 0 in the event of an early matching failure. If the input ends before the first matching failure or conversion, EOF is returned. If a read error occurs the error indicator for the stream is set, EOF is returned, and errno is set to indicate the error.
    You have
    Code:
    				filelist2=fscanf(dirsptr,"%[^\n]\n",var3);  
    				if (filelist2==EOF) {
    Rather than comparing the result to EOF, you should compare the result to 1:
    Code:
    				filelist2=fscanf(dirsptr,"%[^\n]\n",var3);  
    				if (filelist2!=1) {
    Another thing:
    Code:
    if (( strncmp(dateptr+3," ",1)) ==0)
    Why not just use this?
    Code:
    if ( dateptr[3] == ' ' )
    Some of your errors have a newline printed after them
    Code:
    puts("file2 does not exist");
    and some before
    Code:
    printf("\n error");
    This is sure to cause some problems.

    exit() is in stdlib.h.

    Code:
    	do {  /* for each file in directory list */
    			filelist=fscanf(d_log_ptr,"%[^\n]\n",var2);  
    			if (filelist==-1) break; 
    
    /*...*/
    
    	}while (  filelist!=-1);
    Don't you think you could use a while loop for that?

    Why is main() declared with the old-style function definition?
    dwk

    Seek and ye shall find. quaere et invenies.

    "Simplicity does not precede complexity, but follows it." -- Alan Perlis
    "Testing can only prove the presence of bugs, not their absence." -- Edsger Dijkstra
    "The only real mistake is the one from which we learn nothing." -- John Powell


    Other boards: DaniWeb, TPS
    Unofficial Wiki FAQ: cpwiki.sf.net

    My website: http://dwks.theprogrammingsite.com/
    Projects: codeform, xuni, atlantis, nort, etc.

  11. #26
    Fountain of knowledge.
    Join Date
    May 2006
    Posts
    794
    Well points taken dwks but the program works and that is all I am concerned about!!

    Point 1 EOF works as well as 1.


    >Another thing:

    Code:
    if (( strncmp(dateptr+3," ",1)) ==0) Why not just use this?
    Code:
    if ( dateptr[3] == ' ' )


    Just lazy programming I had been working with the file in strings and I didn't
    want to change to characters, less chance of making a silly coding error, and I was thinking in strings at the time.


    >Some of your errors have a newline printed after them
    Code:
    
    puts("file2 does not exist");and some before
    Code:
               
    printf("\n error");

    >This is sure to cause some problems.



    Not really, the program just originated from a program I copied, as a rule I don't use puts usually, but it was already there so I don't modify working code, I always put a newline first.

    Exit() gave no compiler/linker error.

    I used that loop like that because of the way I developed the program, I don't care if it's not
    elegant - it works!!


    It's declared old style because it is copied again and more importantly - it works!!

    In short I would rather have a badly written program which works than a correctly (in style)
    written program which doesn't!! Substance over style is what I want!!

    When I started programming I couldn't afford books etc..but my programs worked, which is more
    than those written by the book learned 'experts' programms did!!
    Last edited by esbo; 09-10-2006 at 08:52 PM.

  12. #27
    Frequently Quite Prolix dwks's Avatar
    Join Date
    Apr 2005
    Location
    Canada
    Posts
    8,057
    Well points taken dwks but the program works and that is all I am concerned about!!

    Point 1 EOF works as well as 1.
    No it does not, as I was trying to point out; you should compare against EOF instead of 1 in case it returns 0.

    Exit() gave no compiler/linker error.
    Well it should have; since it didn't, you don't have warnings enabled, which could cause you problems in the future.

    I used that loop like that because of the way I developed the program, I don't care if it's not
    elegant - it works!!
    Yes but you have repeated code, which should be avoided if possible.

    It's declared old style because it is copied again and more importantly - it works!!

    In short I would rather have a badly written program which works than a correctly (in style)
    written program which doesn't!! Substance over style is what I want!!

    When I started programming I couldn't afford books etc..but my programs worked, which is more
    than those written by the book learned 'experts' programms did!!
    You seem obsessed with having programs that work with your compiler and input and enviroment, never mind some one else's compiler or larger buffer or prompt that doesn't print a newline after your program exits. If you have this
    Code:
    printf("\nerror");
    exit(1);
    and you run it on Linux, it will look something like this
    Code:
    $ ./program
    
    error$
    whereas if you printed the newline after the message it would look like this
    Code:
    $ ./program
    error
    $
    The old-style function declaration might work on your compiler but it is deprecated and might not work on others.
    dwk

    Seek and ye shall find. quaere et invenies.

    "Simplicity does not precede complexity, but follows it." -- Alan Perlis
    "Testing can only prove the presence of bugs, not their absence." -- Edsger Dijkstra
    "The only real mistake is the one from which we learn nothing." -- John Powell


    Other boards: DaniWeb, TPS
    Unofficial Wiki FAQ: cpwiki.sf.net

    My website: http://dwks.theprogrammingsite.com/
    Projects: codeform, xuni, atlantis, nort, etc.

  13. #28
    Supermassive black hole cboard_member's Avatar
    Join Date
    Jul 2005
    Posts
    1,709
    Quote Originally Posted by Dave_Sinkula
    Yes, I knew that. The same as I know a forward slash is easier to work with.

    Perhaps the MSDN has something about converting long filenames to short filenames?
    Talking of which, do these functions "take" forward slashes as back slashes in a Windows environment?

    Just occured to me I've never tried and have been at the hands of \\ for years.
    Good class architecture is not like a Swiss Army Knife; it should be more like a well balanced throwing knife.

    - Mike McShaffry

  14. #29
    Frequently Quite Prolix dwks's Avatar
    Join Date
    Apr 2005
    Location
    Canada
    Posts
    8,057
    Functions like rename() take forward slashes and backslashes, at least with Dev-C++.
    dwk

    Seek and ye shall find. quaere et invenies.

    "Simplicity does not precede complexity, but follows it." -- Alan Perlis
    "Testing can only prove the presence of bugs, not their absence." -- Edsger Dijkstra
    "The only real mistake is the one from which we learn nothing." -- John Powell


    Other boards: DaniWeb, TPS
    Unofficial Wiki FAQ: cpwiki.sf.net

    My website: http://dwks.theprogrammingsite.com/
    Projects: codeform, xuni, atlantis, nort, etc.

  15. #30
    Fountain of knowledge.
    Join Date
    May 2006
    Posts
    794
    Quote Originally Posted by dwks
    No it does not, as I was trying to point out; you should compare against EOF instead of 1 in case it returns 0.


    Well it should have; since it didn't, you don't have warnings enabled, which could cause you problems in the future.


    Yes but you have repeated code, which should be avoided if possible.


    You seem obsessed with having programs that work with your compiler and input and enviroment, never mind some one else's compiler or larger buffer or prompt that doesn't print a newline after your program exits. If you have this
    Code:
    printf("\nerror");
    exit(1);
    and you run it on Linux, it will look something like this
    Code:
    $ ./program
    
    error$
    whereas if you printed the newline after the message it would look like this
    Code:
    $ ./program
    error
    $
    The old-style function declaration might work on your compiler but it is deprecated and might not work on others.
    Well the EOF thing is not a problem at the moment. I do have warnings enabled. I get lots (5) of them, but not about exit.

    The proram works on my compiler and my machine, which is fortunete because that is where it runs!!

    The program is designed to run on Linux like that its a feature of thre program!!
    It's old style so it will also run on old style compilers, so its a portable program which
    will run on other machines/compilers.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Inserting a swf file in a windows application
    By face_master in forum Windows Programming
    Replies: 12
    Last Post: 05-03-2009, 11:29 AM
  2. hton long long
    By carrotcake1029 in forum C Programming
    Replies: 1
    Last Post: 06-01-2008, 08:26 PM
  3. error: double free or corruption
    By dsc in forum C Programming
    Replies: 3
    Last Post: 04-03-2008, 09:26 AM
  4. need help
    By emperor in forum C Programming
    Replies: 1
    Last Post: 03-04-2002, 12:26 PM
  5. can someone check this out and let me know ?
    By javaz in forum C Programming
    Replies: 5
    Last Post: 01-21-2002, 02:13 PM