need a way to dynamically write files with sequentially incremented names

ok, first, my apologies for the long title, short decriptions were always one of my weak points. it took some trimming to get the title short enough to work.

in any case, at this time, the I think the issue I am having is with the following line of code:

 
ofstream img_pg_writer("pg_name");


this line of code is intended to create a file that has the name stored in the string "pg_name". I am using a string because this is inside a loop, and each time the loop runs, the string is different. to be exact, i am attempting to write a web page gallery, with each image shown in a separate page, and each page is nearly the same as the rest, with only the hyperlinks to the previous and next pages being incremented, thanks to the itoa function. but i am getting off topic.

to get back to the question, I am unsure how to get the program to use the value stored in the string, as opposed to using the name of the string itself.

at least, I think that's what its doing, my compiler finds no errors, but whenever I try to run the program, it always crashes at that line of code printed above.

anyone got a suggestion?
I think that would be useful if you post a bit more of your code
With ofstream img_pg_writer("pg_name"); the file named "pg_name" will be created. Do not quote pa_name if you want to pass the variable.

Though, i don't see any reason for the compiler to crash at those string of code.
I think that would be useful if you post a bit more of your code


Bazzy? you asked for it, so here it is, i hope that this doesn't turn out too long to make sense.

Though, i don't see any reason for the compiler to crash at those string of code.


melkiy? i took another try at setting up system("pause"); es throughout my code, and, i found the code crashing in a spot it wasn't before. the line in question thats crashing me this time is as follows:

itoa(pg_num, pg_label, 10);

ok, the pg_num is a variable that holds the int value of the page number to be written. and, the pg_label is a char variable that takes the char version of that int. also, that "10" is to set the value at base ten, or at an int. oh, and yeah, i got the code from the page on this website for itoa. i wasn't sure what else to use, if i still wanted to keep the code from getting too complex.

to be clear, what connects this code, with the code from my first post, is the following code:

pg_name = pg_name_left + pg_label + imgpg_name_right;

the pg_name_left is a string that holds the text "pg_".

the imgpg_right is a string that holds the text ".html".

