fstream not creating text file - c++

It seems when I try to run this source of code, instead of making an Attempt1.txt, or Attempt2.txt, or Attempt3.txt, it simply just makes a FILE named Attempt.
string str;
int num_attempts_x_million = 1;
str = "Attempt";
str += num_attempts_x_million;
str += ".txt";
textfile.open(str);
textfile << password << endl;
textfile.close();

You might be appending control characters, not 'regular' characters. This is assuming, of course, that the type of num_attempts_x_million is an int (or any integer type).
std::string::operator+= does not have an overload for int. Instead, it has one for char so it casts it into a char first and then appends it. For low integer values, this ends up with things like 0x0, 0x1, 0x2, etc which are known as control characters in ASCII.
In order for you to convert the integer into a string you have to use std::to_string.

str = "Attempt";
str += std::to_string(num_attempts_x_million);
str += ".txt";
textfile.open(str);
textfile << password << endl;
textfile.close();

Related

Add a Character Between Strings in C++

So basically I'm trying to add a character in the middle of a string. Normally in something like Python, this would be pretty straightforward, but I'm really not sure how to achieve this in C++. What I'm trying to achieve is something like this:
void converter(){
converted = ":regional_indicator_" + character + ":";
}
So basically, I'm trying to add the variable character of a type char in a string. Should I be storing character as a string instead?
For reference here's all of my code:
#include <iostream>
using namespace std;
string inputLine;
char character;
string converted;
void input(){
cout << "Please input the text in which you would like to be converted" << endl;
cin >> inputLine;
}
void converter(){
converted = ":regional_indicator_" + character + ":";
}
int main(){
input();
for (int i = 0; i < inputLine.length(); i++ ){
character = tolower(inputLine[i]);
}
return 0;
}
Append s behind the strings literals to treat them as std::strings instead of const char*s:
converted = ":regional_indicator_"s + character + ":"s;
You would need to do either using namespace std::literals or using namespace std::string_literals for it to work.
On a side note, in C++, it is strange to have a function converter() to modify a global variable using another global variable. You might want to consider passing character as a parameter to the function instead.
You can do it like this:
converted = ":regional_indicator_" + std::string(1, character) + ":";
This works because adding a string literal (const char *) to a string yields a string. But adding const char * and char results in pointer arithmetic. So, by constructing a std::string from "character" you end up with const char * + std::string yielding a string and then std::string + const char * again yields a string as the final result.
You can avoid invoking the std::string() constructor and memory allocation by using following. I have tested this before posting and it works:
void converter(){
converted = ":regional_indicator_";
converted.push_back(character);
converted.push_back(':');
}
It's better because "converted" already will have some extra memory reserved, so you will just be filling that extra memory with two more characters and won't be allocating new memory.
The wasy way to build strings is to use a std::ostringstream like this:
void converter(){
std::ostringstream oss;
oss << ":regional_indicator_" << character << ":";
converted = oss.str(); // copy the string out
// ... etc ...
}
The added advantage of that method is it converts numbers to string automatically too.
That's not the fastest way so if speed was important I would take advantage of the static nature of this concatenation like this:
std::string converter(){
static char* template = ":regional_indicator_X:";
template[20] = character; // replace the `X` with your character
converted.assign(template, 21); // assign your string all at once
// ... etc ...
}
That works because your string is of fixed length. If thread safety is required you can use thread_local static char* template....

Converting int to string and adding to an existin string in c++

I was wondering how I could convert an int to a string and then add it to an existin string. i.e.
std::string s = "Hello";
//convert 1 to string here
//add the string 1 to s
I hope I'm making sense. Thank you very much in advance for any answer.
If the number you want to append is an integer or floating point variable, then use std::to_string and simply "add" it:
int some_number = 123;
std::string some_string = "foo";
some_string += std::to_string(some_number);
std::cout << some_string << '\n';
Should output
foo123
The "modern" way is to use std::to_string(1). In fact, various overloads of std::to_string exist for different number types.
Putting this together you can write std::string s = "Hello" + std::to_string(1);
Alternatively you can use std::stringstream which can be faster due to fewer string concatenation operations which can be expensive:
std::stringstream s;
s << "Hello" << 1;
// s.str() extracts the string

How to convert a string to its unicode escapes?

I'm trying to convert a char array to unicode-escapedchar array.
Say I have a string "C:/İmüp".
How can I convert it to C:/\u0130m\u00fcp as char array or const char?
(I get "C:/Hello İmüp" as char array via ExpandEnvironmentStrings(), then i need to write that to a file with its unicode escapes)
I tried typecast converting, std::stringstream and ASCII tables, looked up for examples on C++ json encoders, however i couldn't get it working
Try this:
std::wstring env;
// fill env with data from ExpandEnvironmentStringsW()...
std::stringstream ss;
for (std::wstring::iterator iter = env.begin(); iter != env.end(); ++iter)
{
if (*iter <= 127)
ss << (char) *iter;
else
ss << "\\u" << std::hex << std::setfill('0') << std::setw(4) << (int)*iter;
}
std::string str = ss.str();
// use str as needed...
First convert it from char array to wchar_t array, using the system-default code page.
Then write trivial code that walks over your wchar_t array and escapes every Unicode character with code >= 128.
P.S. Better yet, make your application Unicode so it will use Unicode version of ExpandEnvironmentStrings. This way you will only have to escape the string, plus your app will still work correctly if some environmental string contains a character that doesn’t fit in char with your system-default code page.
Try this code:
string yourAsciiString = "this is test";
string yourUnicodeString = System.Text.Encoding.Unicode.GetString(System.Text.Encoding.ASCII.GetBytes(yourAsciiString));

