C++ removing file with filesystem library doesn't work - c++

I have a russian Roulette script written with C++. If two randomly generated numbers are the same, the script deletes a specified file.
People suggested to me that I should use C++17 for using the <filesystem> library in order to run file-related operations correctly. The removing operation runs if the conditions are matching. The if block runs correctly, but removing the file isn't happening.
#include <iostream>
#include <cstdlib>
#include <stdio.h>
#include <filesystem>
//include filesystem and replace remove() with filesystem libs remove function
using namespace std;
namespace fs = std::filesystem;
int main(){
int minNumber = 1, maxNumber = 6;
int possibility,chamberNumber;
srand(time(0));
possibility = rand() % (maxNumber - minNumber + 1 ) + minNumber;
chamberNumber = rand() % (maxNumber - minNumber + 1 ) + minNumber;
cout << "First Number: " <<possibility<<endl<<"Second Number: " << chamberNumber<< endl;
if (possibility == chamberNumber){
std::filesystem::remove("C:\\Users\\mypath\\Desktop\\cppRoulette\\delete.txt");
cout << "You're Dead " <<possibility<< endl;
}
// else{
// cout << possibility << endl;
// }
return 0;
}
I use this line to compile my code:
g++ -std=c++17 rulet.cpp -o output
Here is a screenshot of the compiled output. Notice "delete.txt" still stands.
I am using WSL Debian, because I am using VS Code and native terminals don't work proper with g++. I may like smoothness of Linux a bit more, though.
I am looking for a proper and easier way to deal with files, just like in Python. I am attending a C++ crash course, so I am trying to learn it, switching to Python isn't on the table.

Your file path is wrong. I just got your code to work on my system by changing the path from E:\Test\delete.txt to /mnt/e/Test/delete.txt.
Under WSL, all Windows drives (C:, E:, etc.) are mounted under the /mnt directory, in subdirectories that match the drive letter (/mnt/c/, /mnt/e/, etc). In order to convert your Windows path for use in WSL, you need to do the following:
Replace all backslashes (\) with forward slashes (/).
Remove the colon (:) after the drive letter.
Convert the drive letter to lower case.
Prepend the string "/mnt/" to the path.
After this, your program works, and will delete the target file.

Related

How to build your own CMD using C++?

Recently I want to enhance CMD in Win10 by myself using C++. I don't want to change the original framework of it but to translate the command. At first i wrote something like this:
#include <unistd.h>
#include <iostream>
#include <string>
using namespace std;
int main()
{
string initial = "retr0# ";
string s;
while(1)
{
cout << initial;
getline(cin,s);
if(s!="exit")
{
system(s.c_str());
cout << "------" << endl;
}
else break;
}
system("pause");
return 0;
}
But I found that if you entered command like "E:" or something else to change the directory, it is impossible for the new thread to inherit the context. My question is, how to solve the problem like this?
In most operating systems (including 1970 era Unix), the working directory is specific to each process.
The system function will run another process. So even if you change its working directory, it only affects the process started by system, not the process running your program.
So you need to define a syntax (perhaps the same cd as Windows CMD has) and parse and implement that command in your own program. You could use SetCurrentDirectory or _chdir

Somthing of bad understanding in "SetCurrentDirectory" ("windows.h") in CPP

