Unable to open fstream when specifying an absolute path - c++

I know this is rather laughable, but I can't seem to get simple C++ ofstream code to work. Can you please tell me what could possibly be wrong with the following code:
#include <fstream>
...
ofstream File("C:\temp.txt");
if(File)
File << "lolwtf";
Opening the ofstream fails whenever I specify an absolute path. Relative paths seems to work with no issues. I'm really uncertain as to what the issue is here.

Your path is invalid:
"C:\temp.txt"
The \ is escaping the "t" as a horizontal tab character, so the path value ends up as:
"C: emp.txt"
What you want is:
"C:\\temp.txt"
or
"C:/temp.txt"

Even though Windows people seem to prefer the non-standard '\' character as a path separator, the standard '/' works perfectly and avoids annoying problems like this.
So, my advice is to stick to forward slashes...
std::ofstream File("C:/temp.txt");

The problem is in your string, you are not escaping the backslash.
ofstream File("C:\\temp.txt");

Related

Backslash or Forward Slash in Qt?

I'm trying to open a file in Qt.I used double back slash in this function
doc->dynamicCall("Open(QVariant)", "E:\\QT\\build-untitled-Desktop_Qt_5_7_0_MSVC2015_64bit-Debug\\My Question.doc")
and it works. However, my directory variable's absolute path returns this, which has forward slash:
"E:/QT/build-untitled-Desktop_Qt_5_7_0_MSVC2015_64bit-Debug/My Question.doc"
and It doesn't work. Error says: " Sorry, we couldn't find your file. Is it possible it was moved, renamed or deleted?" I tried everything and it only works with double back slash.
I do know that I have to escape \ as \\, but how do I write this function using my variable ?
I think toNativeSeparators function may help you. Since you are on Windows it will replace forward slashes into backward slashes.
Code is like that:
string path = "E:/QT/build-untitled-Desktop_Qt_5_7_0_MSVC2015_64bit-Debug/My Question.doc";
doc->dynamicCall("Open(QVariant)", QDir::toNativeSeparators(path));

Convert path to \\

Okay, after two days of searching the web and MSDN, I didn't found any real solution to this problem, so I'm gonna ask here in hope I've overlooked something.
I have open dialog window, and after I get location from selected file, it gives the string in following way C:\file.exe. For next part of mine program I need C:\\file.exe. Is there any Microsoft function that can solve this problem, or some workaround?
ofn.lpstrFile = fileName;
char fileNameStr[sizeof(fileName)+1] = "";
if (GetOpenFileName(&ofn))
strcpy(fileNameStr, fileName);
DeleteFile(fileName); // doesn't works, invalid path
I've posted only this part of code, because everything else works fine and isn't relevant to this problem. Any assistence is greatly appreciated, as I'm going mad in last two days.
You are confusing the requirement in C and C++ to escape backslash characters in string literals with what Windows requires.
Windows allows double backslashes in paths in only two circumstances:
Paths that begin with "\\?\"
Paths that refer to share names such as "\\myserver\foo"
Therefore, "C:\\file.exe" is never a valid path.
The problem here is that Microsoft made the (disastrous) decision decades ago to use backslashes as path separators rather than forward slashes like UNIX uses. That decision has been haunting Windows programmers since the early 1980s because C and C++ use the backslash as an escape character in string literals (and only in literals).
So in C or C++ if you type something like DeleteFile("c:\file.exe") what DeleteFile will see is "c:ile.exe" with an unprintable 0xf inserted between the colon and "ile.exe". That's because the compiler sees the backslash and interprets it to mean the next character isn't what it appears to be. In this case, the next character is an f, which is a valid hex digit. Therefore, the compiler converts "\f" into the character 0xf, which isn't valid in a file name.
So how do you create the path "c:\file.exe" in a C/C++ program? You have two choices:
"c:/file.exe"
"c:\\file.exe"
The first choice works because in the Win32 API (and only the API, not the command line), forward slashes in paths are accepted as path separators. The second choice works because the first backslash tells the compiler to treat the next character specially. If the next character is a hex digit, that's what you will get. If the next character is another backslash, it will be interpreted as exactly that and your string will be correct.
The library Boost.Filesystem "provides portable facilities to query and manipulate paths, files, and directories".
In short, you should not use strings as file or path names. Use boost::filesystem::path instead. You can still init it from a string or char* and you can convert it back to std::string, but all manipulations and decorations will be done correctly by the class.
Im guessing you mean convert "C:\file.exe" to "C:\\file.exe"
std::string output_string;
for (auto character : input_string)
{
if (character == '\\')
{
output_string.push_back(character);
}
output_string.push_back(character);
}
Please note it is actually looking for a single backslash to replace, the double backslash used in the code is to escape the first one.

Read files in C++

