Thread: Running/calling Dos under XP

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

    Unhappy Running/calling Dos under XP

    Gudday all
    It seems to be a simple task but one that has taxed my obsolete grey matter to the hilt.
    I would like call the dos command string dir /b | findstr /c:".RPT" from a C program and return the value as a variable. This variable is a file name of form *.RPT. I would then like to use this variable to open that file for manipulation. (I am using the dos command as the name of the .RPT file can vary depending upon day and date of creation.)
    Code:
    system("dir /b | findstr /c:\".RPT\" ");
    
    inputFile = fopen("<file name found by system call>", "r"); //fopen("file name","mode i.e r-read");
    The above code sends to the screen the .RPT file name e.g. it finds it quite well. See attachment.
    I originally used system() as noted above but am aware that there are other alternatives viz. fork(), pipe() etc:

    What would be the best alternative to use to get the information back to my C program so that I may use it?

    [But how do I prevent it from being echoed to the screen and also have it so that I may use it as I wish?]

  2. #2
    'Allo, 'Allo, Allo
    Join Date
    Apr 2008
    Posts
    639
    If you're searching for files, it's usually easier to use functions that search for files rather than having to mess around with string parsing

    Code:
    // you'll need to include <io.h> 
    struct _finddata_t fileData = {0};
    // start a search for all files with an extension of "rpt"
    intptr_t searchHandle = _findfirst("*.rpt", &fileData);
    // if the search started
    if(searchHandle != -1)
    {
           // print a banner
    	puts("Found the following files:");
    	do
    	{
                    // print the file name
    		puts(fileData.name);
    	}
            // look for any more files
    	while(_findnext(searchHandle, &fileData) == 0);
            // stop the search after all have been enumerated
    	_findclose(searchHandle);
    }
    else
    {
           // if we couldn't start a search, print out the reason
    	perror("Couldn't enumerate files: ");
    }
    Last edited by adeyblue; 06-24-2009 at 08:05 PM. Reason: Abachler style spelling

  3. #3
    Guest Sebastiani's Avatar
    Join Date
    Aug 2001
    Location
    Waterloo, Texas
    Posts
    5,708
    >> If you're searching for files, it's usually easier to use functions that search for files rather than having to mess around with string parsing

    That won't recurse a directory, though. There are a few cross-platform libraries that can do this, including boost::filesystem.

    If you want to parse the output of the command, you'll need to use 'popen' instead of 'system', ie:

    Code:
    #include <stdio.h>
    
    int main( void )
    {
    	int
    		success = 0;
    	size_t
    		read = 0;	
    	const size_t
    		size = 1024;
    	char 
    		buffer[ size + 1 ];
    	const char*
    		command = "dir /b | findstr /c:\".RPT\" ";
    	FILE*
    		pipe = popen( command, "r" );
    	if( pipe )
    	{
    		for( ;; )
    		{
    			read = fread( buffer, 1, size, pipe );
    			if( read == 0 )
    				break;
    			success = 1;	
    			buffer[ read ] = 0;
    			printf("Buffer:\n***\n%s\n***\n", buffer );
    			if( read < size )
    				break;
    		}		
    		pclose( pipe );
    	}
    	if( !success ) 
    	{
    		fprintf( stderr, "Error: could not not execute command: %s\n", command );
    		return 1;
    	}
    	return 0;		
    }
    Code:
    #include <cmath>
    #include <complex>
    bool euler_flip(bool value)
    {
        return std::pow
        (
            std::complex<float>(std::exp(1.0)), 
            std::complex<float>(0, 1) 
            * std::complex<float>(std::atan(1.0)
            *(1 << (value + 2)))
        ).real() < 0;
    }

  4. #4
    Registered User Tigers!'s Avatar
    Join Date
    Jun 2009
    Location
    Melbourne, Australia
    Posts
    49
    Quote Originally Posted by adeyblue View Post
    If you're searching for files, it's usually easier to use functions that search for files rather than having to mess around with string parsing

    Code:
    // you'll need to include <io.h> 
    struct _finddata_t fileData = {0};
    // start a search for all files with an extension of "rpt"
    intptr_t searchHandle = _findfirst("*.rpt", &fileData);
    // if the search started
    if(searchHandle != -1)
    {
           // print a banner
    	puts("Found the following files:");
    	do
    	{
                    // print the file name
    		puts(fileData.name);
    	}
            // look for any more files
    	while(_findnext(searchHandle, &fileData) == 0);
            // stop the search after all have been enumerated
    	_findclose(searchHandle);
    }
    else
    {
           // if we couldn't start a search, print out the reason
    	perror("Couldn't enumerate files: ");
    }
    Thank you for that. It works a treat. Is fileData the variable that contains the output? Could I use that data elsewhere i.e. if i wrote more code around it? If so how would I express the variable? Would a pointer be ok or just the variable as it is?
    Last edited by Tigers!; 06-24-2009 at 10:50 PM. Reason: Left out a ?

  5. #5
    Registered User Tigers!'s Avatar
    Join Date
    Jun 2009
    Location
    Melbourne, Australia
    Posts
    49
    Quote Originally Posted by Sebastiani View Post
    >> If you're searching for files, it's usually easier to use functions that search for files rather than having to mess around with string parsing

    That won't recurse a directory, though. There are a few cross-platform libraries that can do this, including boost::filesystem.

    If you want to parse the output of the command, you'll need to use 'popen' instead of 'system', ie:

    Code:
    #include <stdio.h>
    
    int main( void )
    {
    	int
    		success = 0;
    	size_t
    		read = 0;	
    	const size_t
    		size = 1024;
    	char 
    		buffer[ size + 1 ];
    	const char*
    		command = "dir /b | findstr /c:\".RPT\" ";
    	FILE*
    		pipe = popen( command, "r" );
    	if( pipe )
    	{
    		for( ;; )
    		{
    			read = fread( buffer, 1, size, pipe );
    			if( read == 0 )
    				break;
    			success = 1;	
    			buffer[ read ] = 0;
    			printf("Buffer:\n***\n%s\n***\n", buffer );
    			if( read < size )
    				break;
    		}		
    		pclose( pipe );
    	}
    	if( !success ) 
    	{
    		fprintf( stderr, "Error: could not not execute command: %s\n", command );
    		return 1;
    	}
    	return 0;		
    }
    That works fine. Is it buffer that contains the names of the RPT files? Is buffer a variable that I could use elsewhere?

  6. #6
    Guest Sebastiani's Avatar
    Join Date
    Aug 2001
    Location
    Waterloo, Texas
    Posts
    5,708
    >> Is it buffer that contains the names of the RPT files?

    Yes, but unless you read everything in one fell swoop, you'll have to assemble it into a secondary buffer before parsing.
    Code:
    #include <cmath>
    #include <complex>
    bool euler_flip(bool value)
    {
        return std::pow
        (
            std::complex<float>(std::exp(1.0)), 
            std::complex<float>(0, 1) 
            * std::complex<float>(std::atan(1.0)
            *(1 << (value + 2)))
        ).real() < 0;
    }

  7. #7
    'Allo, 'Allo, Allo
    Join Date
    Apr 2008
    Posts
    639
    Quote Originally Posted by Sebastiani View Post
    That won't recurse a directory, though.
    Oops good spot, for anybody intested I've fixed it so it does the same recursing as XP's dir does.

    Is fileData the variable that contains the output?
    fileData.name is the name of your rpt file, you can do anything that you can do with normal strings with it, including giving it to fopen like in your initial post. As long as you finish using it before the findnext, when it'll become the name of the next rpt file etc.

  8. #8
    Guest Sebastiani's Avatar
    Join Date
    Aug 2001
    Location
    Waterloo, Texas
    Posts
    5,708
    >> for anybody intested I've fixed it so it does the same recursing as XP's dir does.

    Looks like the same code to me??
    Code:
    #include <cmath>
    #include <complex>
    bool euler_flip(bool value)
    {
        return std::pow
        (
            std::complex<float>(std::exp(1.0)), 
            std::complex<float>(0, 1) 
            * std::complex<float>(std::atan(1.0)
            *(1 << (value + 2)))
        ).real() < 0;
    }

  9. #9
    Registered User
    Join Date
    Aug 2006
    Posts
    163
    Just to kind of answer the original question, here's what I've done for this in C++ before. I'm not sure if it can be easily switch to C, though:

    Code:
        FILE* stream = _popen( "dir", "r" );
        std::ostringstream output;
    
        while( !feof( stream ) && !ferror( stream ))
        {
            char buf[128];
            int bytesRead = fread( buf, 1, 128, stream );
            output.write( buf, bytesRead );
        }
        std::string result = output.str();

  10. #10
    Registered User
    Join Date
    Jul 2007
    Posts
    43
    system_159 what include files do I need to make that work? Doesnt compile for me

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Question..
    By pode in forum Windows Programming
    Replies: 12
    Last Post: 12-19-2004, 07:05 PM
  2. XP style in DOS !
    By skywing in forum C Programming
    Replies: 7
    Last Post: 05-03-2004, 07:34 PM
  3. Direct Connect between XP and DOS
    By lightatdawn in forum Tech Board
    Replies: 0
    Last Post: 01-22-2004, 11:22 PM
  4. Dos differences in Windows NT and Windows XP
    By Ruchikar in forum A Brief History of Cprogramming.com
    Replies: 5
    Last Post: 09-17-2003, 11:36 PM
  5. loading DOS app before XP startup: is it even possible?
    By toaster in forum A Brief History of Cprogramming.com
    Replies: 6
    Last Post: 05-26-2002, 04:59 PM