So I am trying to save a string (that is stored in a String variable) into a text file... I have literally spent almost 2 hour looking this up and have not been able to find out why c++ is incapable of writing string variable into a text document.
What am I missing here?
private: System::Void SaveButton_Click(System::Object^ sender, System::EventArgs^ e) {
String^ _String= "WHATTHEFUCK";
//So this works vvv
ofstream _SaveFile;
_SaveFile.open("SaveCFG.txt");
_SaveFile << "FUUUUCK"; //<<<<<<<<
_SaveFile.close();
//^^^
//But this does NOT work vvv
ofstream _SaveFile;
_SaveFile.open("SaveCFG.txt");
_SaveFile << _String; //<<<<<<<<
_SaveFile.close();
//^^^
//Neither does this vvv
ofstream _SaveFile;
_SaveFile.open("SaveCFG.txt");
_SaveFile << "WTF" << _String<< endl; //<<<<<<<<
_SaveFile.close();
//^^^
}
Might be way off here, but assuming that you are writing the pointer and not the string. Don't have a C++ compiler, but you could try (if I remember correctly):
//But this does NOT work vvv
ofstream _SaveFile;
_SaveFile.open("SaveCFG.txt");
_SaveFile << *_String; // or is it &_String;
_SaveFile.close();
//^^^
It looks like nowadays people use std::string instead though. Hope you find your answer.
Related
I'll cut the the short of it. I'm attempting to understand the filesystem library but there's very little information I've been able to find. I managed to get it to compile and understand the filesystem::path type variable really well but don't seem to understand how to get filesystem::directory_iterator to work properly. I'm not sure if I'm using it for a purpose it wasn't design for. So here is what I'm attempting to do:
I wanted to create a program that opens every text file within a specified folder. For this I need to obtain the folder name and path but I want the program to be able to obtain this information on itself and dynamically so if I add or remove textFiles it'll have the logic to function.
I'm able to create a directory_iterator variable that it manages to hold the first file with me just giving it the directory like this:
const char address[]{ "C:\\Users\\c-jr8\\ProgramBranch\\PersonalPlatform\\log extruder\\logs" };
fs::directory_iterator myIterator(address);
When testing the code in the folder I have four textFiles called "attempt 1" to "attempt 4". When reading the information on:
https://learn.microsoft.com/en-us/cpp/standard-library/directory-iterator-class?view=vs-2019#op_star
It mentions two functions to move the path object within the iterator to the next file. The first is increment(), which is the intendent method for iterating through the files, and operation++().
Now increment() hasn't been able to work for me cause it takes in a erro_code type variable and I haven't been able to find much information about how to implement this with the filesystem_errorcode variable or however it's meant to be used. The operation++() works beautifully and provides me with the path to every file but I was having issues with managing the code to detect when the operate++() functions leads to no other files. Once it iterates through every file it sorts of crashes when it keeps moving to the next. Here's that piece of code:
string tempString;
for (int i = 0; i < 5; i++) { //Here the limiting is 5 so it'll iterate onces more than the numbers of files unpurpose to see how it responses.
tempString = myIterator.operator*().path().generic_string();
ifstream tempFile(tempString);
if (!tempFile.is_open()) {
cout << "Looking at file: " << i + 1 << "; failed to open." << endl << endl;
cin.get();
return 0;
}
{
//do things with file...
}
tempFile.close();
myIterator.operator++();
}
What I want if to find a way to stop the for loop once it the iterator goes off the final file.
whichever information about how the filesystem library works it would be very much appreciated.
std::directory_iterator is a classic iterator that allows for iterating over ranges, and those are usually designated by a pair of iterators, one indicating the beginning of a sequence and another representing the past-the-end iterator.
Some iterator types, like those providing access to streams, don't have an actual end location in memory. A similar situation applies to a directory iterator. In such a case, the idiomatic approach is to use a default-constructed iterator object that will serve as an end indicator.
Having said that, you could rewrite your loop to:
for (fs::directory_iterator myIterator(address), end{}; myIterator != end; ++myIterator) {
Alternatively, you can utilize a range-based for loop:
for (auto& p : fs::directory_iterator(address)) {
tempString = p.path().generic_string();
// ...
Also, note that iterators' interface is supposed to look/behave like a pointer, hence it uses operator overloading to allow for concise syntax. So instead of:
myIterator.operator++();
you should be using:
++myIterator;
Similarly, instead of:
myIterator.operator*().path().generic_string();
juse use:
(*myIterator).path().generic_string();
or:
myIterator->path().generic_string();
You should compare myIterator with a default constructed directory_iterator to check if the last file has been processed. You can also use a much simpler form to access the operators (shown in the code below):
string tempString;
// loop until myIterator == fs::directory_iterator{}
for(size_t i = 1; myIterator != fs::directory_iterator{}; ++i) {
// access path() through the iterators operator->
tempString = myIterator->path().generic_string();
ifstream tempFile(tempString);
if(!tempFile.is_open()) {
cout << "Looking at file: " << i << "; failed to open." << endl << endl;
cin.get();
return 0;
}
{
std::cout << tempString << " opened\n";
}
// tempFile.close(); // closes automatically when it goes out of scope
// simpler form to use myIterator.operator++():
++myIterator;
}
An even simpler approach would be to use a range-based for-loop:
for(const fs::directory_entry& dirent : fs::directory_iterator(address)) {
const fs::path& path = dirent.path();
ifstream tempFile(path);
if(!tempFile) {
cout << "Looking at file: " << path << "; failed to open.\n\n";
cin.get();
return 0;
}
std::cout << path << " opened\n";
}
So, I'm trying to create a text file that can be written to and used to seed a random number generator, but I need to be able to write to and call on the file in all of my functions. The file has to be named with the user's first and last name so I found some code that would create a text file and rename it, I'm just having trouble calling the file in my other functions. I included the beginning part of one of my other functions after the code for the text file creation. I'm going to need to send a time stamp to the file and use that time to seed my RNG.
int user_file_name()
{
string tstamp = get_timestamp();
//Creating input/output file using user's name
ofstream user_file;
string filename;
cout << "What is your first and last name?\n" << endl;
getline(cin, filename);
filename += ".txt";
cout << "Thank you, " << filename << "." << endl << endl;
user_file.open(filename.c_str());
user_file << tstamp;
user_file.close();
return 0;
}
int addition()
{
char DIFFICULTY;
difficulty_menu();
cin >> DIFFICULTY;
get_timestamp();
string tstamp = get_timestamp();
Why not just have user_file_name return the string filename instead of just an int? You can then store that filename somewhere so that other areas of your program can access it.
When the user types in a word the program is searching for a match in an array, if there is a match the program prints out the string from the array.The code below does just that. My goal is to make it so when a word matches with a a word in the array the program should print an info not only the word. I thought I can fill the array with functions, but its not working. Is it even possible ?
I am using league of legend hero names because they are a lot and I know them and it doesent take me a lot of time to think of names that way :D
The idea is if the user types in voly, the program finds voly in the array and prints out(for example) his starting life, armor, mr and so on.
I tryed a lot of thing with functions but I cant make it work.
#include <iostream>
#include <string>
using namespace std;
string voly(string holder,string heroName);
int main(){
const int numH = 10;
string holder;
string heroName;
string heroList[numH] = {"voly", "teemo", "vladimir", "morgana", "jax", "ekko", "anivia", "nunu", "ashe", "tresh" };
cout << "Enter hero name.\n" << endl;
cin >> heroName;
for (int i = 0; i < numH; i++){
holder = heroList[i];
if (heroName == holder){
cout << holder << endl;
}
}
system("PAUSE");
return 0;
}
string voly(string holder, string heroName) {
cout << "Voly is the best" << endl;
}
Try to learn about structs. You can utilize them to encapsulate all hero information in a hero struct, as follows. This serves as kind of a prototype for each hero:
struct hero {
string name;
int hp;
int mana;
float mreg;
...
void printMe() { cout << 'hp: ' << hp << endl << 'mana: ' << mana << endl << ...; }
}
Using the printMe() function of that specific hero object, you can print its values.
Then, for each hero, create a struct object and add them to the array.
hero* pointer = new hero[numH];
pointer[0] = new hero {
name: "voly",
hp: 150
};
pointer[1] = new hero {
...
};
(Try considering some import function via a .CSV file or so.)
By using your for loop, compare the name:
for (int i = 0; i < numH; i++){
if (heroName == pointer[i].name){
pointer[i]->printMe();
}
}
Try using Google to find tutorials on that. Unfortunately, I'm not quite sure about the syntax in C++, maybe someone can help me out.
Good Luck!
I want to edit the username and password according to userinput. I have a file exampless.txt whixh has default username and password values. I want to replace the values of username and password according to user input. I'm able to replace the username value. But password values doesnt get changed.
Please help.
My code is as below:
#include <iostream>
#include <fstream>
#include <sstream>
#include <string>
int main()
{
std::wstring y;
std::wstring username;
std::wstring password;
std::cout<<"enter the username:";
std::wcin>>username;
std::cout<<"enter the password:";
std::wcin>>password;
std::wstring x=L"username";
std::wstring a=L"password";
std::wfstream fp("/home/aricent/Documents/exampless.txt",std::ios::in | std::ios::out );
while(!fp.eof()) {
std::getline(fp, y);
if (y.find(x, 0) != std::string::npos) {
std::wstring z=y.substr(y.find(L"-") + 1) ;
fp.seekg( 0, std::ios::beg );
fp<<y.replace(x.length()+1, z.length(), username)<<"\n";
fp.clear();
fp.seekg( 0, std::ios::beg );
}
fp.seekg(0,std::ios::beg);
std::getline(fp, y);
if (y.find(a, 0) != std::string::npos) {
std::wstring b=y.substr(y.find(L"-") + 1) ;
fp<<y.replace(a.length()+1, b.length(), password <<std::endl;
fp.clear();
}
}
fp.close();
}
my exampless.txt file contains:
username-aaa
password-bbb
There are many reasons why your code doesn't work. Some have to do with the way you intend to do this. Some have to do with the way you actually implemented your idea.
So I suggest you simplify the code in the following way.
#include <iostream>
#include <fstream>
#include <sstream>
#include <string>
int main() {
std::wstring username;
std::wstring password;
std::cout<<"enter the username:";
std::wcin>>username;
std::cout<<"enter the password:";
std::wcin>>password;
std::wfstream fp("/home/aricent/Documents/exampless.txt",std::ios::in | std::ios::out );
if(!fp) { /* Failed to open file. do something */ }
<here you can check whether the file is already properly formatted>
if(!(fp << "username-" << username << "\npassword-" << password << "\n") {
//writing failed. Do something to handle this error (like throwing an exception)
}
fp.close();
}
So instead of reading the file contents, modifying it and writing it back to the file you can simply overwrite it with whatever you want it to contain.
This avoids (and fixes in this case) a lot of problems.
Also, your code should check for any exceptional states and handle them properly (like failing to open the file).
In your code you also check for whether the file is properly formatted (e.g. are the username and password lines already there) before writing to it. The above changes make this step redundant but if you still want this check to be done you can put it in between the two if's.
Finally I want to clear up a misconception. std::fstream maintains two separate positions into the filestream. One for reading and one for writing. To change these positions it has two methods seekp(pos) and seekg(pos). seekp(pos) changes at what position in the filestream any write operation (like operator << and put()) starts writing (the p stands for put I guess). seekg(pos) changes at what position in the filestream any read operation (like operator >> and get()) starts writing (the g stands for get).
Reading from a stream only changes the reading position but not the writing position and vice versa.
I was wondering how can I print colorful text in the console? I use eclipse win64 OS. Does it have to do with the compiler? Can anyone give a simple example in C with just a hello world text in red or whatever?
I know that this is incredibly easy to do in C++, but I found this for you to look at in C:
#include <stdio.h>
#include <windows.h> // WinApi header
int main()
{
HANDLE hConsole;
int k;
hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
// you can loop k higher to see more color choices
for(k = 1; k < 255; k++)
{
SetConsoleTextAttribute(hConsole, k);
printf("%3d %s\n", k, "I want to be nice today!");
}
getchar(); // wait
return 0;
}
All of the comments will help you to find your way through the code - hope it helps!
If you want to print colored text in Windows console, you will have to use Windows API. ANSI.sys support is no longer present in Windows.
In Linux you can still use ANSI escape sequences to color text.
You can use ANSI escape sequence on Windows as well with the following modification:
reg add HKEY_CURRENT_USER\Console /v VirtualTerminalLevel /t REG_DWORD /d 0x00000001 /f
example:
int main()
{
printf("\033[33mThis is yellow\033[0m");
return 0;
}
source:
https://www.codeproject.com/Tips/5255355/How-to-Put-Color-on-Windows-Console
If you are constrained to using just printf(), this requires knowledge of the terminal to which you're writing. The chances are it is an ANSI-style terminal, so it can be done. The Unix curses (Linux ncurses) library handles such information in a terminal-independent way. Basically, you will need to define or manufacture control strings to turn the terminal into red mode and then reset it back again (but how do you know what state it was in before you changed it to writing red text?). The libraries mentioned keep track of the state information, amongst many other details.
However, if you get the strings organized, then code like this will do the trick (more or less):
static const char to_red[] = "\033...";
static const char to_black[] = "\033...";
printf("%s%s%s\n", to_red, "hello world", to_black);
The hard part is determining what goes in the constant strings (which need not actually be constant).
All this means there is probably a Windows-specific interface that can be used to do the job, but that does not really involve printf() for controlling the colours; you call the Windows API to set the colour, then write with printf(), then call the API again to reinstate the colour. There is probably a query function to allow you to find the current setting, which you use before changing it.
The console in Java uses stdout which is whatever OS you are running on. For Windows, you would need to access the Console API to change the colours. For Linux or Mac, the console might support ANSI escape sequences which can change the console colours via stdout.
Here's a further example for you. It is in C++, but I'm sure you can handle that; but I do also have the exact same code in this example in python. It's a small demo I wrote to end up drawing some lines in colors.
Anyway the series of demos is at:
https://github.com/goblinhack/c-plus-plus-python-tutorial
With the full source for the below example at:
https://github.com/goblinhack/c-plus-plus-python-tutorial/blob/master/lesson1/lesson1.cpp
The C++ code for the above picture is using the Ansi color class I define in the lesson1.cpp. But once you use that, it's very simple to use. hth.
int main (int argc, char *argv[])
{
Ansi ansi;
std::cout << ansi.get_code(ansi.FOREGROUND_RED);
std::cout << "hello ";
std::cout << ansi.get_code(ansi.FOREGROUND_GREEN);
std::cout << "beautiful";
std::cout << ansi.get_code(ansi.RESET);
std::cout << ansi.get_code(ansi.FOREGROUND_CYAN);
std::cout << " colorful";
std::cout << ansi.get_code(ansi.RESET);
std::cout << ansi.get_code(ansi.FOREGROUND_BLUE);
std::cout << " world";
std::cout << ansi.get_code(ansi.RESET);
std::cout << std::endl;
return (0);
}
With similar ability in python
def lesson1():
""" hello beautiful world """
ansi = Ansi()
for bg_col in range(ansi.Code.BACKGROUND_BLACK,
ansi.Code.BACKGROUND_WHITE):
for fg_col in range(ansi.Code.FOREGROUND_BLACK,
ansi.Code.FOREGROUND_WHITE):
sys.stdout.write("{0: <20} {1: <20}".format(\
ansi.get_code_name(bg_col),
ansi.get_code_name(fg_col)))
sys.stdout.write(ansi.get_bgfg_code(bg_col, fg_col))
sys.stdout.write("colorful")
sys.stdout.write(ansi.get_code(ansi.Code.RESET))
print()
sys.stdout.write(ansi.get_code(ansi.Code.FOREGROUND_RED))
sys.stdout.write("hello")
sys.stdout.write(ansi.get_code(ansi.Code.FOREGROUND_GREEN))
sys.stdout.write(" beautiful")
sys.stdout.write(ansi.get_code(ansi.Code.FOREGROUND_CYAN))
sys.stdout.write(" colorful")
sys.stdout.write(ansi.get_code(ansi.Code.FOREGROUND_BLUE))
sys.stdout.write(" world")
sys.stdout.write(ansi.get_code(ansi.Code.RESET))
print("from Python")
lesson1()