1

To create multiple files using a for loop in c++.

Objective:- To create multiple files in the respective folder named as 1.txt, 2.txt,3.txt

Here is my sample code:

int co = 3;
for (int i = 1; i <= co; i++)
{   
    ofstream file;
    file.open (i+".txt");
    file.close();
}

This code creates three files: t, xt and txt.

What is happening in this code? and what is wrong with my code?

Alok
  • 49
  • 2
  • 8
  • You have to convert i in string before. – Alexandre Lavoie Dec 05 '16 at 11:08
  • Try to convert your i variable to String. – Prometheus Dec 05 '16 at 11:09
  • The idiom `i+".txt"` works as if `".txt"` is an *array* and so you get an offset to the `i`th character of that string. Hence the `txt` (offset 1), `xt` (offset 2), and `t` (offset 3). – Jongware Dec 05 '16 at 11:12
  • Dupe is answering the questions from the body of your question. For a working alternative see the answers below, https://stackoverflow.com/questions/64782/how-do-you-append-an-int-to-a-string-in-c or many more easily found by searching the web. – Baum mit Augen Dec 05 '16 at 11:13
  • Thanks, one more question why it created file named t, xt and txt – Alok Dec 05 '16 at 11:14
  • @Alok I already googled that for you, all you need to do now is read the duplicate. – Baum mit Augen Dec 05 '16 at 11:16
  • @Alok Because `".txt"` is a (temporary) **pointer** to a chunk of memory filled with chars `.txt`. And int + pointer "moves" that pointer, i.e. `0 + ".txt" == ".txt"`, `1 + ".txt" == "txt"`, `2 + ".txt" == "xt"` and so on. – freakish Dec 05 '16 at 11:16
  • @freakish It's an array, not a pointer. It decays to a pointer when used with `+`. – Baum mit Augen Dec 05 '16 at 11:17
  • @BaummitAugen array and pointer is pretty much the same thing. – freakish Dec 05 '16 at 11:18
  • @freakish That's very much not true, as the never ending stream of questions about passing/returning arrays to/from functions, *"Why can't I convert `int[][]` to `int**`?"* etc. proves. Statements like yours are needlessly misleading, especially for beginners. – Baum mit Augen Dec 05 '16 at 11:21
  • @BaummitAugen Dude, `T[X][Y]` is just a syntactic sugar for `T[X*Y]` or a pointer to a chunk of memory of size `sizeof(T)*X*Y`. I know that arrays and pointers are different types in C/C++ with different syntax and that arrays have sweet opeartors making your life easier, but under the hood their the same thing. Inability to understand that doesn't mean they are different things. I'm not misleading anyone. I've never said that double arrays are double pointers, which is false. – freakish Dec 05 '16 at 11:26
  • @freakish I know what an array is and you know what an array is. Most beginners only have a vague idea about that stuff though, and being imprecise about the difference between arrays and pointers only gives them wrong expectations. Again, that's not just a theoretical problem, see the questions from beginners getting it wrong. – Baum mit Augen Dec 05 '16 at 11:33
  • Thanks everyone :-) – Alok Dec 05 '16 at 13:16

3 Answers3

1

You need to convert i to a string in order to concatenate it using operator+, otherwise you will inadvertently execute pointer arithmetic:

// C++11
#include <fstream>
#include <string>     // to use std::string, std::to_string() and "+" operator acting on strings 

int co = 3;
for (int i = 1; i <= co; i++)
{   
    ofstream file;
    file.open (std::to_string(i) + ".txt");
    file.close();
}

If you do not have access to C++11 (or if you want to avoid explicitly "converting i and then concatenating"), you can use std::ostringstream:

// C++03
#include <fstream>
#include <sstream>

std::ostringstream oss;
int co = 3;
for (int i = 1; i <= co; i++)
{   
    ofstream file;

    oss << i << ".txt"; // `i` is automatically converted
    file.open (oss.str()); 
    oss.str(""); // clear `oss`

    file.close();
}

Note: clang++ catches this mistake with the -Wstring-plus-int warning flag (wandbox example).

F14
  • 67
  • 2
  • 6
Vittorio Romeo
  • 90,666
  • 33
  • 258
  • 416
  • You are wrong. First of all `".txt"` is not `std::string`. Secondly `int + char*` is perfectly well defined: it moves pointer. That's why OP gets pieces of `.txt` filename in each iteration. – freakish Dec 05 '16 at 11:12
  • @freakish: thanks, fixed. I'm too used to the `"..."s` literal, I guess :( – Vittorio Romeo Dec 05 '16 at 11:14
  • Also in case of clang++ it seems that `-Wstring-plus-int` always shows this warning, no matter what `i` is. At least that's what I've observed, not sure though. – freakish Dec 05 '16 at 11:22
  • @freakish: yes, but only if the integer value is not known at compile-time. I will change the note regardless - my comment could have been misleading. – Vittorio Romeo Dec 05 '16 at 11:32
1

In C++ you can't simply "concatenate" a string literal with an integer. A string literal will decompose into a pointer to constant char (char const *) and pointer arithmetic rules apply.

When adding or subtracting an integer value from a pointer, the result is a pointer to an object that's the number of elements further in memory - and of course this only holds if the boundaries of that memory are not crossed.

datenwolf
  • 159,371
  • 13
  • 185
  • 298
0

You have to convert i to std::string first:

int co = 3;
for (int i = 1; i <= co; i++){   
    ofstream file;
    file.open (std::to_string(i) + ".txt"); //Here
    file.close();
}
Humam Helfawi
  • 19,566
  • 15
  • 85
  • 160