passing ofstream reference

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;
}

You are correctly passing the outstream by reference.
Perhaps there is an error in the logic.
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.
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
i edited it actually there was a folder name after f:\\
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
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.
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;
}

still not showing files of first folder
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
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;
}
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.
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);
}
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.
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);
}
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
Topic archived. No new replies allowed.