Convert int to const char * ( for a file name )

Hello , i found a lot about how to convert int to const char * but non of them explain correctly or sometimes dont even work.

Here is my 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
#include <stdio.h>
#include <cstdlib>

using namespace std;

int main ()
{
int i =0;
char c1 =0;
char c2 =0;
int wrong =0;

long rFile1Size;
long rFile2Size;

FILE * pFile;
FILE * rFile1;
FILE * rFile2;
rFile1 = fopen ("myfile.bin","rb");
rFile2 = fopen ("myfile2.bin","rb");

if (rFile1!=NULL && rFile2!=NULL)
  {
      // get size
  fseek (rFile1 , 0 , SEEK_END);
  rFile1Size = ftell (rFile1);
  rewind (rFile1);
  fseek (rFile2 , 0 , SEEK_END);
  rFile2Size = ftell (rFile2);
  rewind (rFile2);

// compare
  while(i<rFile1Size){
    fseek ( rFile1 , i , SEEK_SET );
    fseek ( rFile2 , i , SEEK_SET );
    c1 = fgetc (rFile1);
    c2 = fgetc (rFile2);
    if (c1!=c2){
    pFile = fopen (i,"ab"); // error here cannot convert int to const char*
    if (pFile!=NULL)
    {
      fputs (c2,pFile);// cannot convert char to const char* 
      fclose (pFile);
    }
    wrong++;i++;}else{i++;}
}

printf("%d",wrong);


    fclose (rFile1);
    fclose (rFile2);
  }

  system("PAUSE");
  return 0;
}
C++ inherits a lot of things from C language, including its standard library.

However, as a C++ programmer you should move away from the C subset, because the alternatives offered by C++ are usually superior.

In your case, why are you using C style I/O instead of C++ streams?
http://www.cplusplus.com/doc/tutorial/files/

And why do you want to use const char * instead of std::string?

Also, if your compiler is new enough (to support the C++11 standard of 2011) you could use std::to_string() to convert an int to std::string.

http://www.cplusplus.com/reference/string/to_string/

Otherwise, if your compiler only supports C++98 you could use string streams to do the same thing.

Thank you for your reply, i add this code:

1
2
#include <string>
#include <sstream> 


1
2
3
4
string Result;
stringstream convert;
convert << i;
Result = convert.str();


in between 38 and 39 line of my code but i get this error:

error: cannot convert 'std::string {aka std::basic_string<char>}' to 'const char*' for argument '1' to 'FILE* fopen(const char*, const char*)'|

Btw im using CodeBlocks
To get the underlying array of char* for a string, call its c_str() member, like this:
1
2
3
4
5
6
std::string Result;
std::ostringstream convert;
convert << i;
Result = convert.str();

fopen(Result.c_str(), "rb");


However, rather than using fopen, you should instead be using the fstream library provided by C++ (as @Catfish suggested).

EDIT: Also, because I fell like it, you can cut out "Result" entirely for that example:
1
2
3
std::ostringstream convert;
convert << i;
fopen(convert.str().c_str(), "rb");
Last edited on
You are very close; the problem is that std::string cannot be converted to const char *.

Fortunately, you can use the std::string::c_str() member function to get the equivalent C string.

http://www.cplusplus.com/reference/string/string/c_str/

pFile = fopen (Result.c_str(), "ab");
First , thank you all for your help i used convert.str().c_str()
Second , my code looks like this now:

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
#include <stdio.h>
#include <cstdlib>
#include <sstream>

using namespace std;

int main ()
{
int i =0;
char c1 =0;
char c2 =0;
int wrong =0;

long rFile1Size;
long rFile2Size;

FILE * pFile;
FILE * rFile1;
FILE * rFile2;
rFile1 = fopen ("myfile.bin","rb");
rFile2 = fopen ("myfile2.bin","rb");

if (rFile1!=NULL && rFile2!=NULL)
  {
      // get size
  fseek (rFile1 , 0 , SEEK_END);
  rFile1Size = ftell (rFile1);
  rewind (rFile1);
  fseek (rFile2 , 0 , SEEK_END);
  rFile2Size = ftell (rFile2);
  rewind (rFile2);

// compare
  while(i<rFile1Size){
    fseek ( rFile1 , i , SEEK_SET );
    fseek ( rFile2 , i , SEEK_SET );
    c1 = fgetc (rFile1);
    c2 = fgetc (rFile2);
    if (c1!=c2){

stringstream convert;
convert << i;
stringstream convert2;
convert2 << c2;
    
    pFile = fopen (convert.str().c_str(),"ab");
    if (pFile!=NULL)
    {
      fputs (convert2.str().c_str(),pFile);
      fclose (pFile);
    }
    wrong++;i++;}else{i++;}
}
//printf("%d",wrong);
    fclose (rFile1);
    fclose (rFile2);
  }
  system("PAUSE");
  return 0;
}






Last edited on
Second , my code looks like this now:

Please be clear about what you need help with.

If you want to refine your code, here are some ideas:
1) use C++ file streams
2) don't use the using namespace std; directive
3) don't use system("PAUSE");

Explanations and links:

1) http://www.cplusplus.com/doc/tutorial/files/

When in C++, do as C++ programmers do. The main reason for favoring the C++ features which seem to merely duplicate those inherited from C, is that in general they will work together better with new, C++-only features that C never had.