I don't know what's happened here. Here is the code sample:
#include<stdio.h>
#include<iostream>
#include<string>
#include <Windows.h>
using namespace std;
int main()
{
char my_current_path[1024];
string current_path(R"(C:)");
if (!SetCurrentDirectory(current_path.c_str()))
cout << "cant change to that directory.";
GetCurrentDirectory(1024, my_current_path);
std::cout << my_current_path << endl;
system("pause");
return 1;
}
What I'm doing here is trying to change the directory to some directories.
There is two strange things with my code.
(1 Strange thing)
When I try to change to "c:" like that:
#include<stdio.h>
#include<iostream>
#include<string>
#include <Windows.h>
using namespace std;
int main()
{
char my_current_path[1024];
string current_path(R"(C:)");
if (!SetCurrentDirectory(current_path.c_str()))
cout << "cant change to that directory.";
GetCurrentDirectory(1024, my_current_path);
std::cout << my_current_path << endl;
system("pause");
return 1;
}
It's not working and not changing the path (and its the good thing.) but its not show me the message that shown when the directory isn't changed:
cout << "cant change to that directory.";
Why is that? (When I try to change something like "efef:" or "exist?" it is showing me that's messege. But Why here it doesn't show me, and also doest change the current working directory?
(Second Strange thing)
When I change the directory to "G:" Its for some reason working..
#include<stdio.h>
#include<iostream>
#include<string>
#include <Windows.h>
using namespace std;
int main()
{
char my_current_path[1024];
string current_path(R"(G:)");
if (!SetCurrentDirectory(current_path.c_str()))
cout << "cant change to that directory.";
GetCurrentDirectory(1024, my_current_path);
std::cout << my_current_path << endl;
system("pause");
return 1;
}
That code compiled, showing that I successfully changed the directory to "G:".
After changing to that path, I'm trying to change to "C:" (Which before, didn't did anything) and now its working! but in strange way, its not moving to "C:\" But to:
C:\Program Files (x86)\Microsoft Visual Studio 12.0\Common7\IDE
And its weird that before its not worked, and now when I'm in "G:" path and trying to move to "c:" again, then its move to path that I didn't even wanted!
If you want to specify the root directory on a drive, you must include a backslash, i.e., C:\.
The syntax you are using, C:, has a different meaning. The command shell separates the concepts of the current drive and the current directory on each drive, so that you can switch between drives quickly without having to retype the full path each time. This feature was introduced (a long time ago) for backwards compatibility reasons (see below) but is actually very useful; power users will sometimes map multiple drive letters to the same drive or network share specifically in order to take advantage of this functionality.
Although only the command shell keeps track of the current directory for each drive, the Win32 API knows how to look them up, and does so whenever you specify a drive but no path. As a special case, if the drive specified is the current drive, it expands to the actual current directory rather than the saved current directory.
So in your example the incomplete path C: is expanded to the current directory for the C drive; since your current directory is already on the C drive, SetCurrentDirectory(R"(C:)") is a no-op. If you want to change to the root directory, you should use SetCurrentDirectory(R"(C:\)") instead.
In your testing, there was no saved current directory for the G: drive, and it was not the current drive, so the effect was to set the current directory to G:\, i.e., you got the behaviour you expected but not for the reason you were expecting. If you had launched the program from the command shell and a current directory had been saved for the G drive, you'd have wound up there instead.
The same thing applies to opening files; C:file.txt will open file.txt from the current directory for the C drive, whereas C:\file.txt will open file.txt from the root directory.
See Raymond Chen's blog post, Why does each drive have its own current directory? for a discussion of the history of this feature.
you can use the two APIs for retrieving and setting the current directory: GetCurrentDirectory() and SetCurrentDirectory() only provide a valid path for the latter:
#include <iostream>
#include <windows.h>
using namespace std;
int main()
{
char czCurDir[MAX_PATH] = "";
char czNewDir[MAX_PATH] = "";
// retrieve the current directory
GetCurrentDirectory(MAX_PATH, czCurDir);
cout << "Current directory: " << czCurDir << endl;// C:\Users\Raindrop7\Desktop\New folder
// set the value for the new directory NB: C:\\ not C:\ because the first backslah is an escape character
strcpy(czNewDir, "C:\\");
// set the current directory to "C:\"
SetCurrentDirectory(czNewDir);
// retrieve the current directory
GetCurrentDirectory(MAX_PATH, czCurDir);
cout << "current directory: " << czCurDir << endl;// C:\
return 0;
}
First change drive to single F or G drive-
Example::
if( !SetCurrentDirectory("F:") )
{
cout <<"can't open the directory"<< endl;
}
then give full path-
Example::
if(!SetCurrentDirectory("F://Python_Django_Webdevelopment//StudentManagement"))
{
cout <<"can't open the directory"<< endl;
}
It works for me.

Having trouble processing a file from my documents in my code?

I have searched for this around the web and here but I can't seem to figure out what I am doing wrong.
I am simply trying get better with file processing and c++.
For practice I am trying to grab a text file from a game folder and make a copy of it.
Here is my code (that can't access the file).
#include <fstream>
#include <iostream>
#include <string>
using namespace std;
int main()
{
//define / open files
ifstream my_input_file;
ofstream my_output_file;
string filepath = "C:/Users/David Laptop/Documents/my games/oblivion/RenderInfo.txt";
my_input_file.open(filepath);
if (my_input_file.is_open())
{
cout << "opened\n";
my_output_file.open("output_file.txt", ofstream::trunc);
char c;
my_input_file.get(c);
while (my_input_file)
{
my_output_file.put(c);
my_input_file.get(c);
}
my_input_file.close();
my_output_file.close();
}
else
{
cout << "FAIL\n";
}
cin.get();
return 0;
}
This seemed to work with both text files and .ini files when in the project directory but I am having issues properly getting to other directiorys?
Any ideas?
thanks!
Your code is perfectly valid and it works - I tried it with my own file instead of yours, in the line
string filepath = "C:/Users/David Laptop/Documents/my games/oblivion/RenderInfo.txt";
So you have not such file or it is not in the given path or you have not such path.
Correct it in that line and it will be OK.
Tip: Find your file in Windows Explorer, press (and keep pressing) Shift) and right-click on this file. From the context menu then choose Copy as path and then paste it to your code. But be carefull - you have to change every backslash (\) to a forward slash (/) (as in your code) or use double backslashes (\\) instead of a single one.

