Hi,

I am working on a program, it asks user for a file name and opens that file with that name, do some calculations and create a new file with the filename.output (.output is the extension) and save the contents into it. I have been working on it for a while. But while I did able to figured out the part where it ask the user for the file name and open that new..., I can't figure out how to actually add the extension. (I am new to programming...)

Because the file name will not be a know size, I am not sure where could I start adding the .output to the file name. I understand char fileName is just an array of char, but I don't know where to start adding...

ifstream infile ;
char fileName[20] ;
cout << "Enter the file name: " << endl ;
cin >> fileName ;
infile.open( fileName ) ;
// ofstream of(FileName.output, ios::out)

for exampe, the user entered "word.txt", I would like the output to be word.txt.output. But I am not know how long the name would be in advance, all I know is it will be 1-15 characters long. The last line doesn't work, because the file name isn't like the string i used to work with, I can't just do fileName + ".output".What could I do in this situation? Thanks in advance for all helps.

My thoughts: Could it be possible for me to read the file name as a string, and add the extension ".output" to the string, and then convert it back to an array of chars? I really think there are easier ways to do this... I feel I am making this more complicated than it really should be. I am not sure... (for open the file, I need it to be char, so I am doing this thing twice at least).

Edited 6 Years Ago by Darkmist: too in the title is miss-spelled... I meant to type to.

Could it be possible for me to read the file name as a string, and add the extension ".output" to the string, and then convert it back to an array of chars?

I'm glad you mentioned this. String class objects are very versitle and can handle virtually any input the user might throw at you.

If we look at the open() function from <fstream>, we see that it has a const char* (cstring) parameter as it's first argument.. which is the file name in a cstring:

fstream::open

public member function

void open ( const char * filename, ios_base::openmode mode = ios_base::in | ios_base::out );

But we are using a string.. what are we supposed to do? Luckily, there is a <string> class member function called c_str() which returns a cstring pointer:

const char* c_str ( ) const;

Get C string equivalent
Generates a null-terminated sequence of characters (c-string) with the same content as the string object and returns it as a pointer to an array of characters.

A terminating null character is automatically appended.

Knowing all this, we can take all user input in the form of a string, concantinate the string with the required file identifier (.txt) and pass the string into the open() function by calling the c_str() member:

#include<string>

string name;

cout << "Enter file name: ";
cin >> name;

//Check to see if user already appended the file type
if(name.find(".txt") == string::npos)
{
    //If user did not add file type, we can add it here: 
    name += ".txt";
}

infile.open(name.c_str());

Learn more about string class member functions here.

Edited 6 Years Ago by Clinton Portis: Slap your troubles away with SlapChop.

Comments
The example on c_str() was really clear and easy to understand

Thanks , I think I got it to running correctly now. Because to be honest, I was trying to write a function that will convert it from a string to a array of char. I think the method using (c_str()) is really a lot better, plus I think I am messing my program up on the way while I was trying to set this up. This function is really helpful, I actually come across this in my search, but I didn't see good examples that I could understand, and your example code and explanation is really good and clear. Thanks a lot!

Moreover, the biggest adv by using this method is I don't have to care will the char array I created is large enough for the string fileName I am going to run it though. (the limit still exist, but i don't have to actually worry about it as much). I was going to create something like...

if (fileName.length() < 30)
{
   openFileName = convertString( fileName ) ; 
   // convertString is a function I was writting while I was researching
   // because a stupid way is better than not working......
}
else
{
   // Tell the user the file name is too big, try again
}

I think the details on how the c_str() work is interesting too. But I am not 100% sure how it works just yet. I will go do more research on this function from the string class. At least I got my program to work now, hehe. I will go finish reading that page about c_str(). The line

Generates a null-terminated sequence of characters (c-string) with the same content as the string object and returns it as a pointer to an array of characters.

I need some more time to read it over... I don't quite get it understand by reading it. But thanks a lot for answering my question, you are really helpful and kind. Thanks a lot.

Edited 6 Years Ago by Darkmist: n/a

I am impressed by your response. Everyone should take note of how you formed your original quesiton, implemented the solution, and how you explained your working knowlege of the solution.

You mentioned you tried to create your own 'string to cstring' function... although we both no that this is no longer necessary with the c_str() member, just for fun, I'll show you how I would have implemented it:

//String to Cstring
char* str_to_cstr(string& str, char* cstr)
{
     #include<cstring>

     int size = 0;
     char* temp = '\0';

     //Check cstring buffer to see if we have enough space available 
     if(strlen(cstr) < str.size())
     {
          //Resize the buffer to match string size
          temp = cstr;
          try{cstr = new char[str.size()+1];}
          catch(bad_alloc){return NULL;}       
          cstr = temp;
          delete temp;
     }

     //Now we can safely copy string to cstring
     strcpy(cstr, str.c_str());

     return cstr;
}

I need some more time to read it over... I don't quite get it understand by reading it. But thanks a lot for answering my question

To break it down really simple, the c_str() member allows the string object to be used as a cstring; therefore, giving it access to all <cstring> library functions.

So anytime you have a function (like open()) that accepts a char* (cstring or "or character array") you can still get all the benefits of using your string object, and still have the ability to pass it into these functions as a cstring... because c_str() returns a char* to a character array located as a private member of the string class.

Edited 6 Years Ago by Clinton Portis: Yarrr.

This question has already been answered. Start a new discussion instead.