fstream

I want to store files by naming them from file 1.dat.
Everything is fine but when I restart the program, it stores file naming from
file 1.dat again but I wants to store it from next numbers
For example if previous file was named 3 then it will store from 4 not from 1
again as the data will lose from previous file as it will overwrite that file.

I have tried a lot of methods. Tried several hours figuring it out by applying bool and loops and if statements but failed.

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
#include <iostream>
#include <string>
#include <fstream>
using namespace std;

int i;
string name, pin_code, cnic, file_name;

void getData();

int main()
{
	int n;
	cout << "How many accounts do you want to create? ";
	cin >> n;
	cin.ignore();

	for (i = 1; i <= n; i++)
	{
		getData();

		ofstream data;
		data.open(file_name = "file " + to_string(i) + ".dat", ios::out | ios::trunc);
		data << name << endl << pin_code << endl << cnic;
		data.close();
	}

	return 0;
}

void getData()
{
	cout << "Enter details of person # " << i << ": " << endl;
	cout << "Enter your name: ";
	getline(cin, name);
	cout << "Enter your pin code: ";
	getline(cin, pin_code);
	cout << "Enter your cnic number: ";
	getline(cin, cnic);
}
Last edited on
Scan the directory of interest to determine the names of files which are already present.
We can use the standard filesystem library to do this. https://en.cppreference.com/w/cpp/filesystem

For example:

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
#include <iostream>
#include <fstream>
#include <string>
#include <filesystem>
#include <regex>

namespace fs = std::filesystem ;

// return the largest file number nnn of the files named 'file nnn.dat' in the directory
int get_last_file_number( const fs::path dir = fs::current_path() )
{
    int last_file_num = 0 ;

    // for each entry in the directory
    for( const auto& entry : fs::directory_iterator(dir) )
    {
        // get the file name component of the path
        const std::string file_name = entry.path().filename().string() ;

        static const std::regex file_name_re( "file (\\d+)\\.dat" ) ;
        std::smatch match ;
        // if the file name is of the expected form 'file nnn.dat'
        if( std::regex_match( file_name, match, file_name_re ) )
        {
            // extract the number as an integer
            const int file_num = std::stoi( match[1] ) ;

            // update last_file_num if it is a larger integer
            if( file_num > last_file_num ) last_file_num = file_num ;
        }
    }

    return last_file_num ;
}

int next_file_number( const fs::path dir = fs::current_path() )
{
    return get_last_file_number(dir) + 1 ;
}

int main()
{
    std::cout << "how many files? " ;
    int n ;
    std::cin >> n ;

    // the next file number starts at fn
    const int fn = next_file_number() ;

    for( int i = 0 ; i < n ; ++i )
    {
        // the file number of this file is fn+i
        const std::string fname = "file " + std::to_string(fn+i) + ".dat" ;
        std::cout << "creating file '" << fname << "'\n" ;
        std::ofstream(fname) << i << " (" << fn+i << "). this is just an example\n" ;
    }
}



Without iterating the file system, a potentially 'easier' method is to store the last file number in a separate file (say file0.dat).
Thanks!
Topic archived. No new replies allowed.