Solved

Opening files without specifing file names

Posted on 2000-04-03
22
210 Views
Last Modified: 2010-04-02
I have a bunch of files in a directory that I want to read in. I don't want to have to enter the name of each file, I would rather have it read in the first file, do the work on it, then read in the next file, do the work on this, and so on...
0
Comment
Question by:llagreca
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 6
  • 6
  • 4
  • +3
22 Comments
 
LVL 2

Expert Comment

by:dirc
ID: 2680724
You can use the opendir(), readdir(), and closedir() functions to determine which files are in the directory.
0
 
LVL 22

Expert Comment

by:cookre
ID: 2680771
Presuming you want all files in the directory, use some flavor of find_first and find_next (depends on OS and runtime environment).

For example (DOS):


if (0==_dos_findfirst(TmpStr,_A_SUBDIR|_A_RDONLY|_A_HIDDEN|_A_SYSTEM,&FindBlock))
   {
   ProcessEntry(DirToScan,FindBlock);
   while (0==_dos_findnext(&FindBlock)) ProcessEntry(DirToScan,FindBlock);
   }
(Hope the formatting is legible)


One does something similar for Windows.
0
 
LVL 22

Expert Comment

by:cookre
ID: 2680794
In MSVC 6, one uses _findfirst and _findnext.
0
Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 

Author Comment

by:llagreca
ID: 2680846
How can I use that to make my code go through each file separately and have each file individually accessed to do what is needed?
0
 
LVL 22

Expert Comment

by:cookre
ID: 2681131
The findfirst initializes the processing of a directory and returns the first entry.  Subsequent calls to findnext return the next entry in the directory.  The entry name and various attributes are returned in the passed structure (FindBlock in the example).

In the example, I also pass the directory path to subroutine ProcessEntry so I can recreate the full path to the entry described in FindBlock.

Here's a bigger chunk of code:


void ProcessEntry(DirToScan,FindBlock)
char           DirToScan[];
struct _find_t FindBlock;

{
char          SubDirPath[_MAX_PATH+9];
extern void   ScanDir(char *);
char          CurFileName[_MAX_PATH+13];
unsigned long TmpULong;
unsigned int  TmpSecs;
unsigned int  TmpMins;

//
// Recurse on another directory
if (FindBlock.attrib & _A_SUBDIR)
   {
   //
   // Skip . and ..
   if ((0==strcmp(".",FindBlock.name)) || (0==strcmp("..",FindBlock.name))) return;
   //
   // Add directory to path
   strcpy(SubDirPath,DirToScan);
   strcat(SubDirPath,"\\");
   strcat(SubDirPath,FindBlock.name);
   ScanDir(SubDirPath);
   return;
   }
//
// Its a file
strcpy(CurFileName,DirToScan);
strcat(CurFileName,"\\");
strcat(CurFileName,FindBlock.name);



Here's where you fiddle with the file



return;
}





void ScanDir(DirToScan)
char *DirToScan;
{
char TmpStr[_MAX_PATH+5];
struct _find_t FindBlock;

//
// Add wild cards to path
if (DirToScan[strlen(DirToScan)-1]=='\\') DirToScan[strlen(DirToScan)-1]='\0';
strcpy(TmpStr,DirToScan);
strcat(TmpStr,"\\*.*");

//
// Scan this directory
if (0==_dos_findfirst(TmpStr
                     ,_A_SUBDIR|_A_RDONLY|_A_HIDDEN|_A_SYSTEM
                     ,&FindBlock))
   {
   ProcessEntry(DirToScan,FindBlock);
   while (0==_dos_findnext(&FindBlock)) ProcessEntry(DirToScan,FindBlock);
   }

return;
}


0
 
LVL 22

Expert Comment

by:cookre
ID: 2681140
Yeah, the formatting abilities aren't quite what we might like, but I think this larger snippet, and your library's documentation, should give you what you need.
0
 
LVL 8

Expert Comment

by:stochastic
ID: 2682699
llagreca,

cookre's answer is detailed and appropriate. But if you want to do this just once, I have a quick-and-dirty suggestion that should work. I am assuming all your files are in one directory.