so, if you plug it all together, with a page number of, for example, 05 (i prefer to use two digit numbers to keep my files sorted, haven't needed a third digit yet), then pg_name should turn out to be "pg_05.html". after the file is written, the pg_num gets incremented by 1, and the loop that writes the file starts again, and writes the next file, assuming that the number of pages to be written has not yet been reached.
Last edited on
What's the exact type of your pg_label, pg_name_left, imgpg_name_right?
ok, sorry about the double post, but i figured my previous post was long enough already. i just thought i should mention, that taking the quotes out of

ofstream img_pg_writer("pg_name");

only, shall we say, made my compiler unhappy. error message is as follows:

no matching function for call to `std::basic_ofstream<char, std::char_traits<char> >::basic_ofstream(std::string&)'

candidates are: std::basic_ofstream<char, std::char_traits<char> >::basic_ofstream(const std::basic_ofstream<char, std::char_traits<char> >&)

std::basic_ofstream<_CharT, _Traits>::basic_ofstream(const char*, std::_Ios_Openmode) [with _CharT = char, _Traits = std::char_traits<char>]

std::basic_ofstream<_CharT, _Traits>::basic_ofstream() [with _CharT = char, _Traits = std::char_traits<char>]

ok, i am really unhappy with how those error messages turned out looking after being copied and pasted from my compiler, but as i can't seem to figure out how to improve them further, that will have to do
Last edited on
figured this might be better off in a new reply than not, so, i moved the following text here, and edited it as needed.

ok, melkiy? they are all strings, or at least, that's what i had in mind when i wrote them. in hindsight, the pg_label didn't turn out as planned (i ended up trying to wing it using a char instead), i guess that's the problem? and if so, what do you recommend for a solution?

[edit]
i may have found the solution i have been seeking, but it is a lot more complex than i was trying to go for.

the method i have in mind, by the way, is to split the two digits of the current page number int, then i am using itoa to make them into char characters sepreately. then, i will group them back into a single string.

here's to hoping this works!


[/edit]
Last edited on
Then write
ofstream img_pg_writer(pg_name.c_str());
since there is no ofstream constructor that expects the string type.
It's because you need to call the .c_str() of the string class. This basically returns the string as a char*, since fstreams want a char* for the file name. And also, I don't think you can use + to add strings and char* together, I suggest changing the char* back to a string and fixing whatever errors you might get there, since std::string is much easier to deal with then char* is.
@firedraco
You can + a string and a char*, but not back to front:
1
2
3
4
string a;
string b("abc");
a = b + "def"; //all right, because there is string::operator+(char*)
a = "def" + b; //error 
1
2
3
4
string a;
string b("abc");
a = b + "def"; //all right, because there is string::operator+(char*)
a = "def" + b; //error  
//

The solution is in your answer :- You can if you turn the first char* into a string:

a = string("def") + b;

so if you have a chain of char* your want to join:
string a = "abd" + "defg" + "hijklm" + "xyz" // can't do this
but you can do this:
string a = string("abd") + "defg" + "hijklm" + "xyz" // ok




itoa(pg_num, pg_label, 10);
if pg_label is a string, this won't work, it should be a char* or a char[]
Last edited on
i hadn't gotten an email saying anyone replied to my post, so i hadn't been checking back. so, i was writing code based on incomplete idea a friend of mine had, and this is what i came up with:

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
int pg_num, num_of_pg, pg_counter = 0, pg_num_one, pg_num_two;
char *pg_label_one, *pg_label_two, *pg_label_array[3];
    
string imgpg_name_right=".html", 
          pg_name_left="pg_",
          pg_name, 
          pg_label;

cout << "input the number of the newest page in the gallery in two digit format\n"
    << endl << "the first page made once this program does its work"<< endl;

cin >> pg_num;

cout << endl << "input the number of pages to be added to the gallery"<< endl;

cin >> num_of_pg;

do{
     
     pg_num_one = pg_num / 10;
     
     pg_num_two = pg_num % 10;
     
     itoa(pg_num_one, pg_label_one, 10);
     
     itoa(pg_num_two, pg_label_two, 10);
     
     pg_label_array[0] = pg_label_one;
     
     pg_label_array[1] = pg_label_two;
     
     pg_label = pg_label_array;
     
     pg_name = pg_name_left + pg_label + imgpg_name_right;
     
     // here is where the content of the file is written
     // i am skipping this part to save space in this post
     
     img_pg_writer.close();
     
     pg_counter++;
     pg_num++;
}while(num_of_pg < pg_counter);


what i am trying to do is split the two digits of the pg_num variable up into two ints, then convert them to two chars, then insert them into the pg_label string. thing is, it doesn't like this way (page 28) of assigning two chars to a string. i have tried a number of other ways, but, none of them seem to work. the last one i tried gave the following error for line 32:

invalid conversion from `char**' to `char'

initializing argument 1 of `std::basic_string<_CharT, _Traits, _Alloc>& std::basic_string<_CharT, _Traits, _Alloc>::operator=(_CharT) [with _CharT = char, _Traits = std::char_traits<char>, _Alloc = std::allocator<char>]'
Last edited on
ok, i figured out that if i change line 32 so that the pg_label_array is *pg_label_array, IE mark it as a pointer, that line now works. but, problems sure keep seeming to pop up the more i swat them down. here is the updated 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
int main () {
    int pg_num, num_of_pg, pg_counter = 0, pg_num_one, pg_num_two;
    char *pg_label_one, *pg_label_two, *pg_label_array[3];
    
     string imgpg_name_right=".html", 
            pg_name_left="pg_",
            pg_name, 
            pg_label;
    
     cout << endl;
     cout << endl;
	
    cout << "input the number of the newest page in the gallery in two digit format\n"
         << endl << "the first page made once this program does its work"<< endl;

     cin >> pg_num;

     cout << endl << "input the number of pages to be added to the gallery"<< endl;

     cin >> num_of_pg;


    
     do{
          pg_num_one = pg_num / 10;
          
          pg_num_two = pg_num % 10;
          
          itoa(pg_num_one, pg_label_one, 10);
          
          itoa(pg_num_two, pg_label_two, 10);
         
          pg_label_array[0] = pg_label_one;
          
          pg_label_array[1] = pg_label_two;
          
          pg_label = *pg_label_array;
          
          //pg_label = pg_label_one + pg_label_two;
          
          pg_name = pg_name_left + pg_label + imgpg_name_right;
          
          ofstream img_pg_writer(pg_name);
          
          pg_name = pg_name_left + pg_label + imgpg_name_right;
          
          // here is where the content of the file is written
          // i am skipping this part to save space in this post
          
          img_pg_writer.close();
          
          pg_counter++;
          pg_num++;
     }while(num_of_pg < pg_counter);
     
     return 0;
}


i changed what was in the previous post was line 32, and in this one is line 37, to mark the array as a pointer. now, the error it is giving is as follows:

no matching function for call to `std::basic_ofstream<char, std::char_traits<char> >::basic_ofstream(std::string&)'

candidates are:

std::basic_ofstream<char, std::char_traits<char> >::basic_ofstream(const std::basic_ofstream<char, std::char_traits<char> >&)

std::basic_ofstream<_CharT, _Traits>::basic_ofstream(const char*, std::_Ios_Openmode) [with _CharT = char, _Traits = std::char_traits<char>]

std::basic_ofstream<_CharT, _Traits>::basic_ofstream() [with _CharT = char, _Traits = std::char_traits<char>]

now, what i need to know is, what should i change to make the ofstream write a file whos name is stored in the contents of string (in this case the string would be "pg_name").
I believe the constructor wants a char*...use pg_name.c_str().
The trouble with Template based classes is that when you make a mistake, the compiler emits a lot of what appears to be gibberish especially when the parameters they take are also templates themselves.

So by way of explanation:
We have the error:
no matching function for call to `std::basic_ofstream<char, std::char_traits<char> >::basic_ofstream(std::string&)'

The stuff in angle brackets <> just gives the template declaration parameters - which we will ignore:
So we have no matching function for call to `std::basic_ofstream::basic_ofstream(std::string&)'

We recognise std as the standard namespace.

What is left is: no matching function for call to `basic_ofstream::basic_ofstream(string&)'


As you can see, this is a constructor (classname and function name is the same).

So the compiler is saying:
It cannot find a constructor for ofstream that takes a string reference as a parameter

For example:
1
2
string astring("guestgulkan.txt");
ofstream outFile(astring); //wrong - No ofstream constructor takes a string type 


The compiler then gives you some alternatives. If you go through these the same way as we did earlier you will get:

basic_ofstream::basic_ofstream(const char*, Ios_Openmode) //char*, mode

and

basic_ofstream::basic_ofstream()//default constructor


So if you have a string type and you want to get a char* from it, then you do as firedraco says in the post above.
Last edited on
ok, i have the basic version of the program working, but, i can't seem to get the blasted thing working in a format that has a .cpp file for function calls (named WebgallerywriterMain.cpp), a .cpp file for the bodies of the functions (named Webgallerywriter.cpp), and a .h file for classes, function prototypes, and so on and so forth (named Webgallerywriter.h).

the error it is currently giving me is short, at least:

`user_input' undeclared (first use this function)

(Each undeclared identifier is reported only once for each function it appears in.)

[Build Error] [WebgallerywriterMain.o] Error 1




user input is a function whos prototype is in the file Webgallerywriter.h, and both the file WebgallerywriterMain.cpp and the file Webgallerywriter.cpp are linked to the .h file in the very first line, via the following code:

#include "Webgallerywriter.h"

i am betting you guys are going to need more info to be able to assist me, but, we are all probably better off without me trying to guess all the possible things that info could be.

so, does anyone have a clear idea of what else i need to tell you guys?
Last edited on
ok, i found a glitch with the basic (single .cpp file) version of the program, but i was able to fix it. i am still having the same issue with the version of the program that is split into different files (again, its split into a .h file, a .cpp file for the bodies of the functions, and a .cpp file for function calls).

here is the code for the working single-file version of the document:

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
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
#include <cstdio>
#include <stdio.h>
#include <iostream>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
#include <string>
#include <cstring>
#include <fstream>
#include <sstream>

using namespace std;

int main () {

    int  pg_num, num_of_pg, pg_counter = 1, pg_num_minus, pg_num_plus;
    // pg_num is the number of the current page being made
    //
    // num_of_pg is the number of the number of pages being added to the gallery
    //
    // pg_counter is an int variable used to keep track of how many pages have been made, and 
    // is also used to stop the loop when the right amount of pages have been made
    //
    // pg_num_minus is an int variable used to set up the string pg_label_minus to
    // hold one integer less than the current page's number value
    //
    // pg_num_plus is an int variable used to set up the string pg_label_plus to
    // hold one integer more than the current page's number value

    string pg_name = ("page_00.html"),
           strg,
           pg_label,
           pg_labeled,
           pg_label_minus,
           pg_label_plus,
           pg_labeled_minus,
           pg_labeled_plus;
    // pg_name is a string that holds a template for the page names
    //
    // strg is a string that holds the name of the current page being made
    //
    // pg_label is a string that takes in the int value of the current page being made
    //
    // pg_labeled is a string that takes in the value of the pg_label, but
    // it does it with either the "=" or the "+=" methods,  depending on
    // if the value of pg_num is less than 10 or not
    //
    // pg_label_minus is a string that takes in either the value of pg_num_minus, or,
    // if the current page being written is to be the first page in the gallery,
    // it takes in the value of the last page to be written, so that the gallery
    // loops to the last page in the gallery when you click the "previous page"
    // link from the first page in the gallery.
    //
    // pg_label_plus is a string that takes in either the value of pg_num_plus, or,
    // if the current page being written is to be the last page in the gallery,
    // it takes in the value of the first page in the gallery, meaning the page number 01 
    //
    // pg_labeled_minus is a string that is the final version of the string that holds 
    // one int less than the page number; this is also used to take into account the
    // possiblility that the number of pages could be less than 10,
    // and if so, then it takes in a zero into the tens digit place 
    //
    // pg_labeled_plus is a string that is the final version of the string that holds 
    // one int more than the page number

    cout << endl << endl;

    cout << "input the number of the newest page in the gallery in two digit format\n"
         << "the first page made once this program does its work" << endl << endl;

    cin >> pg_num;

    cout << endl << "input the number of pages to be added to the gallery" << endl << endl;

    cin >> num_of_pg;

    cout << endl << endl;

    do
    {
         pg_labeled = ("0"),
         pg_labeled_minus = ("0"),
         pg_labeled_plus = ("0");

         stringstream ss;

         ss << pg_num;

         ss >> pg_label;

         string strg = pg_name;

         if(pg_num < 10)
         {
              pg_labeled += pg_label;
         }
         else
         {
              pg_labeled = pg_label;
         }

         strg.replace(5, 2, pg_labeled);

         pg_num_minus = pg_num;

         pg_num_plus = pg_num;

         stringstream gg;

         gg << pg_num_minus - 1;

         gg >> pg_label_minus;

         stringstream nn;

         nn << pg_num_plus + 1;

         nn >> pg_label_plus;

         if (pg_num == 01)
         {
              string pg_link_last, pg_link_final, pg_link_final_tens = ("0");

              stringstream ff;

              ff << num_of_pg;

              ff >> pg_link_last;

              pg_link_final = pg_link_last;

              if (num_of_pg%10 == 0)
              {
                    strg.replace(0, 1, pg_link_final_tens);
              }
              pg_labeled_minus = pg_link_final;

              pg_labeled_plus += pg_label_plus;
         }
         else if(pg_num == num_of_pg)
         {
              string pg_one = ("01");

              pg_labeled_plus = pg_one;

              pg_labeled_minus = pg_label_minus;
         }
         else if(pg_num < 9)
         {
              pg_labeled_minus += pg_label_minus;

              pg_labeled_plus += pg_label_plus;
         }
         else if (pg_num == 9 || pg_num == 10)
         {
              pg_labeled_minus += pg_label_minus;

              pg_labeled_plus = pg_label_plus;
         }
         else
         {
              pg_labeled_minus = pg_label_minus;

              pg_labeled_plus = pg_label_plus;
         }
         
         ofstream img_pg_writer;

    	 img_pg_writer.open (strg.c_str());

         img_pg_writer << "<html>" << endl;
         img_pg_writer << "<head>" << endl;
         img_pg_writer << "<title> page "<< pg_label << " </title>" << endl;
	     img_pg_writer << "<link rel=\"stylesheet\" type=\"text/css\"";
         img_pg_writer << " href=\"gallery.css\" />" << endl;
	     img_pg_writer << "</head>" << endl;
    	 img_pg_writer << "<body>" << endl;
	     img_pg_writer << endl;
         img_pg_writer << "<a align=\"left\" href=\"page_" << pg_labeled_minus <<; 
         img_pg_writer << ".html\"> previous picture </a>..." << endl;
         img_pg_writer << endl;
         img_pg_writer << "<a align=\"left\" href=\"index.html\"> ";
         img_pg_writer << "index page </a>" << endl;
         img_pg_writer << endl;
         img_pg_writer << "<a align=\"center\" href=\"page_" << pg_labeled_plus <<;
         img_pg_writer << ".html\"><img src=\"image_" << pg_labeled <<;
         img_pg_writer << ".jpg\" alt=\"image_" << pg_labeled <<;
         img_pg_writer << ".jpg\"></a>" << endl;
         img_pg_writer << endl;
         img_pg_writer << "<a align=\"right\" href=\"index.html\"> index page";
         img_pg_writer << " </a>..." << endl;
         img_pg_writer << endl;
         img_pg_writer << "<a align=\"right\" href=\"page_" << pg_labeled_plus <<;
         img_pg_writer << ".html\"> next picture </a>" << endl;
         img_pg_writer << endl;
         img_pg_writer << "</body>" << endl;
         img_pg_writer << "</html>";

		 img_pg_writer.close();

         pg_label.clear();
         pg_labeled.clear();
         pg_labeled_minus.clear();
         pg_labeled_plus.clear();

         pg_counter++;
         ss << ++pg_num;
         ss >> pg_label;
    }while(num_of_pg >= pg_counter);

    system("pause");

    return 0;
}


i have been working on this code so long, i forgot exactly how some of it works, but i think the explanations i gave in the comments in the code should explain it well enough.

and, sorry about the rediculaslly long post, i just thought that now that the basic version of the program seems to be working, i should post it all.

that way, you guys have a far better chance of spotting any glitches i missed, and you also will have an easier time advising me on how to get this program to work in the 3- file format i have been trying to get working.

P.S.

i still need to post more info on some of the variables, but i am out of time at the moment, so, i will edit the info into the post later. sorry about this.
Topic archived. No new replies allowed.