passing ofstream reference

Dec 13, 2016 at 1:53pm
i am trying to write a program that finds files in a folder recursively but i am not sure how to pass ofstream reference when i am running my program it runs successfully but when i open the file its empty ca someone please tell me where i am wrong.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
#include <iostream>
#include<fstream>
#include <dirent.h>
#include<string.h>
#include<cstdlib>
#include <sys/stat.h>

using namespace std;

    void browse(string addr,ofstream& outstream){
        DIR *dir;
        dirent *ent;
        struct stat buf;
        const char* caddr=addr.c_str();

        if ((dir = opendir (caddr)) != NULL){
            while ((ent = readdir (dir)) != NULL) {
                if((strcmp(ent->d_name,"..")==0)||(strcmp(ent->d_name,".")==0)){}
                else{
                    stat(ent->d_name,&buf);
                    if(S_ISREG(buf.st_mode)){outstream<<ent->d_name<<"\"\n";}
                    else if(S_ISDIR(buf.st_mode)){browse(addr+"\\"+ent->d_name,outstream);}
                    }

            }
        }
        else {cout<<"cannot open directory";}
        closedir (dir);
    }

int main()
{
  
    string addr="F:\\";
    ofstream outstream;
    outstream.open("c:\\files.txt",ios::app);
    browse(addr,outstream);
    outstream.close();
    return 0;
}

Dec 13, 2016 at 2:04pm
You are correctly passing the outstream by reference.
Perhaps there is an error in the logic.
Dec 13, 2016 at 2:27pm
but when i open the file its empty

Which file is empty?

