I using function "ofstream" wrong - c++11

I want write some code to write to a file but I don't know how. This is the code I have.
string filename;
ofstring fout(filename);
Why is this code wrong?

Try this:
ofstream fout;
string filename;
fout.open(filename.c_str());

I think you have just misspelled the name of the class.
#include <fstream>
std::string filename = ...
std::ofstream fout(filename);

Related

why the output of the auto variable displays something not related to type?

I tried a example on Auto for variable initialization and STL in C++. For normal variable, type was printed using : typeid(var_name).name() to print i (integer) / d(float) / pi(pointer) which works fine.
But while working on STL,
`#include <iostream>
#include <vector>
using namespace std;
int main()
{
vector<string> st;
st.push_back("geeks");
st.push_back("for");
for (auto it = st.begin(); it != st.end(); it++)
cout << typeid(it).name() << "\n";
return 0;
}
`
which gives output like,
`N9__gnu_cxx17__normal_iteratorIPNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESt6vectorIS6_SaIS6_EEEE
N9__gnu_cxx17__normal_iteratorIPNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESt6vectorIS6_SaIS6_EEEE`
and I am unable to understand the output logic behind it, can anyone explain why it is giving output like this? and thanks in advance
That's the "name mangled" version of the name of the type of it. typeinfo::name() is not required by the standard to return a name in human-readable format (a shortcoming IMHO) and GCC doesn't do so.
To get the actual, human-readable name, you need to call the abi::__cxa_demangle() function provided by GCC, but note that this is non-portable so if your project needs to work on different compilers you'll need to wrap it appropriately.

Error: unable to open primary document entity

I'm trying to parse an xml file(I've got the schema definition in xsd as well) in my c++ program using xerces library. To get things started I've written a small program, where I just initialise the std::unique_pointer with the xml file. I get the following error if I use an std::string object containing the xml file while initialising whereas the program runs fine if I use the xml file directly for initialisation.
The main program is as follows:
#include <stdio.h>
#include <iostream>
#include "ShDataTypeRel15.hxx"
#include<fstream>
#include<string>
using namespace std;
int main (int argc, char* argv[])
{
try
{
fstream t("/home/vishal/UDA_XML/ShDataTypeRel15.xml", ios::in);
stringstream buffer;
buffer << t.rdbuf();
std::string xml_file = buffer.str();
std::unique_ptr<tSh_Data> Shdata(Sh_Data(xml_file));
}
catch (const xml_schema::exception& e)
{
cout <<"Exception caught"<<std::endl;
std::cerr << e << std::endl;
return 1;
}
return 0;
}
When I replace std::unique_ptr<tSh_Data> Shdata(Sh_Data(xml_file)); with std::unique_ptr<tSh_Data> Shdata(Sh_Data(argv[1])); then the program runs fine(I provide the path to the xml file as command line input.)
I get the following error:
Exception caught
:0:0 error: unable to open primary document entity '/home/vishal/UDA_XML/<?xml version="1.0"?>
The above error statement is followed by the xml file.
Problem was solved after I stored the location of my XML file in the string object instead of the whole content of that XML file in it.
i.e.
Now my std::string xml_file = path_to_xml_file;

MFC - Display message

I'm trying to display a simple message within my first MFC application.
Strangely, the first sample doesn't work, instead the second one works correctly.
auto text = std::to_wstring(1).c_str();
MessageBox(text, NULL, 0); // Not ok, the message is empty
auto temp = std::to_wstring(1);
MessageBox(temp.c_str(), NULL, 0); // Ok, display 1
Can you explain why of this behavior?
Yes, in the first example, the wstring created by the call to std::to_wstring only has the scope of the line. After the line executes, it is out of scope and its value is dubious.
In the second example, the wstring is still in scope and valid and so the call to .c_str() works.
No, the other answer is wrong. Look at the implementation of c_str(). c_str() returns basically a LPCWSTR... call it a const WCHAR* or const wchar_t* or whatever. However, the return of c_str() is to an internal pointer of wstring. The problem is that after the line of code executes, the wstring returned from to_wstring() is not valid and so the the pointer returned by c_str() is garbage. For fun, try the following code:
//cstr_.cpp
#include <iostream>
#include <string>
using namespace std;
int main(int argc, char* argv)
{
auto temp = to_wstring(1).c_str();
wprintf(L"%s\n", temp);
auto temp2 = to_wstring(1);
wprintf(L"%s\n", temp2.c_str());
wstring ws = to_wstring(1);
auto temp3 = ws.c_str();
wprintf(L"%s\n", temp3);
}
I compiled the above from a VC++ shell prompt with: cl.exe cstr.cpp
If the other answer is correct, then the last line should have garbage or nothing output because according to the other answer, c_str() is a temp. But, if my answer is correct, then it should output 1 (which it does). If all else fails, look at the implementation source code.