1.
In a DOS box, give the command
   DIR /B > filelist.txt
This will create a file called filelist.txt with one filename per line. This may also contain "filelist.txt" itself, which you may have to remove with a text editor (notepad should do fine).

2. In your program, open this file filelist.txt. In a loop, read one line at a time (I would suggest fgets() call), so you will get one filename at a time into a string.

3. While you are still inside the loop, do whatever you want to do on this filename. (e.g. you can open that file, process it, close it).

Hope this is clear enough.

best of luck

- stochastic

0
 
LVL 10

Expert Comment

by:makerp
ID: 2682932
/*
this function recursivly scan directries. you will need to change it so it gets the first file only.

i donr this in VC++ on NT 4.0
*/

#include <stdio.h>
#include <io.h>


int scan_path(char *path)
{
     char spath[256];
     struct _finddata_t ff;
     long fhandle;

     sprintf(spath,"%s\\*",path);
     fhandle=_findfirst(spath,&ff);
     if(fhandle==-1L)
     {
          printf("Bad path\n");
          return -1;
     }
     else
     {
          /* loop through each etry in the dir */
          while(!_findnext(fhandle,&ff))
  {
               /* if its a sub-dir then recursivly call our self*/
               if(ff.attrib&_A_SUBDIR)
               {
                     if(strcmp(ff.name,".."))
                     {
                            sprintf(spath,"%s\\%s",path,ff.name);
                            scan_path(path2);
                     }
               }
               else
               {
                     /* if its a file then */
                     if(ff.attrib^_A_SYSTEM)
                     {
                            printf("Found File %s\n",ff.name);
                     }
               }
          }
     }
     return 1;
}


0
 
LVL 10

Expert Comment

by:makerp
ID: 2682939
if you just remove the subdir bit so you dont recursively call your self and put a function in the file bit passing your path/filename and you can process the file.
0
 

Author Comment

by:llagreca
ID: 2685051
I would like to do what stochastic said to do, using filelist.txt in DOS, but I am running on a SUN box. What would the command be for the SUN to do the filelist.txt in DOS?
Thanks for your helf
0
 

Expert Comment

by:P_Mahesh
ID: 2686169
I agree with what 'stochastic' had suggested

In SUN you do :

ls > filelist.txt

Then the file 'filelist.txt' will have all the names of the files.
You give this command from the directory where the files are. and provided
the directory has only the files required for processing.

hope this helps.
0
 

Author Comment

by:llagreca
ID: 2687257
Thank you very much the ls> filelist.txt worked.
One more question, how would i write the loop to read the next filename. I am just a beginner at C.
Thanks again.
0
 
LVL 8

Expert Comment

by:stochastic
ID: 2688724
llagreca,

Sorry for assuming you were on a DOS / Windows machine. And sorry for not responding to your question quickly enough, but P_Mahesh gave you the precise answer. That's the beauty of EE! So many experts willing to help out! Thanks Mahesh; hope to see you around EE oftener.

- stochastic

0
 

Author Comment

by:llagreca
ID: 2689371
I wrote the code to open filelist.txt and I can't open any of the files in the list. I think that it is reading past the filename into the blanks in the line. How can I correct this?
0
 

Expert Comment

by:P_Mahesh
ID: 2689420
Can you give the piece of code you wrote . It would be of more help.
Does the file "filelist.txt" contain all the names of the files ?
The directory from where you are executing should be the same, in which
the files are present.

 Meanwhile you can try the following logic ...

/*** I strongly advice you to go thru the syntax of each command. You shouldn't face any problems regarding the logic . I hope this is what you wanted and it works ***/

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