This is my simple code:
#include "C:\Users\Myname\Desktop\Documents\std_lib_facilities.h"
using namespace std;
//**************************************************
int main()
try {
ifstream ifs("C:\Users\Myname\Desktop\raw_temps.txt");
if(!ifs) error("can't open file raw_temps.txt");
keep_window_open("~~");
return 0;
}
//**************************************
catch(runtime_error& e) {
cerr<<e.what();
keep_window_open("~~");
return 1;
}
The .txt file is in address "C:\Users\Myname\Desktop\raw_temps.txt".
When I run that, only the error (" ... ") function operates and theifs can't open the raw_temps.txt file.
Why please?
I believe that this problem is are due to some misunderstanding your use of backslashes as a path separator. Paths in c++ should be written with normal slashes, and not backslashes to prevent errors like those you have done here. This is because a single backslash is used as an escape character, meaning that it combined with the next symbol becomes a new symbol. An example is "\n" for newline or "\t" for tab.
To prevent this, and to make the code run on all platforms, and not just those using backslash as path separator, stick to slash as a path separator.
More information on this can be found on Marshal Clines C++ FAQ
And, yes, you can make this work with double backslashes, but then you are making a bad habit IMO. Plus that it is two characters where only one is needed.
You need to ignore "\" as it is a wildcard character. Replace "\" with "\".
Change this line
ifstream ifs("C:\Users\Myname\Desktop\raw_temps.txt");
To this
ifstream ifs("C:/Users/Myname/Desktop/raw_temps.txt");
\ is used to mark escape characters, so unless you use \\, the string will not look like what you think it should. You can see this by using a debugger and breaking on this line.
best option is to keep the file you want to open in the folder of source code and write this
ifstream ifs("raw_temps.txt");

c++ opening file with non-Latin name

I have such files. I just want to open files with non-Latin names correctly.
I have no problems with files that have Latin names only with non-Latin names.
I use QDir for scanning directory and I hold names in QString, so it's held fine inside.
But there is a bottleneck with opening the file.
It gets so that I don't want to use QFile, I can use only C++ streams (more preferred) or C files.
When I want to open file, I do so:
fstream stream(source.toStdString().c_str(),ios_base::in | ios_base::binary);
After that I check whether attempt was successful:
if(!stream.is_open())
{ cout<<"file wasn't opened " <<source.toStdString().c_str())<<"\n";
return false; // cout was redirected to file // just a notice
}
I get in my log file:
file wasn't opened /home/sh/.mozilla/firefox/004_??????? - ????? - ?????.mp3
It doesn't work for any file with non-Latin name and it does work fine for every file with Latin names.
I understand that this problem can be jumped over using QFile.
But I wonder, is it possible to get it done without third-party libraries or are there some another ways for solving it?
Thanks in advance for any tips.
Things are going wrong when you call toStdString() on your QString. It will convert the contents based on QTextCodec::codecForCStrings(), if it has been set, and latin-1 will be used otherwise. Latin-1 will collapse your non-latin characters to '?'s.
Using source.toLocal8Bit().data() or source.toUtf8().data() instead will likely do what you want, but failing that you'll need to deal with QTextCodecs to get the right 8-bit encoding.

executing filenames with spaces in cmd pmt Passed from c++ program

I am currently working on getting my program to execute a program (such as power point) and then beside it the path to the file I want to open. My program is getting the file's path by using:
dirIter2->path()
I get the 2 paths of the program and file, Merge them as one string and pass them into the following:
system(PathTotal.c_str())
this is working great but my only issue is that when the file name has a space in its name command prompt says it cannont find the file (becuase it thinks the file name ends when it gets to the first space. I have tried to wrap it with quotes but it is the acutal file name that need to be wrapped.
(eg. i have tried "C:\users\bob\john is cool" but it needs to be like this: C:\users\bob\"john is cool")
Does anyone have any suggestions on how I could fix this? I was thinking about getting the path to the folder to where the file and then getting the file name. I would wrap the file name with quotes then add it to the folder's path. I have tried using the ->path() like above but the only problem is that it only goes to outside of the folder's directory?
Is there a boost command that could get the enitre path to the file without getting the file aswell?
I am not commited to this idea if anyone has any better suggestions
Thanks
In both C and C++, the '\' is an escape character. For certain things (like '\n' or '\t') it inserts a control code; otherwise, it just gives you the next character.
So if you do something like:
fopen("C:\users\bob\john is cool", "r");
it's going to try to open a file named
C:usersbobjohn is cool
If you want those '\' characters in the output, you have to escape them. So you'd want:
fopen("C:\\users\\bob\\john is cool", "r");
On Windows with Visual Studio, I've also successfully used Unix-style separators:
fopen("C:/users/bob/john is cool", "r");
And in fact, you can mix them up:
fopen("C:/users\\bob/john is cool", "r");
I'm not familiar with C string operations, but couldn't you do the following rather easily?
int i = path.lastIndexOf("\\"); //Find the index of the last "\"
String quotedPath = path.substring(0, i+1); //Get the path up until the last "\"
quotedPath += "\"" + path.substring(i+2) + "\""; //Add quotes and concatenate the filename
Sorry for the Java, its the closest thing that I'm familiar with. I've made this a community wiki in case someone can edit the code to the equivalent C.
I'd also like to add that sometimes it is necessary to escape spaces as in the following:
cmd.exe -C C:/Program\ Files/Application\ Folder/Executable\ with\ spaces.exe
or
cmd.exe -C C:\\Program\ Files\\Application\ Folder\\Executable\ with\ spaces.exe