c++ Write Chars into Batch file - c++

Why does this give error at '%' as incorrect formatted speical character.
ofstream batch;
batch.open("C:\tesfile.bat", ios::out);
batch << "#echo off\n";
batch << "set Dir=C:\Users\%USERNAME%\AppData\ \n";
Also i gave c:\ to create bat file it creates bat file at the app folder (where the app is placed).
Please help.

You should either escape special character \ in your string, or use C++11 raw literals (much better option in my view!) like this:
batch.open(R"(C:\tesfile.bat)", ios::out);

In a string, you need to escape your backslashes (\) as \\. Otherwise, the compiler thinks you are trying to insert special characters like \n:
batch.open("C:\\tesfile.bat", ios::out);
batch << "#echo off\n";
batch << "set Dir=C:\\Users\\%USERNAME%\\AppData\\ \n";
As a thought exercise, imagine what would happen if you didn't escape your backslashes:
batch.open("C:\nifty_folder", ios::out); //\n in "nifty" causes a newline!
In fact, your original code has an unintended consequence!
batch.open("C:\tesfile.bat", ios::out); //\t is a tab!

Related

Why do I need std::endl to reproduce input lines I got with getline()?

I am a newbie learning C++ to read or write from a file. I searched how to read all contents from a file and got the answer I can use a while loop.
string fileName = "data.txt";
string line ;
ifstream myFile ;
myFile.open(fileName);
while(getline(myFile,line)){
cout << line << endl;
}
data.txt has three lines of content and output as below.
Line 1
Line 2
Line 3
but if I remove "endl" and only use cout<<line; in the curly bracket of the while loop, the output change to :
Line 1Line 2Line 3
From my understanding, the while loop was executed 3 times, what's the logic behind it?
endl means "end line" and it does two things:
Move the output cursor to the next line.
Flush the output, in case you're writing to a file this means the file will be updated right away.
By removing endl you are writing all the input lines onto a single output line, because you never told cout to go to the next line.
Your question regards a semantic ambiguity with std::getline(): Should it result be "a line", in which case the result should include the line-ending newline character, or should the result be the contents of a line, in which case the trailing newline should be dropped?
In the C programming language, getline() takes the first approach:
getline() reads an entire line from stream ... The [result] buffer is
null-terminated and includes the newline character, if one was found.
but in C++, the semantics are different: The newline is considered to be a delimiter, and the results of repeated calls to std::getline() is the content without the delimiter. Note that the function actually takes the delimiter in a third parameter, which defaults to '\n', but could be replaced with any other single character. That makes std::getline() more of a tokenizer.

Saving A File to Directory C++

So i've spent about 30minutes on this with no luck. Tried many ways of saving the file. It works when i save it into:
C:\Users\jsmit\OneDrive\Documents\Visual Studio 2017\Projects\Password Generator\Password Generator
but not when i try and save it into:
C:\Users\jsmit\OneDrive\Documents
or:
C:\Users\jsmit\Documents\New folder
This is my code for saving a file:
void savePassword(string stringpassword, string site) {
ofstream out("C:\Documents\New folder\output.txt", ofstream::app); // DOESN'T WORK
out << site << ": " << stringpassword << endl; // This is where it saves the password into the text file
out.close(); // Closes file
}
If i put:
ofstream out("Password.txt", ofstream::app); // ofstream:app stops overwrite
it works.
EDIT:::: Allows me to save to H:\New folder but not C: drive? How to fix?
How do i make it so it saves it into: C:\Users\jsmit\OneDrive\Documents
The problem is the character \ use \\ or /
See here for more details:
In C, all escape sequences consist of two or more characters, the
first of which is the backslash, \; the remaining characters determine
the interpretation of the escape sequence. For example, \n is an
escape sequence that denotes a newline character. The remainder of
this article focuses on C; other programming languages are likely to
have different syntax and semantics.
Like others said \ is the escape character. You need to use double backslashes when meaning for \ to be included.
You can't just write into C: unless you are admin.
Use the shortcut for the Home Folder "%USERPROFILE%" to access this folder, then you can use "%USERPROFILE%\OneDrive\Documents"
Also, make sure the folder exists before writing any file into it. The folder won't be automatically created, you have to make it yourself.
Also, take a look at other answers, '\' character should be '\\'

C++ file reading and string printing

Why do these two print different things? The first prints abcd but the second prints \x61\x62\x63\x64. What do I need to do to make the line from the file to be read as abcd?
std::string line("\x61\x62\x63\x64");
ifstream myfile ("myfile.txt"); //<-- the file contains \x61\x62\x63\x64
std::string line_file;
getline(myfile,line_file);
cout << line << endl;
cout << line_file << endl;
In c++, the backslash is an escape character, which can be used to represent special characters such as new-lines \n and tabs \t, or in your case, hexadecimal representations of ASCII characters in string literals. If you actually want to store a backslash in c++ you have to escape it: char c='\\'. When you read a backslash from a file, it's not treated as an escape character, but as an actual backslash.
It has to do with the input file stream character interpretation:
File streams opened in binary mode perform input and output operations independently of any format considerations. Non-binary files are known as text files, and some translations may occur due to formatting of some special characters (like newline and carriage return characters).
Text file streams are those where the ios::binary flag is not included in their opening mode. These files are designed to store text and thus all values that are input or output from/to them can suffer some formatting transformations, which do not necessarily correspond to their literal binary value.
So, the backslashes'\' are the most probable reason your ifstream is reading and interpreting the bytes from the file differently (as separate characters), as opposed to the string that contains information about its value, thus making it non-ambiguous.
For further reading see how fstreams work and learn about character literals backslash escape.

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");

Reading in quoted CSV data without newline as endline

I have an issue with a file I am trying to read in and I don't know how to do solve it.
The file is a CSV, but there are also commas in the text of the file, so there are quotes around the commas indicating new values.
For instance:
"1","hello, ""world""","and then this" // In text " is written as ""
I would like to know how to deal quotes using a QFileStream (though I haven't seen a base solution either).
Furthermore, another problem is that I also can't read line by line as within these quotes there might be newlines.
In R, there is an option of quotes="" which solves these problems.
There must be something in C++. What is it?
You can split by quote (not just quote, but any symbol, like '\' for example) symbol in qt, just put \ before it, Example : string.split("\""); will split string by '"' symbol.
Here is a simple console app to split your file (the easiest solution is to split by "," symbols seems so far):
// opening file split.csv, in this case in the project folder
QFile file("split.csv");
file.open(QIODevice::ReadOnly);
// flushing out all of it's contents to stdout, just for testing
std::cout<<QString(file.readAll()).toStdString()<<std::endl;
// reseting file to read again
file.reset();
// reading all file to QByteArray, passing it to QString consructor,
// splitting that string by "," string and putting it to QStringList list
// where every element of a list is value from cell in csv file
QStringList list=QString(file.readAll()).split("\",\"",QString::SkipEmptyParts);
// adding back quotes, that was taken away by split
for (int i=0; i<list.size();i++){
if (i!=0) list[i].prepend("\"");
if (i!=(list.size()-1)) list[i].append("\"");
}//*/
// flushing results to stdout
foreach (QString i,list) std::cout<<i.toStdString()<<std::endl; // not using QDebug, becouse it will add more quotes to output, which is already confusing enough
where split.csv contains "1","hello, ""world""","and then this" and the output is:
"1"
"hello, ""world"""
"and then this"
After googling I've found some ready solution. See this article about qxt.