main( )
{

    FILE *fpt;
    FILE *fpt1;

    /*** Assuming here that no filename is more than 30 chars ***/
    char filename[30];  
    int number=30;       /***   This number should be one more than the                                                                             number ***/
                       /***    of characters in the string you are reading ***/
    char filelist[10];
   
    strcpy( filelist, "filelist" );
     
    /*** Open the file 'filelist' for reading only ***/
    fpt = fopen( filelist, "r");

    /*** You can also use this loop to read the filenames
      while( feof( fpt )==NULL )
      {
          fgets( filename, number, fpt  );
          .
          .
     }
     fclose( fpt );  ***/
   
    /*** fgets returns null when end of file is reached ***/
    while( fgets( filename, number, fpt ) != NULL )
    {
       /*** For each run, the variable 'filename' will contain the
       name of file you want to process ***/
       
      /*** Open the file in read and updating . check that
            the mode "r+" is correct  ***/
       fpt1 = fopen( filename, "r+" );

       /*** Now the filename is open for processing ***/

       ...
       ...
       ...

      /*** After completion you need to close the file 'filename' ***/
      fclose( fpt1 );
   }

   /*** After all the names have been read from file "filelist" you have to           close  it.  ***/
   fclose( fpt );

}


 thanks,
mahesh.
0
 
LVL 8

Expert Comment

by:stochastic
ID: 2689468
llagreca and mahesh,

my comments below relate to the code suggested by mahesh.

let me add a couple of comments:
a. strcpy( filelist, "filelist" );
   should probably have been
   strcpy( filelist, "filelist.txt" );

b. the fgets() function reads the whole line INCLUDING the end-of-line (newline) character, and it then adds a null character at the end. You will have to strip that newline character before you use the string as a valid filename. So after the statement
fgets(filename, number, fpt);
you should probably do
filename[strlen(filename)-1] = '\0';
to overwrite the newline with a null.
[to get strlen to work okay, you may need #include <string.h> or something. Mahesh has already put that]

c. Please keep the value of 'number' sufficiently large. It won't matter if it is much larger than actual filename length; but it will matter if it is smaller - you will get wrong results.
fgets() terminates when it finds a newline, so even if you have a large number, it will pick up only upto end of line.

For the newline reason above, your number should be at least 2 greater than the longest filename you will have. For example, if you have a filename called myfile.dat, the actual buffer size should be at least 10 for the filename + 1 for the newline + 1 for the string-terminating null = 12.

So just make 'number' big enough to avoid any possible problem. You can make it 128 or something.

d. llagreca, maybe you could insert a
printf("=%s=\n", filename); just after the fgets and the above fix, just to see what filename is actually being read. The '=' characters at both ends are just meant to be end-indicators in the screen output, so that you would know if any nonprintable character comes after the actual filename end. This will help you debug it.

Hope this works :-)

- stochastic          
0
 

Author Comment

by:llagreca
ID: 2689611
Thank you so much for your help!!! Here is my code as it is right now. Remeber, I am not a good C programmer, just a beginner. I haven't looked at the suggestions made above yet, but I am going to do that right now. Again, thanks so mcuh!!


#include <stdio.h>                                                              
#define MAXLEN 25                                                              
                                                                               
                                                                               
/*  opens filelist.txt which is a list of the file names in a specific          
    dir and prints out each one  */                                            
                                                                               
                                                                               
main()                                                                          
{ FILE *fp, *fp1; char fileName[10];                                            
  char buffer[25]; int i; char buffer1[25]; int loc;                            
  printf("Enter file name: ");                                                  
  gets(fileName);                                                              
  if ((fp = fopen("filelist.txt", "r")) == NULL) printf("\n no open");          
  while(1)                                                                      
  {                                                                            
    fgets(buffer, MAXLEN, fp);                                                  
    printf("\nfileName  = %s", buffer1);                                        
    strcpy(buffer, buffer1);                                                    
                                                                               
     for (i = 0; i <MAXLEN; i++)                                                
    {                                                                          
       printf("\nbuffer[i] = %c", buffer[i]);                                  
       if (buffer[i] = ' ')                                                    
       { loc = i;                                                              
         buffer[i] = '\0';                                                      
       }                                                                        
       if (buffer[i] >= loc) buffer[i] = '\0';                                  
    }                                                                          
    if ((fp = fopen(buffer, "rb")) != NULL)                                    
    {                                                                          
       printf("\n opened file!!!");                                            
       fclose(fp1);                                                            
    }                                                                          
    else printf("\nDID NOT OPEN!!"); exit(0);                                  
   if (buffer[0] = '\0' ) break;                                                
                                                                               
    puts(buffer);                                                              
                                                                               
   }                                                                            
                                                                               
}  
0
 