Save list of files in array

I am making a C++ program which should be able to list the files from particular directory and save each file name as a string(which will be processed further for conversion). Do I need array of strings? Which functionality should I use. The number of files is not fixed.
Main thing is I can't enter the names manually. I must accept the names from the list generated.
In this case you want to use a vector:
#include <vector>
#include <string>
using namespace std;
int main()
{
vector<string> file_names;
file_names.push_back("file1.txt");
file_names.push_back("file2.txt");
file_names.push_back("file3.txt");
file_names.push_back("file4.txt");
return 0;
}
Have you thought about using some command line tools to deal with this? Even input redirection will work for this. Example:
./Cpp < echo somedir/*
Where Cpp is the name of your compiled binary, and somedir is the directory you want to read from
Then in your c++ program, you simply use std::cin to read each filename from standard in.
#include <vector>
#include <string>
#include <iterator> // std::istream_iterator, std::back_inserter
#include <algorithm> //std::copy
#include <iostream> // std::cin
int main()
{
std::vector<string> file_names;
// read the filenames from stdin
std::copy(std::istream_iterator<std::string>(std::cin), std::istream_iterator<std::string>(), std::back_inserter(file_names));
// print the filenames
std::copy(file_names.begin(), file_names.end(), std::ostream_iterator<std::string>(std::cout, "\n"));
return 0;
}

scoped_lock doesn't work on file?

According to the link below, I wrote a small test case. But it doesn't work. Any idea is appreciated!
Reference:
http://www.cppprog.com/boost_doc/doc/html/interprocess/synchronization_mechanisms.html#interprocess.synchronization_mechanisms.file_lock.file_lock_careful_iostream
#include <iostream>
#include <fstream>
#include <boost/interprocess/sync/file_lock.hpp>
#include <boost/interprocess/sync/scoped_lock.hpp>
using namespace std;
using namespace boost::interprocess;
int main()
{
ofstream file_out("fileLock.txt");
file_lock f_lock("fileLock.txt");
{
scoped_lock<file_lock> e_lock(f_lock); // it works if I comment this out
file_out << 10;
file_out.flush();
file_out.close();
}
return 0;
}
Running the test on Linux produces your desired output. I notice these two warnings:
The page you reference has this warning: "If you are using a std::fstream/native file handle to write to the file while using file locks on that file, don't close the file before releasing all the locks of the file."
Boost::file_lock apparently uses LockFileEx on Windows. MSDN has this to say: "If the locking process opens the file a second time, it cannot access the specified region through this second handle until it unlocks the region."
It seems like, on Windows at least, the file lock is per-handle, not per-file. As near as I can tell, that means that your program is guaranteed to fail under Windows.
Your code appears to be susceptible to this long-standing bug on the boost trac site: https://svn.boost.org/trac/boost/ticket/2796
The title of that bug is "interprocess::file_lock has incorrect behavior when win32 api is enabled".
Here is a workaround to append in a file with a file locking based on Boost 1.44.
#include "boost/format.hpp"
#include "boost/interprocess/detail/os_file_functions.hpp"
namespace ip = boost::interprocess;
namespace ipc = boost::interprocess::detail;
void fileLocking_withHandle()
{
static const string filename = "fileLocking_withHandle.txt";
// Get file handle
boost::interprocess::file_handle_t pFile = ipc::create_or_open_file(filename.c_str(), ip::read_write);
if ((pFile == 0 || pFile == ipc::invalid_file()))
{
throw runtime_error(boost::str(boost::format("File Writer fail to open output file: %1%") % filename).c_str());
}
// Lock file
ipc::acquire_file_lock(pFile);
// Move writing pointer to the end of the file
ipc::set_file_pointer(pFile, 0, ip::file_end);
// Write in file
ipc::write_file(pFile, (const void*)("bla"), 3);
// Unlock file
ipc::release_file_lock(pFile);
// Close file
ipc::close_file(pFile);
}

Resources