# Appended an extension to filename, but now can't use with fstream,I really need help

## Recommended Posts

ChaosCommand    122
Basicailly, I want a user to enter a file name, and then append an extension to the end of it.
#include <iostream>
#include <string>
#include <Shlwapi.h>
#include <fstream>

void database_editor_new()
{

// Other code taken out to save space

string fname;
const char *fnameExt = ".txt";
string fnameComplete;

cout << "Enter a file name: ";

cin >> fname;

// Appends .txt to the end
fnameComplete = fname.append(fnameExt);

fstream database;

// Problem is, is that the compiler complains when i try to use this
// as a filename
database.open(fnameComplete, ios::in|ios::out);
// Error generated

// I/O Stuff
database.close();

}

//The Error:
Error	1	error C2664: 'void std::basic_fstream<_Elem,_Traits>::open(const wchar_t *,
std::ios_base::openmode,int)' :
cannot convert parameter 1 from 'std::string' to 'const wchar_t *'
f:\documents and settings\james mowery\my documents\visual studio
2005\projects\tennis sim\tennis sim\database_editor.cpp	40


So I have three questions. 1. How do I convert the string fnameComplete to a char, and possibly get it working. 2. Is there an easier way to append a file extension to the end of a string, or an array of chars, and have it work with fstream, because this is annoying and holding me up for working on my database editor. lastly 3. My small tennis simulation game/engine is being worked on, and I need to write a database to tie it all together, I have the database planned out (for player attributes, name, and such), but I need to figure out a way to easily read the data and write out statistical data (have not planned that yet). I'm doing this in the command line, so I'm only going to be playing the game out with commentary (if any of you have played Championship Manager, or Football Manager as it is today, you'll know what I mean). So does anyone have any resources for managing databases for games, and reading and writing to them? After this, I hope to move over to an API and do it, maybe one day put together a 2D engine, and so on. Hopefully work my way up to a real football game engine.

##### Share on other sites
Telastyn    3777
fnameComplete.c_str()

##### Share on other sites
ChaosCommand    122
Quote:
 Original post by TelastynfnameComplete.c_str()

That didn't really help... care to explain.

I tried putting it right after I assigned fnameComplete to the whole name, but I still got an error.

Error 1 error C2664: 'void std::basic_fstream<_Elem,_Traits>::open(const wchar_t *,std::ios_base::openmode,int)' : cannot convert parameter 1 from 'std::string' to 'const wchar_t *' f:\documents and settings\james mowery\my documents\visual studio 2005\projects\tennis sim\tennis sim\database_editor.cpp 40

I think it is the same one

##### Share on other sites
Roboguy    794
I would try:
std::string fname;std::cout << "Enter a file name: ";std::cin >> fname;fname += ".txt";

##### Share on other sites
ChaosCommand    122
Quote:
 Original post by RoboguyI would try:std::string fname;std::cout << "Enter a file name: ";std::cin >> fname;fname += ".txt";

Tried that, deleted all and built it around that.

again:
Error 1 error C2664: 'void std::basic_fstream<_Elem,_Traits>::open(const wchar_t *,std::ios_base::openmode,int)' : cannot convert parameter 1 from 'std::string' to 'const wchar_t *' f:\documents and settings\james mowery\my documents\visual studio 2005\projects\tennis sim\tennis sim\database_editor.cpp 42

database.open() is wanting something that it isn't getting, and the suggestions aren't changing it to what it wants. I'd tell you what it was, but I just don't understand MSDN.

##### Share on other sites
ChaosCommand    122
MSDN States:
basic_filebuf *open(   const char *_Filename,   ios_base::openmode _Mode);

Parameters
_Filename
The name of the file to open.

_Mode
One of the enumerations in ios_base::openmode.

__________________________________________________________

So,
It wants a const char *_Filename.

So how do I make the filename into that, anyone know?

##### Share on other sites
cozman    583
if something wants a const char* and you have a string you can use string::c_str()

for example
void foo(const char* text);string str = "something";foo(str); //error!foo(str.c_str()); //much better :)

##### Share on other sites
Telastyn    3777
At least for the thin-character version [char, not wchar] calling string.c_str() returns the internal char * version of the text. The error is just saying that fstream.open takes a char *, not a std::string.

Thus:

database.open(fnameComplete.c_str(),...

should pass the internal const wchar_t * representation of the text as parameter one, which is what the function wants.

##### Share on other sites
ChaosCommand    122
Quote:
 Original post by cozmanif something wants a const char* and you have a string you can use string::c_str()for examplevoid foo(const char* text);string str = "something";foo(str); //error!foo(str.c_str()); //much better :)

You completely lost me with that. Happen to know how I would get that to work with my code? I am sure it is simple, but, my attempts have failed.

##### Share on other sites
ChaosCommand    122
Quote:
 Original post by TelastynAt least for the thin-character version [char, not wchar] calling string.c_str() returns the internal char * version of the text. The error is just saying that fstream.open takes a char *, not a std::string.Thus:database.open(fnameComplete.c_str(),...should pass the internal const wchar_t * representation of the text as parameter one, which is what the function wants.

I'll try that right now

##### Share on other sites
Roboguy    794
std::fstream::open takes a const char* as an argument. You need to convert the std::string to const char* with it's (std::strings) c_str() function.

##### Share on other sites
ChaosCommand    122
Quote:
 Original post by TelastynAt least for the thin-character version [char, not wchar] calling string.c_str() returns the internal char * version of the text. The error is just saying that fstream.open takes a char *, not a std::string.Thus:database.open(fnameComplete.c_str(),...should pass the internal const wchar_t * representation of the text as parameter one, which is what the function wants.

It didn't give me an error, but the file wasn't created either. I don't understand why.

##### Share on other sites
Telastyn    3777
Quote:
Original post by ChaosCommand
Quote:
 Original post by TelastynAt least for the thin-character version [char, not wchar] calling string.c_str() returns the internal char * version of the text. The error is just saying that fstream.open takes a char *, not a std::string.Thus:database.open(fnameComplete.c_str(),...should pass the internal const wchar_t * representation of the text as parameter one, which is what the function wants.

It didn't give me an error, but the file wasn't created either. I don't understand why.

You might want to print the string [to make sure it was made correctly], and look around. If you're not using explicit paths, the 'current working directory' might not be what you think it is, especially if run from an IDE.

##### Share on other sites
ChaosCommand    122
Quote:
Original post by Telastyn
Quote:
Original post by ChaosCommand
Quote:
 Original post by TelastynAt least for the thin-character version [char, not wchar] calling string.c_str() returns the internal char * version of the text. The error is just saying that fstream.open takes a char *, not a std::string.Thus:database.open(fnameComplete.c_str(),...should pass the internal const wchar_t * representation of the text as parameter one, which is what the function wants.

It didn't give me an error, but the file wasn't created either. I don't understand why.

You might want to print the string [to make sure it was made correctly], and look around. If you're not using explicit paths, the 'current working directory' might not be what you think it is, especially if run from an IDE.

Everything works fine, it just simply doesn't create the file

I tried another example and instead used ofstream, and it worked, but fstream didn't work.

Why is that?

##### Share on other sites
ChaosCommand    122
Can someone put this in there compiler, and tell me if it works. Everything for me compiles fine, but it just isn't creating the file.

I don't know if it is VS screwing up, or if it is something I'm doing wrong.

#include <iostream>#include <string>#include <fstream>#include <Shlwapi.h>using namespace std;int main(){	string str;	string fname;	const char *fnameExt = ".txt";	string fnameComplete;	cout << "Enter a file name: ";	cin >> fname;	// Extension added	fnameComplete = fname.append(fnameExt);	cout << fname << endl;	fstream database1;	database1.open(fnameComplete.c_str(), ios::in|ios::out);	cout << endl;	database1.close();	return 0;}

##### Share on other sites
ChaosCommand    122
And how would I specify a directory to save the file, like the directory the program is running from, or a specific directory?

##### Share on other sites
ChaosCommand    122
Is there a bug in fstream

Because I seriously cannot create a file without using ofstream or ifstream...
Or is it supposed to be that way, or is my version of VS screwed up, I really need to know, this is the most annoying problem I have ever had and my patience is running out.

##### Share on other sites
Telastyn    3777
remove the ios::in. I don't remember the details, but some flags don't like other flags...

This works for me:
#include <fstream>#include <iostream>#include <string>using namespace std;int main(){	string fn="moocow";	string ext=".moo";	string filename=fn+ext;	cout << fn << " + " << ext << " == " << filename << "\n";	fstream	f;	f.open(filename.c_str(),iostream::out);	f.close();}

##### Share on other sites
Agony    3452
Quote:
 From MSDN:· ios_base::in becomes "r" (open existing file for reading).· ios_base::out or ios_base::out | ios_base::trunc becomes "w" (truncate existing file or create for writing).· ios_base::out | app becomes "a" (open existing file for appending all writes).· ios_base::in | ios_base::out becomes "r+" (open existing file for reading and writing).· ios_base::in | ios_base::out | ios_base::trunc becomes "w+" (truncate existing file or create for reading and writing).· ios_base::in | ios_base::out | ios_base::app becomes "a+" (open existing file for reading and for appending all writes).

Note that it says "open existing file for reading and writing". So it will fail if the file doesn't already exist. You'll need to use a different mode for opening, or check to see if the file exists before hand, and create it if it doesn't.

//Open the file as input-onlydatabase.open(fnameComplete.c_str(), ios::in);if (!database.is_open()){  //if it doesn't already exist, open it in output-only  //to force it to be created  database.open(fnameComplete.c_str(), ios::out);}//Close it so that we can open it in read/write modedatabase.close();//Open it in read/write modedatabase.open(fnameComplete.c_str(), ios::in|ios::out);

##### Share on other sites
ChaosCommand    122
Quote:
Original post by Agony
Quote:
 From MSDN:· ios_base::in becomes "r" (open existing file for reading).· ios_base::out or ios_base::out | ios_base::trunc becomes "w" (truncate existing file or create for writing).· ios_base::out | app becomes "a" (open existing file for appending all writes).· ios_base::in | ios_base::out becomes "r+" (open existing file for reading and writing).· ios_base::in | ios_base::out | ios_base::trunc becomes "w+" (truncate existing file or create for reading and writing).· ios_base::in | ios_base::out | ios_base::app becomes "a+" (open existing file for reading and for appending all writes).

Note that it says "open existing file for reading and writing". So it will fail if the file doesn't already exist. You'll need to use a different mode for opening, or check to see if the file exists before hand, and create it if it doesn't.

*** Source Snippet Removed ***

Nice, that worked, seems kinda strange that it just doesn't create it with both flags, but, at least it works now. Now I can finally start working on this thing and hopefully make progress.

Thanks for all the help.