Opening a file with std::string - c++

This should be a fairly trivial problem. I'm trying to open an ofstream using a std::string (or std::wstring) and having problems getting this to work without a messy conversion.
std::string path = ".../file.txt";
ofstream output;
output.open(path);
Ideally I don't want to have to convert this by hand or involve c-style char pointers if there's a nicer way of doing this?

In the path string, use two dots instead of three.
Also you may use 'c_str()' method on string to get the underlying C string.
output.open(path.c_str());

this should work:
output.open(path.c_str())

I'm afraid it's simply not possible. You have to use c_str, and yes, it sucks.
Incidentally, using char* also means fstream has no support for Unicode file names... a shame.

Related

How does using a variable for file paths work?

ifstream inFile;
inFile.open("C:/FilePathThatWorks");
The above seems to work in C++. But if I try and take a String, or CString, or anything else, and plug it in for inFile.open(ExampleString), it fails at compile time (error at the bottom of this question). The question is not about my code, but how to make C++ accept a variable for inFile.
If it only ever accepts char* variables, then is there perhaps a method that takes input from the user in the form of a char* with the null terminator and everything.
error: no matching function for call to 'std::basic_ifstream<char>::open(std::__cxx11::string&)'
The method open in fstream does not accept std::string. You need to pass a char*.
So just call c_str() on string.
ifstream requires a char* param for the filename. see http://www.cplusplus.com/reference/fstream/ifstream/ifstream/
most string classes have some way to convert to this kind of string (e.g. c_str())
If you want to use CString:
CString path = "c:\\FilePathThatWorks";
ifstream inFile;
inFile.open(static_cast<const char*>(path));
The cast is not needed here.
CString can represent two different strings depending on the project settings. If it is a string of char the code should compile, if the character type is wchar_t compiling should fail.

Are the methods in the <cstring> applicable for string class too?

I've tried out using memcpy() method to strings but was getting a "no matching function call" although it works perfectly when I use an array of char[].
Can someone explain why?
www.cplusplus.com/reference/cstring/memcpy/
std::string is an object, not a contiguous array of bytes (which is what memcpy expects). std::string is not char*; std::string contains char* (somewhere really deep).
Although you can pull out the std::string inner byte array by using &str[0] (see note), I strongly encourage you not to. Almost anything you need to do already is implemented as a std::string method. Including appending, subtracting, transforming and anything that makes sense with a text object.
So yes, you can do something as stupid as:
std::string str (100,0);
memcpy(&str[0],"hello world", 11);
but you shouldn't.
Even if you do need memcpy behaviuor, try to use std::copy instead.
Note: this is often done with C functions that expects some buffer, while the developer wants to maintain a RAII style in his code. So he or she produces std::string object but passes it as C string. But if you do clean C++ code you don't need to.
Because there's no matching function call. You're trying to use C library functions with C++ types.

What should I use instead of std::ostrstream?

I like to use std::ostrstream to format text but not print it to stdout but instead write it into an std::string (by accessing the std::ostrstream::str() member). Apparently this is deprecated now. So, how am I supposed to write formatted objects to a string, with the same convenience as when writing to a stream?
You could use std::ostringstream. Similarly, instead of std::istrstream you should use std::istringstream. You need to include the <sstream> header for these classes.
You could also see this question which explains why strstream was deprecated.
As others have already said, std::ostringstream is the replacement.
It's more convenient (and safer) than std::ostrstream because it manages all memory automatically so you don't need to call freeze(false) to ensure the memory gets freed when you're finished with it.
You should use std::stringstream. Also, see boost::lexical_cast.
std::stringstream supports both << and >>. std::ostringstream only supports <<, and std::istringstream only supports >>. Often I find it convenient to be able to use both operators.
You can also use boost::format. Then you can do things like:
int a = 1;
std::string b("foo");
std::string s = boost::str(
boost::format("some text, some vars=%1%, %2%, %1%") % a % b % a);
Then s would contain "some text, some vars=1, foo, 1".
This is, in my opinion, more convenient in some cases than using operator <<.
As a reference, I also include the format specification.

Is there an equivalent way to do CString::GetBuffer in std::string?

Many Windows API, such as GetModuleFileName, etc... write output to char* buffer. But it is more convenient to use std::string. Is there a way to have them write to std::string (or std::wstring)'s buffer directly?
Sorry for my poor English. I'm not a native English speaker. -_-
Taworn T.
If you're using C++0x, then the following is guaranteed to work:
std::string s;
s.resize(max_length);
size_t actual_length = SomeApiCall(&s[0], max_length);
s.resize(actual_length);
Before C++0x the std::string contents is not guaranteed to be consecutive in memory, so the code is not reliable in theory; in practice it works for popular STL implementations.
use std::string::c_str() to retrieve a const char * that is null terminated.
std::string::data() also returns a const char * but that may not be null terminated.
But like zeuxcg says, I dont suggest you to write directly in that buffer.

use of char * vs std::string in different environments

I have been using std::string in my code. I was going to make a std::string and pass it by reference. However, someone suggested using a char * instead. Something about std::string is not reliable when porting code. Is that true? I have avoided using char * as I would need to do some memory management for it. Instead I find using the std::string much easier to use.
Basically I have a 10 digit output that I am storing in this string. Atm, I am not sure which would be better to use.
std::string is part of the C++ Standard, and has been since 1998. It is available in all the current C++ compilers. There really is no portability reason not to use it. If you have an API that needs to use a C-style string, you can use the std::string's c_str() member to get one from a string:
std::string s = "foo";
int n = strlen( s.c_str() );
In C++, almost every string should be std::string unless another library requires a cstring, in which case you should still be using an std::string and passing string.c_str(), unless you're using functions that work with buffers.
However, if you're writing a library and exporting functions, it's better to use const char* parameters rather than std::string parameters for portability.
Using a char * you are sure that you will not get portability issues among libraries.
If a library exports a function that uses an std::string, it might have problems communicating with another library that has been linked against a different version of the standard library.
I think that there is nothing to worry about unless you are going to provide some API to 3rd party.
Just use std::string
There's nothing unportable about std::string that isn't also an issue with char *. std::string actually uses a char * internally...
string is better. There is nothing unreliable about it on any platform. If you're worried about passing large classes, you can pass const references of your strings into functions. Makes coding faster and less bug prone.
In addition to the fact thata it's easier, std::string will probably be more efficient. Its small string optimization can keep the 10 digits in the std::string object itself, instead of putting them in another memory block off the heap.