I'm trying to make a program that moves a file (like file.txt) specified by the user to a directory that he also specifies. I tried using the move() function, however I don't quite understand it yet, so I tried with the rename() function and used this site's code as help.
I've worked with the rename() function and moved a file like this:
char oldDir[] = "C:\\Users\\MyName\\file.txt";
char newDir[] = "C:\\Users\\MyName\\New folder\\file.txt";
if (rename(oldDir, newDir) != 0)
perror("Error moving file");
else
cout << "File moved successfully";
And that worked perfectly, if I typed in the directory correctly. The thing is that I would like to tell the user to type in the directory of a file to move to another directory, so I tried this:
char oldDir[] = " ";
char newDir[] = " ";
cout << "Type file directory: "; cin >> oldDir;
cout << "Type file directory to move to: "; cin >> newDir;
if (rename(oldDir, newDir) != 0)
perror("Error moving file");
else
cout << "File moved successfully";
But, when typing in the console the oldDir path like: C:\\Users\\MyName\\file.txt, I always get the error:
Error moving file no such file or directory
It returns before I can even type the newDir path. Of course the file.txt is in C:\Users\MyName.
What could be the problem? I tried to remove the " " from the oldDir and newDir variables, but then I get another error:
incomplete type is not allowed
What am I doing wrong?
First off, don't double up on the slashes when typing them in at the command prompt at runtime, if that is what you are doing. Escaping slashes only applies to string literals in code, not runtime data.
That said, you are not allocating enough memory to hold the user's input. When initialized with " ", your oldDir[] and newDir[] arrays are each only 2 chars in size. When you drop the " ", the compiler no longer knows how large to make the array, since you are not telling it which size to use.
You need to handle the arrays more like this instead:
char oldDir[MAX_PATH] = "";
char newDir[MAX_PATH] = "";
std::cout << "Type file directory: ";
cin.getline(oldDir, MAX_PATH); // paths can contain spaces!
std::cout << "Type file directory to move to: ";
cin.getline(newDir, MAX_PATH); // paths can contain spaces!
if (rename(oldDir, newDir) != 0)
perror("Error moving file");
else
std::cout << "File moved successfully" << std::endl;
However, you really should be using std::string instead:
std::string oldDir, newDir;
std::cout << "Type file directory: ";
std::getline(cin, oldDir); // paths can contain spaces!
std::cout << "Type file directory to move to: ";
std::getline(cin, newDir); // paths can contain spaces!
if (rename(oldDir.c_str(), newDir.c_str()) != 0)
perror("Error moving file");
else
std::cout << "File moved successfully" << std::endl;
If you are using C++17 or later, consider using std::filesystem::rename() instead of ::rename():
#include <filesystem>
std::string oldDir, newDir;
std::cout << "Type file directory: ";
std::getline(cin, oldDir); // paths can contain spaces!
std::cout << "Type file directory to move to: ";
getline(cin, newDir); // paths can contain spaces!
std::error_code err;
std::filesystem::rename(oldDir, newDir, err);
if (err)
std::cerr << "Error moving file: " << err.message() << endl;
else
std::cout << "File moved successfully" << std::endl;
Related
I am new at C/C++,
So basically I want to call an .exe file that displays 2 numbers and be able to grab those two numbers to use them in my code.
To call the .exe file I've used the system command, but I am still not able to grab those two numbers that are displayed by the .exe file
char *files = "MyPath\file.exe";
system (files);
I think this is better aproach:
Here you just create new process, and you read data that process gives you. I tested this on OS X 10.11 with .sh file and works like a charm. I think that this would probably work on Windows also.
FILE *fp = popen("path to exe","r");
if (fp == NULL)
{
std::cout << "Popen is null" << std::endl;
}else
{
char buff[100];
while ( fgets( buff, sizeof(buff), fp ) != NULL )
{
std::cout << buff;
}
}
You need to escapr back slashes in C++ string literals so:
// note the double "\\"
char* files = "MyPath\\file.exe";
Or just use forward slashes:
char* files = "MyPath/file.exe";
Its not very efficient but one thing you can to with std::system is redirect the output to a file and then read the file:
#include <cstdlib>
#include <fstream>
#include <iostream>
int main()
{
// redirect > the output to a file called output.txt
if(std::system("MyPath\\file.exe > output.txt") != 0)
{
std::cerr << "ERROR: calling system\n";
return 1; // error code
}
// open a file to the output data
std::ifstream ifs("output.txt");
if(!ifs.is_open())
{
std::cerr << "ERROR: opening output file\n";
return 1; // error code
}
int num1, num2;
if(!(ifs >> num1 >> num2))
{
std::cerr << "ERROR: reading numbers\n";
return 1; // error code
}
// do something with the numbers here
std::cout << "num1: " << num1 << '\n';
std::cout << "num2: " << num2 << '\n';
}
NOTE: (thnx #VermillionAzure)
Note that system doesn't always work everywhere because unicorn
environments. Also, shells can differ from each other, like cmd.exe
and bash. – VermillionAzure
When using std::system the results are platform dependant and not all shells will have redirection or use the same syntax or even exist!
Okay guys, I've tried everything I can think of. I'm passing in a file name into this function. A little context: hash_table is an already initialized and filled vector with key pairs, and the 'value' part of the pair is a Linked List that has the field "bucket_size". When I use cout to check if these fields are actually being accessed, they are; even the debugger lists them as being filed into the output stream. I have flush() and close() in there, but it doesn't write anything to the file. Returns true, indicating no errors in the stream. Anyone have nay ideas?
string line;
std::ofstream ofs;
if(ofs.is_open())
ofs.close();
ofs.open(filename);
if (ofs.is_open())
{
cout << "File Opened" << endl;
for (double i = 0; i < hash_table.capacity(); ++i)
{
ofs << "Bucket Number " << i;
if (hash_table[i].value != NULL)
ofs << " Bucket Size: " << hash_table[i].value->bucket_size << endl;
else
ofs << " Bucket Size: 0" << endl;
ofs.flush();
}
cout << "closing file stream" << endl;
ofs.flush();
ofs.close();
if (ofs.good())
return true;
else
return false;
}
else
{
cout << "File not opened" << endl;
return false;
}
}
You're almost certainly examining the wrong file. Remember that relative paths are relative to the working directory of the process, which is not necessarily the same as where the executable lives on disk.
I compiled and ran it by the console and now it works, with no edits made. It seems my IDE doesn't like something in the code. Regardless, thank you everyone for the response.s
I am trying to run the following program:
#include <iostream>
#include <fstream>
using namespace std;
int main()
{
ifstream inFile;
ofstream outFile;
double first=1.49, second=2.59, third=3.69, fourth=4.79;
inFile.open("prices.txt");
char response;
if(!inFile.fail())
{
cout << "A file by the name prices.txt exists.\n" << "Do you want to continue and overwrite it\n" << " with the new data (y or n);"; cin >> response;
if(tolower(response) == 'n')
{
cout << "The existing file will not be overwritten." << endl;
return -1;
}
}
outFile.open("prices.txt");
if (inFile.fail())
{
cout << "\n The file does not exist and can not be opened" << endl;
cout << "The file has been successfully opened for output." << endl;
outFile << first << "\n" << second << "\n" << fourth << "\n" << endl;
outFile.close();
exit(1);
cout << "The file has been successfully opened for output. " << endl;
outFile << first << "\n" << second << "\n" << third << "\n" << fourth << endl;
outFile.close();
return 0;
}
}
Yet this program will not write the values to the prices.txt file. If you run the program once it says the file does not exist. Running it a second time says the file is already there and if you want to overwrite it. The thing is searching my Mac I cannot find this file anywhere.
Any ideas what I am doing wrong with running it in Xcode? A friend runs the exact same code in Visual Studio 2008 and it works. Any help is appreciated.
You need to set the working directory for the executable since you are assuming that your data files are in the current working directory. In Xcode 3.x you set this in the first tab of Get Info for the executable. In Xcode 4.x it has been moved, but the principle is the same.
Alternatively you can change your data file paths (e.g. make them absolute) so that you do not make assumptions about the current working directory.
You may not have permission to write into the directory that you are trying to save the file too.
Also, there is an error in your program and I am sure if it is there for debugging reasons. You have
outFile.close();
exit(1);
But then shortly there after you try to write to the file, then close it again.
I am having some trouble with sprintf and fstream functions in order to create new text files for a POS program/check whether the file already exists. I don't know if i am doing something wrong because the same set of functions works fine in other places in my code...
This particular section of code is taking input from the user to create a details file, the name is made up of the first and last name details that were entered into the system. For some reason the new file is not being created. When I step through the program I can see that the custDetC variable is being filled with the correct data. I have also included the file existence check as it may or may not have something to do with the issue at hand...
Tony Mickel
sprintf(custDetC,"%s%s.txt", firstName.c_str(), lastName.c_str());
cout << custDetC << endl;
FileEX = FileExists(custDetC);
if (FileEX == true)
{
fopen_s(&custDetF,custDetC, "rt");
fprintf(custDetF, "%s %s\n", firstName, lastName);
fprintf(custDetF, "$d\n", phoneNo);
fprintf(custDetF, "%s $s\n", unitHouseNum, street);
fprintf(custDetF, "%s %s %d", suburb, state, postCode);
fclose(custDetF);
}
else
{
char *buf = new char[100];
GetCurrentPath(buf);
cout << "file " << custDetC << " does not exist in " << buf << endl;
}
}
bool FileExists(char* strFilename)
{
bool flag = false;
std::fstream fin;
// _MAX_PATH is the maximum length allowed for a path
char CurrentPath[_MAX_PATH];
// use the function to get the path
GetCurrentPath(CurrentPath);
fin.open(strFilename, ios::in);
if( fin.is_open() )
{
//cout << "file exists in " << CurrentPath << endl;
flag = true;
}
else
{
//cout << "file does not exist in " << CurrentPath << endl;
flag = false;
}
fin.close();
return flag;
}
You seem to be opening the file for reading, but you need to open it for writing.
Instead of "rt" use "wt" in fopen_s()
For some reason, Xcode will not take input from a file, while Visual C++ will.
When I run this program in xcode, the variables numberRows and numberCols stay 0 (they are initialized to 0 in the main function).
When I run it in Visual C++ they become 30 and 30 (the top line of maze.txt is "30 30" without the quotes).
Any ideas why this is happening?
void readIn(int &numberRows, int &numberCols, char maze[][100]){
ifstream inData;
inData.open("maze.txt");
if (!inData.is_open()) {
cout << "Could not open file. Aborting...";
return;
}
inData >> numberRows >> numberCols;
cout << numberRows << numberCols;
inData.close();
return;
}
There is something else wrong.
Unfortunately it is hard to tell.
Try flushing the output to make sure you get the error message:
void readIn(int &numberRows, int &numberCols, char maze[][100])
{
ifstream inData("maze.txt");
if (!inData) // Check for all errors.
{
cerr << "Could not open file. Aborting..." << std::endl;
}
else
{
// Check that you got here.
cerr << "File open correctly:" << std::endl;
// inData >> numberRows >> numberCols;
// cout << numberRows << numberCols;
std::string word;
while(inData >> word)
{
std::cout << "GOT:(" << word << ")\n";
}
if (!inData) // Check for all errors.
{
cerr << "Something went wrong" << std::endl;
}
}
}
interesting, so I followed the following suggestion from this post http://forums.macrumors.com/showthread.php?t=796818:
Under Xcode 3.2 when creating a new
project based on stdc++ project
template the target build settings for
Debug configuration adds preprocessor
macros which are incompatible with
gcc-4.2:
_GLIBCXX_DEBUG=1
_GLIBXX_DEBUG_PEDANTIC=1
Destroy them if you want Debug/gcc-4.2
to execute correctly.