Making a sequential list of files

I have been stuck on a problem for a while now and can't seem to find an answer.
I'm trying to create multiple files with the same name but a different number at the end each time, I have attempted this at first just by using
int seq_number = 1;
while (seq_number < 10)
{
ofstream fsave;
fsave.open("filename" + seq_number + ".txt");
fsave << "blablabla";
fsave.close();
seq_number = seq_number + 1;
}
But that gives me a very strange result where the letters get jumbled up, I'm not sure how that works but I know it doesn't.
I've looked online and found stringstream or sstream, and tried with that, but it keeps giving me errors too,
string filename;
filename = "character";
ostringstream s;
s << filename << seq_number;
filename(s.str());
fsave.open(filename + ".txt");
fsave << "blabla"
fsave.close(;)
but i keep getting an error:
no match for call to `(std::string) (std::basic_string, std::allocator >)'
I'm not sure how string stream works exactly so im working off of instinct, but i would appreciate any way this is possible, and honestly I think I would prefer doing it without sstream, but i need a way to get an int and str together and save a filename that is a string.
unless you know a better way ;) thanks guys
filename(s.str());
this is wrong; you are not constructing a new variable (filename is already constructed), what you want here is an assignment.
filename = s.str();
Then,
fsave.open((filename + ".txt").c_str());
(although, if you are using C++11, this change is not necessary)
Still, personally I would just construct the whole file name with the stream:
ostringstream s;
s<<"character"<<seq_number<<".txt";
fsave.open(s.str.c_str());
I'm not sure how string stream works exactly so im working off of instinct
This is a very bad idea, C++ is often quite a minefield of bizarre syntax, segfaults and undefined behavior, going by instinct usually leads to disaster.
About the errors you get:
fsave.open("filename" + seq_number + ".txt");
This shouldn't even compile, since you are summing an integer to a const char * (thus moving the "start of the string"), and then summing it again to a const char *, which is not allowed at all. Maybe it could compile if it were like this:
fsave.open("filename" + seq_number);
but it won't give the required result - "filename" is a pointer (not a C++ string), so summing an integer to it just moves the pointer of the given offset.
In your second snippet, instead, you are using an object (filename) as it were a function, which is only allowed if the class overloads operator(); thus, the compiler complains that such an operation is not allowed on that object.
Replace
fsave.open(filename + ".txt");
With
fsave.open( (filename + ".txt").c_str() );
This is because the ofstream constructor takes as parameter a char const *, not an std::string.
Also, your first version generates strange file names because in C and C++, adding an integer to a char * simply offsets within the character array. It does not append to the string.
In C++ you can not convert an int to a string, or concatenate it to one -- not to a ´char*`:
"filename" + seq_number + ".txt"
^const char* ^int ^const char*
Also, ostream can not recieve the filename as a string, it must be a const char*, which you can acquire temporarily via ´c_str()`.
Use sprintf, ostringstream (as you did), or C++11 to_string to do that:
#include <string>
#include <iostream>
int main() {
for(int seq_number = 1; i<10; ++i) {
std::string num_as_string = std::to_string(seq_number); // make a string, C++11
std::string filename = "abcd" + num_as_string + ".txt";
std::ostream f(filename.c_str());
f << "text\n";
}
}
This (modulo typos) should get you started.
You can do it like this:
ostringstream s;
s << "character" << seq_number << ".txt";
fsave.open(s.str());
fsave << "blabla";
fsave.close();
And this is how you could implement the original loop:
for (int seq_number = 1; seq_number<10; ++seq_number)
{
ostringstream s;
s << "filename" << seq_number << ".txt";
ofstream fsave(s.str());
fsave << "blablabla";
}
You could do something like this:
#include <iostream>
#include <string>
#include <sstream>
int main (int argc, char const* argv[])
{
std::string filename;
int seq_number = 10;
filename = "character";
std::stringstream s;
s << filename << seq_number << ".txt";
filename = s.str();
std::cout<< filename << std::endl; // <-- Here open your file instead print the filename
}

Store a string of hex into a char?

so I have a string that has a hex value in it. For example, my string may have
string a = "0x4D";
Would it be possible to assign 0x4D to a char? Because I know that if I had
char c = 0x4D
then I could print out its ASCII symbol, which would be M.
Is it possible to store "0x4D" into a char so that I can print out its ascii symbol? If anyone has any tips, that would be appreciated! If there's a better way to do this, please let me know! Thanks!
You can use strtol to convert the string to a number. You can then print this number or do other things you like with it.
Oh wait, you tagged it C++, and strtol is very much C-style. In C++, you can use a stringstream, and extract a number from it.
You can use std::stoi to convert the string to an integer (the base is auto-detected from the 0x prefix):
std::string str = "0x4D";
char c = static_cast<char>(std::stoi(str));
std::cout << c << std::endl;
However, this is not guaranteed to give you the ASCII character for that value. There are various translations between character sets that occur in this simple code alone. For example, the chars in the string literal "0x4D" are initialized with the corresponding value in the implementation-defined execution character set. The printed character is also up to interpretation by the medium that is displaying it.
The best you could do is provide a mapping from ASCII values to characters. You could do this with an array where the index is the ASCII value and the element is the corresponding character.
To use stringstreams as Bas suggests:
int x;
string s = "0x10";
stringstream ss;
ss << hex << s;
ss >> x;
But I think it's a wasteful way to do it.
Here is a solution based on std::stringstream:
std::istringstream iss ("0x4D");
iss.flags(std::ios::hex);
int i;
iss >> i;
std::cout << "[" << (char)i << "]" << std::endl; //--> prints "[M]"