Are you sure there are any regular files in the root of drive "F:"? Your program only appears to list the directories in the directory provided, it doesn't navigate to any other sub directories.
Dec 13, 2016 at 2:32pm
browse(addr+"\\"+ent->d_name,outstream
string addr (in main() ) already has the trailing double backslash, do you need another pair after this?
Last edited on Dec 13, 2016 at 2:32pm
Dec 13, 2016 at 3:28pm
i edited it actually there was a folder name after f:\\
Dec 13, 2016 at 3:34pm
i solved above problem i was passing just file address with stat, i replaced it with absolute address by adding addr to ent->d_name and it worked but now i am having another problem files present in the first child folder are not written in output file rest all files of other folder are being written i don't know what is happening
Dec 13, 2016 at 3:36pm
i put a cout before outstream even that cout is showing files of first folder but on opening output file, files of first folder are not present.
Dec 13, 2016 at 3:42pm
corrected code:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
#include <iostream>
#include<fstream>
#include <dirent.h>
#include<string.h>
#include<cstdlib>
#include <sys/stat.h>

using namespace std;

    void browse(string addr,ofstream& outstream){
        DIR *dir;
        dirent *ent;
        struct stat buf;
        outstream.open("C:\\files.txt",ios::app);
        const char* caddr=addr.c_str();
        cout<<caddr<<"\n\n\n";

        if ((dir = opendir (caddr)) != NULL){
            while ((ent = readdir (dir)) != NULL) {

                if((strcmp(ent->d_name,"..")==0)||(strcmp(ent->d_name,".")==0)){}
                else{
                    string pathname=addr+"\\"+ent->d_name;

                    const char* cfname=pathname.c_str();
                    
                    stat(cfname,&buf);

                    if(S_ISREG(buf.st_mode)){


                            outstream<<ent->d_name<<"\"\n";
                            cout<<ent->d_name<<"\"\n";
                    }
                    else if(S_ISDIR(buf.st_mode)){
                            //cout<<ent->d_name;
                            browse(addr+"\\"+ent->d_name,outstream);
                    }
                    }

            }
        }
        else {cout<<"cannot open directory";}
        outstream.close();
        closedir (dir);
    }
int main()
{


    /*DIR *dir;
    dirent *ent;*/
    string addr="F:\\Introduction";
    ofstream outstream;

    browse(addr,outstream);

    return 0;
}

Dec 13, 2016 at 3:42pm
still not showing files of first folder
Dec 13, 2016 at 4:26pm
Change the name associated with the ofstream object to a non-existing file instead of files.txt and see if that works. Also try and put in state flag checks throughout browse() and see if it generates any messages
Dec 13, 2016 at 5:59pm
I opened ofstream inside browse function and it worked but it is not a good practice i guess, now ofstream is opened and closed every time browse function is called

Working Code


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
#include <iostream>
#include<fstream>
#include <dirent.h>
#include<string.h>
#include<cstdlib>
#include <sys/stat.h>

using namespace std;

    void browse(string addr){
        DIR *dir;
        dirent *ent;
        struct stat buf;
        ofstream outstream1;
        outstream1.open("C:\\Users\\sk9294\\Desktop\\wierd.txt",ios::app);
        const char* caddr=addr.c_str();
        cout<<"\n\n"<<caddr<<"\n\n\n";

        if ((dir = opendir (caddr)) != NULL){
            while ((ent = readdir (dir)) != NULL) {

                if((strcmp(ent->d_name,"..")==0)||(strcmp(ent->d_name,".")==0)){}
                else{
                    string pathname=addr+"\\"+ent->d_name;

                    const char* cfname=pathname.c_str();

                    stat(cfname,&buf);

                    if(S_ISREG(buf.st_mode)){


                            outstream1<<ent->d_name<<"\n";
                            cout<<ent->d_name<<"\n";
                    }
                    else if(S_ISDIR(buf.st_mode)){
                          
                            browse(addr+"\\"+ent->d_name);
                    }
                    }

            }
        }
        else {cout<<"cannot open directory";}
        outstream1.close();
        closedir (dir);
    }
int main()
{


    
    string addr="F:\\Introduction";
   

    browse(addr);

    return 0;
}
Dec 13, 2016 at 6:02pm
I have never passed ofstream as reference before, can anybody help me change this code to pass ofstream reference from main, so that ofstream is opened and closed only once during program run.
Dec 13, 2016 at 6:13pm
I have never passed ofstream as reference before, can anybody help me change this code to pass ofstream reference from main, so that ofstream is opened and closed only once during program run.

The very first post in this thread is an example, at least with regard to the ofstream.
1
2
3
4
5
6
7
8
9
10
11
12
13
#include <iostream>
#include <fstream>

void browse(std::ofstream& outstream)
{
    outstream << "some text\n";
}

int main()
{
    std::ofstream outstream("c:\\files.txt");
    browse(outstream);
}
Dec 14, 2016 at 4:06am
yes but that very first program is giving weird output, it is not including all files in the directory. I ran that code for a directory having lots of folder and sub folders in it, although the cout listed all files but when i opened output file it had only one file name in it then i thought there must be some problem with the ofstream reference so i moved ofstream inside browse function and it started listing all files in the output file too.
Dec 14, 2016 at 5:37am
Here, took the latest "Working Code" from this thread, reinstated the ofstream reference
(and some small mostly cosmetic adjustments)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
#include <iostream>
#include <fstream>
#include <dirent.h>
#include <cstring>
#include <string>
#include <cstdlib>
#include <sys/stat.h>

void browse(std::string addr, std::ofstream & outstream1)
{
    DIR *dir;
    dirent *ent;
    struct stat buf;

    std::cout << "\n\n" << addr << "\n\n\n";

    if ( (dir = opendir (addr.c_str())) )
    {
        while ( (ent = readdir (dir)) ) 
        {
            if ( strcmp(ent->d_name, "..") && strcmp(ent->d_name, ".")  )
            {
                std::string pathname = addr + "\\" + ent->d_name;

                stat(pathname.c_str(), &buf);

                if (S_ISREG(buf.st_mode))
                {
                    outstream1 << ent->d_name << "\n";
                    std::cout  << ent->d_name << "\n";
                }
                else if (S_ISDIR(buf.st_mode))
                {
                    browse(pathname.c_str(), outstream1);
                }
            }
        }
        
        closedir (dir);
    }
    else
    {
        std::cout << "cannot open directory";
    }
}

int main()
{
    std::string addr = "F:\\Introduction";
        
    std::ofstream fout("C:\\Users\\sk9294\\Desktop\\wierd.txt");
   
    browse(addr, fout);
}
Dec 14, 2016 at 7:00am
A slight variation. Essentially the same code as before, but with two changes.
1. defer the processing of subdirectory until after ordinary files
2. allow capture of console output to another file.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
#include <iostream>
#include <fstream>
#include <dirent.h>
#include <cstring>
#include <string>
#include <cstdlib>
#include <sys/stat.h>
#include <vector>

std::string title(const std::string & text, size_t  width = 80)
{
    std::string result = ' ' + text + ' ';
    while (result.size() < width)
    {
        result = '-' + result;
        if (result.size() < width)
            result += '-';
    }
    return result;
    
}
void browse(std::string addr, std::ofstream & outstream1, std::ostream& logout=std::cout)
{
    DIR *dir;
    dirent *ent;
    struct stat buf;

    logout << "\n" << title(addr) << "\n\n";

    if ( (dir = opendir (addr.c_str())) )
    {
        std::vector<std::string> subdir;
        
        while ( (ent = readdir (dir)) ) 
        {    
            if ( strcmp(ent->d_name, "..") && strcmp(ent->d_name, ".")  )
            {
                std::string pathname = addr + "\\" + ent->d_name;
                stat(pathname.c_str(), &buf);

                if (S_ISREG(buf.st_mode))
                {
                    outstream1 << ent->d_name << "\n";
                    logout     << ent->d_name << "\n";
                }
                else if (S_ISDIR(buf.st_mode))
                {
                    subdir.push_back(pathname);
                    //browse(pathname.c_str(), outstream1, logout);
                }
            }
        }
        
        for (const std::string & p : subdir)
        {
            browse(p.c_str(), outstream1, logout);
        }
        
        closedir (dir);
    }
    else
    {
        logout << "cannot open directory";
    }
}

int main()
{
    std::string addr = "F:\\Introduction";
        
    std::ofstream fout("output.txt");
   
    // browse(addr, fout);  // default output to console
    
    std::ofstream log("logout.txt");
    browse(addr, fout, log);
    
}


change last few lines to get console output:
73
74
75
76
    browse(addr, fout);  // default output to console
    
    // std::ofstream log("logout.txt");
    // browse(addr, fout, log); 
Last edited on Dec 14, 2016 at 7:57am
Topic archived. No new replies allowed.