2) http://www.parashift.com/c++-faq/using-namespace-std.html

using namespace std; is bad practice, especially if you do it in header files. Effectively you remove the namespace, in this case the std namespace.

The alternative is omitting the using directive and qualifying the names appropriately:

1
2
3
4
5
6
7
8
9
#include <iostream>
#include <string>

int main()
{
    std::string message("Hello, World!");

    std::cout << message << std::endl;
}


3) A decent enough IDE for Windows, such as Visual Studio C++ or even Orwell Dev-C++ is smart enough to keep the console window open for you, without you polluting your own program with a pause. Otherwise, if you use command line tools, why aren't you starting your program in a Command Prompt in the first place?
Last edited on
Thank you, but i dot need any more help, my program is finished.
Last edited on
Sorry to hijack your thread here OP but serious question: Why is it you all ran straight to stringstreams and none of you suggested just using "snprintf()" or even "sprintf()" for older compilers? Wouldn't that have been the more obvious solution?
This is a C++ forum. You're really asking why people are recommending C++ solutions, rather than (inferior) C solutions? Seriously?
Last edited on
Inferior by what standard exactly? Using string streams turns out code that is aesthetically terrible. Then you have to screw around with the buffer when you want to reuse the variable. It doesn't even insert a null terminator at the end of the string when you use the insertion operator! std::strings are the only data type they are meant to work with and they all end with a null but with this you have to tell it to be a string AND to return a C-String with the "c_str()" member function to even use it anywhere. So please, quantify the inferiority of "snprintf()" when compared to this boon-dongle of an object type.
Last edited on
snprintf doesn't provide type safety. std::stringstream also provides the options to use user-defined classes as input/output through overloading stream operators. And what do you mean that it doesn't insert a null terminator? It returns a std::string, and the c_str() method of std::string will append a null-terminator if the string doesn't have one, and is safe for input and output streams as is anyway.
Did it suddenly become more difficult to overload a function then it is to overload an operator? Also no, an std::stringstream is not an std::string, that is why you have to use the ".str()" member function before you call "c_str()" before passing it to something like "fopen()" (which I do agree here by the way, OP should not be using this).
The problem with type safety is that it becomes impossible to use snprintf in templated program, as you don't know in advance what the types are going to be. This would force template specialization for all the types that may be used, unless streams were used. Also, I meant to say that the 'str()' member function returns a std::string, I just jumped ahead in my mind...

Anyway, often, you don't need to use c_str() to do everything. For example, using std::fstream for file, fstream takes as a constructor an object of a string, which is perfectly adequate. Also, the stl algorithms can be performed on a string easily, whereas with the const char* obtained from snprintf the size has to be found to correctly iterate over the elements.

EDIT: Also, I don't think that snprintf supports wide strings (whereas you can always use std::wostringstream or the like).
Last edited on
I just noticed that every difference will be saved in a different file even if difference occurred right next to previous.

i know that i have to put this code in 45 line of my code:
if ( condition ){convert << (i-1);}

But what the condition should be?
I just cant figure out.
Just found out how to deal with this problem, so proud of myself now :D

So now if difference occurred right next to previous it will be saved in the same file.

Here is my 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
62
63
64
65
66
67
68
69
70
71
72
73
#include <stdio.h>
#include <cstdlib>
#include <sstream>

using namespace std;

int main ()
{
int i =0;
char c1 =0;
char c2 =0;
char preveusc1 =0;
char preveusc2 =0;

int wrong =0;

long rFile1Size;
long rFile2Size;

FILE * pFile;
FILE * rFile1;
FILE * rFile2;
rFile1 = fopen ("myfile.bin","rb");
rFile2 = fopen ("myfile2.bin","rb");

if (rFile1!=NULL && rFile2!=NULL){
      // get size
  fseek (rFile1 , 0 , SEEK_END);
  rFile1Size = ftell (rFile1);
  rewind (rFile1);
  fseek (rFile2 , 0 , SEEK_END);
  rFile2Size = ftell (rFile2);
  rewind (rFile2);

// compare
  while(i<rFile1Size){
    fseek ( rFile1 , i , SEEK_SET );
    fseek ( rFile2 , i , SEEK_SET );
    c1 = fgetc (rFile1);
    c2 = fgetc (rFile2);

    if (wrong>0){
            fseek ( rFile1 , (i-1) , SEEK_SET );
            preveusc1 = fgetc(rFile1);
            fseek ( rFile1 , (i+1) , SEEK_SET );
            fseek ( rFile2 , (i-1) , SEEK_SET );
            preveusc2 = fgetc(rFile2);
            fseek ( rFile2 , (i+1) , SEEK_SET );
            }

    if (c1!=c2){

stringstream convert;
stringstream convert2;
convert2 << c2;

    if (wrong>0 && preveusc1!=preveusc2){convert << (i-1);}else{convert << i;}

    pFile = fopen (convert.str().c_str(),"ab");

    if (pFile!=NULL){
      fputs (convert2.str().c_str(),pFile);
      fclose (pFile);
    }
    wrong++;i++;}else{i++;}
}
//printf("%d",wrong);
    fclose (rFile1);
    fclose (rFile2);
  }
  system("PAUSE");
  return 0;
}
Topic archived. No new replies allowed.