We help IT Professionals succeed at work.

system() return values

RunBoris
RunBoris asked
on
I have a function that copies various files using SYSTEM(copyThisFile). When the functions attempts to copy, the cmd Prompt will either say "1 file(s) copied." or give an error. What I would like to do, if possible, is something like this:

if "1 file(s) copied" then suppress system message, successCounter++
else display "FileName failed to copy: " + "system failure message", failureCounter++

So if text1.txt copies successfully, the screen shows nothing. If text2.txt fails, the screen displays "text2.txt failed to copy: The source file and destination file are the same."
Comment
Watch Question

evilrixSenior Software Engineer (Avast)
SILVER EXPERT

Commented:
http://www.experts-exchange.com/Programming/Languages/CPP/Q_23113993.html#discussion
#include <io.h>
#include <cstdlib>
#include <iostream>
#include <fstream>
#include <string>
#include <stdexcept>
 
 
void copy_file(std::string const & sOldPath, std::string const & sNewPath, bool bOverWrite = false)
{
	if(!bOverWrite && (0 == access(sNewPath.c_str(), 0x00))) { throw std::runtime_error("Output file already exists"); }
 
	std::ifstream ifs(sOldPath.c_str(), std::ios::binary);
	if(!ifs.is_open()) { throw std::runtime_error("Unable to open input file"); }
 
	std::ofstream ofs(sNewPath.c_str(), std::ios::trunc | std::ios::binary);
	if(!ofs.is_open()) { throw std::runtime_error("Unable to open output file"); }
 
	ifs.seekg(0, std::ios::end);
	std::ifstream::pos_type size = ifs.tellg();
	ifs.seekg(0);
 
	std::string sData(size, std::string::value_type());
 
	ifs.read(&sData[0], size);
	if(!ifs.good()) { throw std::runtime_error("Unable to read input file"); }
 
	ofs.write(sData.data(), size);
	if(!ifs.good()) { throw std::runtime_error("Unable to write output file"); }
}
 
int main()
{
	int nRetval = 0;
 
	try
	{
		std::string sOldPath = "c:\\temp\\test.txt";
		std::string sNewPath = "c:\\temp\\newtest.txt";
 
		copy_file(sOldPath, sNewPath);
 
		std::cout << "Copied " << sOldPath << " to " << sNewPath << " successfully." << std::endl;
	}
	catch(std::exception const & ex)
	{
		std::cerr <<"Error. " << ex.what() << std::endl;
		nRetval = -1;
	}
 
#ifdef WIN32
	system("pause"); // Only works on Windows
#endif
 
	return nRetval;
}

Open in new window

Senior Software Engineer (Avast)
SILVER EXPERT
Commented:
The code above was posted to your previous thread but then I saw you'd opened this one to discuss exactly the issue I raised in the previous thread. As you can see the code above will do the file copy for you programmatically. It has no reliance on system commands and as such (a) gives you better control and (b) is not platform specific.

NB. I've tested the code using my own test sample and it worked file; however, if you do decide to use this code you should test it thoroughly before putting it into a production environment.

>> if "1 file(s) copied" then suppress system message, successCounter++
Change line 43 to be "++ successCounter"

>> else display "FileName failed to copy: " + "system failure message", failureCounter++
Change line 47 - 48 to be "++ failureCounter"

Note, you should prefer pre-increment (++x) to post-increment (x++) as it's more efficient. The reason why is that for post increment the compiler must generate a temporary (it takes a copy, increments the value and the returns the copy), which not necessary in pre-increment (it increments and returns the incremented value). The truth is, this isn't really a problem with intrinsic types (such as int, long etc)  but it can be a big problem when working with user defined types. Basically, it's a good idea to get into the habit so you don't need to think about it. Only use post-increment when you specifically need those semantics.

I hope this helps.

-Rx.

Author

Commented:
I wish I had seen your solution prior to accepting the answer on the other question. Thanks!

Explore More ContentExplore courses, solutions, and other research materials related to this topic.