Solved

Opening files without specifing file names

Posted on 2000-04-03
22
166 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
  • 6
  • 6
  • 4
  • +3
22 Comments
 
LVL 2

Expert Comment

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

Expert Comment

by:cookre
Comment Utility
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
Comment Utility
In MSVC 6, one uses _findfirst and _findnext.
0
 

Author Comment

by:llagreca
Comment Utility
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
Comment Utility
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
Comment Utility
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
Comment Utility
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
Comment Utility
/*
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
Comment Utility
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
Comment Utility
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
Comment Utility
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
Free Trending Threat Insights Every Day

Enhance your security with threat intelligence from the web. Get trending threat insights on hackers, exploits, and suspicious IP addresses delivered to your inbox with our free Cyber Daily.

 

Author Comment

by:llagreca
Comment Utility
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
Comment Utility
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
Comment Utility
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
Comment Utility
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
Comment Utility
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
Comment Utility
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
Comment Utility
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
Comment Utility
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
Comment Utility
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
Comment Utility
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
Comment Utility
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

Enabling OSINT in Activity Based Intelligence

Activity based intelligence (ABI) requires access to all available sources of data. Recorded Future allows analysts to observe structured data on the open, deep, and dark web.

Join & Write a Comment

Suggested Solutions

Title # Comments Views Activity
memory mapped I/O query 6 136
How to Deploy a Windows C++ Application With Libraries 9 135
Finding a good hash function 4 115
Problem to save 10 120
Have you thought about creating an iPhone application (app), but didn't even know where to get started? Here's how: ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ Important pre-programming comments: I’ve never tri…
Preface I don't like visual development tools that are supposed to write a program for me. Even if it is Xcode and I can use Interface Builder. Yes, it is a perfect tool and has helped me a lot, mainly, in the beginning, when my programs were small…
The goal of this video is to provide viewers with basic examples to understand and use structures in the C programming language.
The goal of this video is to provide viewers with basic examples to understand opening and writing to files in the C programming language.

763 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

Need Help in Real-Time?

Connect with top rated Experts

9 Experts available now in Live!

Get 1:1 Help Now