LVL 8

Expert Comment

by:stochastic
ID: 2689744
llagreca,

Just edited your code. I have not tested it myself, but I think it should work. Please tell me if there is still a problem.

(Sorry if the formatting is messed up. I just copy-pasted; I don't know why formatting gets disturbed)

- stochastic

#include <stdio.h>
#include <string.h>

#define MAXLEN 128
/*  opens filelist.txt which is a list of the file names in a specific          
    dir and prints out each one  */                                              
                                                                                 
                                                                                 
main()                                                                          
{ FILE *fp, *fp1; char buffer[128];                                            

  if ((fp = fopen("filelist.txt", "r")) == NULL) printf("\n no open");          
  while(1)                                                                      
  {                                                                              
    fgets(buffer, MAXLEN, fp);                                                  
    if (buffer == NULL) break;  /* exit when no more lines to read */
    buffer[strlen(buffer)-1] = '\0';
    printf("\nfileName is =%s=", buffer1);                                        
                                                                                 
    if ((fp1 = fopen(buffer, "rb")) != NULL)                                      
    {                                                                            
       printf("\n opened file!!!");                                              
       fclose(fp1);                                                              
    }                                                                            
    else printf("\nDID NOT OPEN!!"); exit(0);                                    
    puts(buffer);
                                                                                 
   }                                                                            
                                                                                 
}  
0
 
LVL 8

Expert Comment

by:stochastic
ID: 2689813
Corrected the code and tested it!

- stochastic

#include <stdio.h>
#include <string.h>
#include <stdlib.h> /* you may not need this line on a Sun machine */

#define MAXLEN 128
/*  opens filelist.txt which is a list of the file names in a specific  
    dir and prints out each one  */  
 
 
main()
{ FILE *fp, *fp1; char buffer[128];

  if ((fp = fopen("filelist.txt", "r")) == NULL)
  {
 printf("\n no open");
 exit(0);
  }
  while(1)  
  {    
    if (fgets(buffer, MAXLEN, fp) == NULL) break;
  /* exit when no more lines to read */
    buffer[strlen(buffer)-1] = '\0';
    printf("\nfileName is =%s=", buffer);  
 
    if ((fp1 = fopen(buffer, "rb")) != NULL)    
    {  
       printf("\n opened file!!!");  
       fclose(fp1);  
    }  
    else printf("\nDID NOT OPEN!!"); /* exit(0); you can enable this later */
    puts(buffer);
 
   }  
 
}  
0
 

Author Comment

by:llagreca
ID: 2689864
thank you, it works great. now though, i have problems reading in the data in the file. If i call the file individually, it works fine, but if I use this method, it doesn't work correctly.
Thanks
0
 
LVL 8

Accepted Solution

by:
stochastic earned 100 total points
ID: 2689910
I think in your earlier code, there was a possible confusion in the file pointers fp and fp1. Maybe that's the reason?

I feel confident you will now be able to figure out things.

best of luck

 -stochastic
0
 

Expert Comment

by:P_Mahesh
ID: 2692092
The problem in llagreca's previous code was that, even though he had
defined 2 file pointers 'fp' and 'fp1' but he was opened both the files
usinf 'fp' ..

 if ((fp = fopen(buffer, "rb")) != NULL)                                      
                       
He should have used 'fp1' instead of 'fp' in the above line.

- mahesh
         
0

Featured Post

Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

An Outlet in Cocoa is a persistent reference to a GUI control; it connects a property (a variable) to a control.  For example, it is common to create an Outlet for the text field GUI control and change the text that appears in this field via that Ou…
This tutorial is posted by Aaron Wojnowski, administrator at SDKExpert.net.  To view more iPhone tutorials, visit www.sdkexpert.net. This is a very simple tutorial on finding the user's current location easily. In this tutorial, you will learn ho…
The goal of this video is to provide viewers with basic examples to understand how to use strings and some functions related to them in the C programming language.
The goal of this video is to provide viewers with basic examples to understand opening and reading files in the C programming language.

623 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question