How to use file strings as commands in c++

I am trying to make a program on Windows 10 using Visual Studio 2015 that would sim-link certain files to certain locations. I am trying to make a text file with the location of the files, and the sim-link destination to use.
This is an example of the file data that would be in the properties.txt file:
FileLocation: "Z:\Folder\file.txt"
FileMkdirLocation: "Z:\Folder2\file.txt"
I want to use something like system(mkdir "sim-link_file_location" "file_location") by changing the data that is in properties.txt. I want to be able to add more than 1 file, without recompiling the program and writing each command for each file, one by one.
The problem is that I don't know how to make the commands use the data in the file.
EDIT: I managed to find out a way, but I get errors when compiling the program. I use this code:
#include <iostream>
#include <fstream>
#include <string.h>
#include <stdlib.h>
using namespace std;
//initialization of Properties File used
ifstream PropertiesFile ("PropertiesFile.txt");
int main()
{
//initialization of variables used
int input_option;
char FileLocation[256], Command[]="mklink ";
// string FileLocation, Command;
PropertiesFile >> FileLocation;
/* switch (input_option)
{
case "add all mods":
}
*/
cout << "FileLocation: " << FileLocation;
cout << endl;
strcat(Command, FileLocation);
Command[strlen(FileLocation)] = '\0';
cout << Command;
cout << endl;
//system(command);
system("pause");
return 0;
}
I know that i haven't used all variables yet.
It tells me that "strcat" is deprecated and to use "strcat_s" instead, and when i replace it with that, I get
"Debug Assertion Failed - Expression: (L"Buffer is too small" && 0)"
I had to make the "Command" char bigger than "FileLocation" because then strcat_s would not be able to copy the content. After that the program worked fine, and there were no other Assert Errors.
The command to create a soft link in linux is: ln -s <source> <destination>
You can use this in a system(""); call, BUT before you continue in your code, you will have to make sure that the kernel finished executing this command.
After that you can read the link as if it was the original file.

Unable to open file.txt with c++

I've looked up similar posts here, but none seem to be doing the job for my question. I'm basically trying take a sequence of words in a .txt file and put each word in a vector, and printing each value afterwards. For example, we have I love racing cars in array.txt, and I want my vector to have "I" at position 0, "love" at 1 and so on. Unfortunately, the code does not access "array.txt", so it never executes the code in the if condition.
Now I've heard that by using the fstream library it should work just fine, but the file is never found. I suspect that it doesn't work because it cannot find the path, but I have never opened files in C++. Also, I have not put my file anywhere in my project folder.
Some changes I've already tried:
file.open("array.txt");
omitting file.close();
include "C:\array.txt"; (with the # in front)
file.open("C:\array.txt")
And I'm using Windows 10, if this matters.
#include <iostream>;
#include <string>;
#include <vector>;
#include <fstream>;
//#include <"C:\Users\Samer El-Hage\Documents">;
using namespace std;
void main(){
vector<string> v (10);
ifstream file;
file.open("C:\array.txt", ios::in);
if (file.is_open())
{
for (int i = 0; i < 3; i++)
{
file >> v[i];
}
file.close();
}
else cout << "Could not access file.";
for (int i = 0; i < 3; i++)
{
cout << v[i] << " ";
}
}
This code prints "Could not access file."
The file cannot be opened because the file system can't find the file named "[Bell]rray.txt". the character sequence '\a' is the "Make my computer Beep" character.
Use either forward slashes: "C:/array.txt", an escaped backslash: "C:\\array.txt" or a raw string literal: R"(C:\array.txt)"
The file must also exist at the specified location. If you do not provide a drive and just say "array.txt" the location defaults to wherever the executable is (or in an IDE, the Working Directory).
Also, you have unnecessary semi-colons after your includes. (In fact, in a Treat Warnings as Errors setup, this won't compile!)
I got it! I had not put the .txt file in my folder with the source code, which, strangely enough, was not mentioned in my previous search results... I got to search better!
\a simply turns the computer beep on. Try writing "C:\\array.txt" instead in the open call.
Try not calling open explicitly:
ifstream file ("array.txt");
Look at the examples here:1