21

I wish to read all the text files in a particular folder. The files' names do not have any common pattern in them- else the task would have been easier.

//read a file from the directory  
//Perform a common operation  
//write output to a common file  
//read the next file

It will be good if I could work around with sub-folders as well, but even the basic implementation is sufficient.

I tried looking at the previously asked related questions (here, here, here and here), but none of them give a C and Linux specific answer which I need.

edit : So, this is what I wrote based on the answers received-

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <dirent.h>
#include <unistd.h>
#include <errno.h>


int main(int argc, char **argv)
{
    DIR* FD;
    struct dirent* in_file;
    FILE    *output_file;
    FILE    *entry_file;
    char    buffer[BUFSIZ];

    /* Opening common file for writing */
    output_file = fopen("/home/pnp/snort_rules_folder/rulesoutput.txt", "a+");
    if (output_file == NULL)
    {
        fprintf(stderr, "Error : Failed to open output_file\n");

        return 1;
    }

    /* Scanning the in directory */
    if (NULL == (FD = opendir ("/home/pnp/snort_rules_folder/rules"))) 
    {
        fprintf(stderr, "Error : Failed to open input directory\n");
        fclose(output_file);

        return 1;
    }
    while ((in_file = readdir(FD))) 
    {
        /* On linux/Unix we don't want current and parent directories
         * If you're on Windows machine remove this two lines
         */
        if (!strcmp (in_file->d_name, "."))
            continue;
        if (!strcmp (in_file->d_name, ".."))    
            continue;
        /* Open directory entry file for common operation */
        /* TODO : change permissions to meet your need! */
        entry_file = fopen(in_file->d_name, "r");
        if (entry_file == NULL)
        {
            fprintf(stderr, "Error : Failed to open entry file\n");
            fclose(output_file);

            return 1;
        }

        /* Doing some stuff with entry_file : */

        while (fgets(buffer, BUFSIZ, entry_file) != NULL)
        {
            /* Use fprintf or fwrite to write some stuff into common_file*/
        }

    fprintf(output_file, "reading file %s", in_file->d_name);

        /* When you finish with the file, close it */
        fclose(entry_file);
    }

    /* Don't forget to close common file before leaving */
    fclose(output_file);

    return 0;
     }

And the error received-
pnp@pnp-laptop:~/snort_rules_folder$ ./a.out
Error : Failed to open entry file

Community
  • 1
  • 1
pnp
  • 554
  • 3
  • 6
  • 21
  • possible duplicate of [c: return all the filenames in directory](http://stackoverflow.com/questions/7927948/c-return-all-the-filenames-in-directory) – Greg Hewgill Jul 31 '12 at 08:33
  • 3
    I think your inability to locate a duplicate stems from the use of the word "folder" instead of the more common "directory" (at least on the Linux platform). – Greg Hewgill Jul 31 '12 at 08:34
  • 2
    could you just use `find -type f -exec your_program {} + >output.file`? – jfs Jul 31 '12 at 09:06
  • @GregHewgill um...doesnt this question that you mention talk about 'filenames'... I am talking about reading the files... – pnp Jul 31 '12 at 09:07
  • Well, once you have the filenames then it's pretty straightforward to open the files and read them. (Or is that what your question was about?) – Greg Hewgill Jul 31 '12 at 09:20
  • @pnp I am getting exactly the same error. Were you able to solve it? – Ketan Maheshwari Aug 12 '15 at 03:59
  • @Ketan the accepted answer (and the comments) had worked for me. But this way too long ago, and I can't recall much about it... – pnp Aug 12 '15 at 12:15

1 Answers1

20

You can use this sample code and modify it if you need:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <dirent.h>
#include <unistd.h>
#include <errno.h>

/* This is just a sample code, modify it to meet your need */
int main(int argc, char **argv)
{
    DIR* FD;
    struct dirent* in_file;
    FILE    *common_file;
    FILE    *entry_file;
    char    buffer[BUFSIZ];

    /* Openiing common file for writing */
    common_file = fopen(path_to_your_common_file, "w");
    if (common_file == NULL)
    {
        fprintf(stderr, "Error : Failed to open common_file - %s\n", strerror(errno));

        return 1;
    }

    /* Scanning the in directory */
    if (NULL == (FD = opendir (in_dir))) 
    {
        fprintf(stderr, "Error : Failed to open input directory - %s\n", strerror(errno));
        fclose(common_file);

        return 1;
    }
    while ((in_file = readdir(FD))) 
    {
        /* On linux/Unix we don't want current and parent directories
         * On windows machine too, thanks Greg Hewgill
         */
        if (!strcmp (in_file->d_name, "."))
            continue;
        if (!strcmp (in_file->d_name, ".."))    
            continue;
        /* Open directory entry file for common operation */
        /* TODO : change permissions to meet your need! */
        entry_file = fopen(in_file->d_name, "rw");
        if (entry_file == NULL)
        {
            fprintf(stderr, "Error : Failed to open entry file - %s\n", strerror(errno));
            fclose(common_file);

            return 1;
        }

        /* Doing some struf with entry_file : */
        /* For example use fgets */
        while (fgets(buffer, BUFSIZ, entry_file) != NULL)
        {
            /* Use fprintf or fwrite to write some stuff into common_file*/
        }

        /* When you finish with the file, close it */
        fclose(entry_file);
    }

    /* Don't forget to close common file before leaving */
    fclose(common_file);

    return 0;
}

Hope this hellp.

Regards.

TOC
  • 4,326
  • 18
  • 21
  • Thanks. If you don't mind some more help, here's my code after modification- http://pastebin.com/4jFTHY6Z, with the error I receive written at the end. – pnp Jul 31 '12 at 12:49
  • @pnp : You can edit your post and post your code here, and get more help. – TOC Jul 31 '12 at 12:56
  • @pnp,pl. check if you are running the code from the same directory, where your files are. It may be that fopen is not getting the full path of the file, if you are running the code from some other directory. Also you may add an error reporting library function like perror instead of your error handling.This will give you what exactly is the error. Now if your directory, which you are reading contains other directories(and not files) do you want fopen to be applied on these too?? Seems no.So you need to add a check for continuing the loop, in case you get a directory.(stat function can help) – Tanmoy Bandyopadhyay Jul 31 '12 at 18:03
  • As @Tanmoy said, provide the complete path to your file, to be sure, also, add errno to your errors to see what's going on, i will edit my code to add that. – TOC Jul 31 '12 at 18:07
  • @TOC Thanks TOC for adding the errno reporting. Also would request you if you can add the code to stat the filename and if that is a directory, continue the loop. This should make the answer better. – Tanmoy Bandyopadhyay Jul 31 '12 at 18:17
  • Windows also has the `.` and `..` directory entries, and you would also want to skip them for the same reason as on Linux. – Greg Hewgill Jul 31 '12 at 20:40
  • @GregHewgill :), Thanks. I'm a Linux user this what i put this line. – TOC Jul 31 '12 at 20:45