I found that when I use more than two user inputs, the program will immediately exit after the third.
Is there a way I can stop this?
Printable View
I found that when I use more than two user inputs, the program will immediately exit after the third.
Is there a way I can stop this?
What's the code?
Haha, it's about 11 KB. I'll quickly try to make an example program, because I've seen it happen before.
O_o
I think we could cope with 500 lines.
Soma
No one has time for that. Make the simplest compilable program that demonstrates the problem.Quote:
O_o
I think we could cope with 500 lines.
Soma
...ok, just 3 cins worked fine.
So, here's the source. I discovered the problem when using my --emulate command, I tried --format, which worked fine on its own, but here it just stopped. And I seem to recall having a simmilar issue before.
Edit: running --emulate on any command will shut it down after you've stated your command (ex: --in), then done an input.
Code:#include <iostream>
#include <string>
#include <vector>
#include <stdlib.h>
#include <fstream>
#include <ctime>
using namespace std;
//Function EditPathIn
void EditPathIn ()
{
string new_path_in ; //variable
cout << "Type the filepath of where you want back up. Be sure to end it with a / !\n";
cin >> new_path_in ;
ofstream path ;
path.open (".backup_prefs/path_in") ;
path << new_path_in ;
path.close() ;
}
//Function EditPathOut
void EditPathOut ()
{
string new_path_out ; //variable
cout << "Type the filepath of where you want to store your backup. Be sure to end it with a / !\n";
cin >> new_path_out ;
ofstream path ;
path.open (".backup_prefs/path_out") ;
path << new_path_out ;
path.close() ;
}
//Function EditFormat
void EditFormat ()
{
string new_format_short ; //variable
string new_format_full ; //Expanded form
cout << "Enter the letter representing the format you want to use.\n\n";
cout << "t Gzipped tar (.tar.gz), for average compression.\n" ;
cout << "z Zip (.zip), for low compression.\n" ;
cout << "7 7zip (.7z), for high compression.\n" ;
cout << " High compression formats take longer.\n" ;
cin >> new_format_short ;
if ( new_format_short == "t" ) {
new_format_full = "tar" ;
}
if ( new_format_short == "z" ) {
new_format_full = "zip" ;
}
if ( new_format_short == "7" ) {
new_format_full = "7z" ;
}
ofstream format ;
format.open (".backup_prefs/format") ;
format << new_format_full ;
format.close() ;
//Record new format to log
ofstream appendlog ("./.backup_prefs/log", ios::app );
if (appendlog.is_open()) {
appendlog << " to " ;
appendlog << new_format_full ;
appendlog << " at " ;
appendlog.close();
}
}
//Main
int main( int argc, char** argv )
{
time_t now; //Time
struct tm *d; //Time
char li [13]; //Time
vector <string> args( argv, argv+argc ) ;
string arg_input; //For checking -xyz type options
int search_for_option = 0; //WTF are fluxes?
int multiple_formats = 0 ;
string emulated_args = "nothing" ;
char yesno ; //For y/n
string io_select ;
int include_hidden_files = 0 ;
int options_present = 0 ;
string archive_type = "tar" ;
string options_to_terminal ;
string settings_outpath ;
string settings_inpath ;
string line_outpath ;
string line_inpath ;
string line_format ;
string date ; //User entered date
string extension = ".tar.gz" ;
string path_in = "~/" ;
string astrisk ; //Adds an astrisk (all) if called.
string exclude_hidden_files = "-X .*" ; //Excludes all .* (hidden) files
string final_command ;
Start:; //A goto
//Get dd-mm-yyyy
time(&now);
d = localtime(&now);
strftime(li, 15, "%d-%m-%Y", d);
date = li ;
//Find preferences
ifstream log (".backup_prefs/log");
if (log.is_open()) {
cout << "Found preferences directory.\n\n" ;
}
else {
system ( "mkdir ~/.backup_prefs" ) ; //Make directory (assuming that no log = no directory)
ofstream mklog ;
mklog.open (".backup_prefs/log") ;
mklog << "Creating log: " ;
mklog << date ;
mklog << ".\n\n\n" ;
mklog.close() ;
}
//Load preferences
//Path in
ifstream in(".backup_prefs/path_in") ;
while(getline(in,line_inpath))
path_in += line_inpath ;
//Path out
ifstream hi(".backup_prefs/path_out") ;
while(getline(hi,line_outpath))
settings_outpath += line_outpath ;
//Format
ifstream format(".backup_prefs/format") ;
while(getline(format,line_format))
archive_type = line_format ;
if ( emulated_args != "nothing" ) { //If it is an emulated run
arg_input = emulated_args ;
}
if ( argv[1] && emulated_args == "nothing" ) {
arg_input = argv[1]; //Gives string arg_input the contents of argument 1, ONLY IF there is an argument 1.
//Without the if, segfault.
}
//If not normal run ( backup <something else> ), check the <something else>.
if (args.size() > 1) {
//If --help
if ( arg_input == "--help" ) {
cout << "\n"
"Usage: backup [option(s)/function]\n"
"Options are written as -xyz. You can append as many options as you want.\n"
"Functions are written as --name, and exit after running.\n\n"
"Options:\n"
" -i Backs up user-defined location instead of default.\n"
" -h Includes hidden files .\n"
" -o Sends to user-defined location instead of default.\n"
" -z Uses .zip instead of .tar.gz . Is less efficiant, but is supported everywhere.\n"
" -7 Uses .7z instead of .tar.gz . 7zip takes longer, but produces a smaller file.\n"
"\n"
"Functions:\n"
" --emulate Treat the next input as if it was argument 1. Use backup --emulate on launchers.\n"
" --format Change the default archive format.\n"
" --in Edit input location.\n"
" --help Opens this index.\n"
" --out Edit output location.\n"
"\n" ;
ofstream appendlog ("./.backup_prefs/log", ios::app );
if (appendlog.is_open()) {
appendlog << "--help" ;
appendlog << " at " ;
appendlog << date ;
appendlog << ".\n\n" ;
appendlog.close();
}
goto End; //NO NOT GOTO
//THE VELOCIRAPTORS
}
//If --emmulate
if ( arg_input == "--emulate" ) {
//State emulation in log
ofstream appendlog_emulate ("./.backup_prefs/log", ios::app );
if (appendlog_emulate.is_open()) {
appendlog_emulate << "Runing emulation..." ;
appendlog_emulate.close();
}
cout << "backup " ;
cin >> emulated_args ;
options_present = 0 ;
goto Start;
}
//If --format
if ( arg_input == "--format" ) {
//Outputs filepath from ~/.backup_prefs/format
ifstream myfile (".backup_prefs/format");
if (myfile.is_open()) {
while (! myfile.eof() ) {
getline (myfile,line_format);
cout << "\n" ;
cout << line_format ;
}
myfile.close();
cout << " is your default archive format. Do you want to edit it? y/n\n" ;
yesno=cin.get();
cin.ignore(256,'\n');
if ( yesno == 'y' ) { //<-Stopped here.
//Archive format changed from <format> ...
ofstream appendlog_format_old ("./.backup_prefs/log", ios::app );
if (appendlog_format_old.is_open()) {
appendlog_format_old << "Archive format changed from " ;
appendlog_format_old << archive_type ;
appendlog_format_old.close();
}
EditFormat () ; //Launch function
//Record date of change to log
ofstream appendlog_format_date ("./.backup_prefs/log", ios::app );
if (appendlog_format_date.is_open()) {
appendlog_format_date << date ;
appendlog_format_date << ".\n" ;
appendlog_format_date.close();
}
}
}
else {
cout << "Unable to open config file. Making a new one...\n" ;
ofstream appendlog_format_old ("./.backup_prefs/log", ios::app );
if (appendlog_format_old.is_open()) {
appendlog_format_old << "Archive format changed from " ;
appendlog_format_old << archive_type ;
appendlog_format_old.close();
}
EditFormat () ;
//Record date of change to log
ofstream appendlog ("./.backup_prefs/log", ios::app );
if (appendlog.is_open()) {
appendlog << date ;
appendlog << " becuase format preference not found.\n\n" ; //State reason
appendlog.close();
}
}
goto End;
}
//If --in
if ( arg_input == "--in" ) {
//Outputs filepath from ~/.backup_prefs/path_in
ifstream myfile (".backup_prefs/path_in");
if (myfile.is_open()) {
while (! myfile.eof() ) {
getline (myfile,line_inpath);
cout << "\n" ;
cout << line_inpath << endl;
}
myfile.close();
cout << "This is the location that will be archived. Do you want to edit it? y/n\n" ;
yesno=cin.get();
cin.ignore(256,'\n');
if ( yesno == 'y' ) {
EditPathIn () ;
}
}
else {
cout << "You don't have a selected input location. ~/ (user's home) is used as a default, though having a saved preference is recommended.\nDo you want to make a config file? y/n " ;
yesno=cin.get();
cin.ignore(256,'\n');
if ( yesno == 'y' ) {
cout << "Making a new one...\n" ;
EditPathIn () ;
}
}
goto End;
}
//If --out
if ( arg_input == "--out" ) {
//Outputs filepath from ~/.backup_prefs/path_out
ifstream myfile (".backup_prefs/path_out");
if (myfile.is_open()) {
while (! myfile.eof() ) {
getline (myfile,line_outpath);
cout << "\n" ;
cout << line_outpath << endl;
}
myfile.close();
cout << "This is the location that the backup will be stored. Do you want to edit it? y/n\n" ;
yesno=cin.get();
cin.ignore(256,'\n');
if ( yesno == 'y' ) {
EditPathOut () ;
}
}
else {
cout << "Unable to open config file. Making a new one...\n" ;
EditPathOut () ;
}
goto End;
}
//If --segfault
if (args[ 1 ] == "--segfault" ) {
system ("firefox http://xkcd.com/371/") ;
goto End;
}
//Checks for multiple formats
if ((search_for_option = arg_input.find("t", 0)) && (search_for_option != string::npos) && (search_for_option = arg_input.find("t", search_for_option))) {
multiple_formats = multiple_formats + 1 ; //+1 if tar
}
if ((search_for_option = arg_input.find("z", 0)) && (search_for_option != string::npos) && (search_for_option = arg_input.find("z", search_for_option))) {
multiple_formats = multiple_formats + 1 ; //+1 if zip
}
if ((search_for_option = arg_input.find("7", 0)) && (search_for_option != string::npos) && (search_for_option = arg_input.find("7", search_for_option))) {
multiple_formats = multiple_formats + 1 ; //+1 if 7zip
}
if ( multiple_formats > 1 ) {
cout << "Error. You've selected multiple archive types. Please only pick one.\n" ;
}
else {
//Things that must be initialized first
//Uh...
/* //-c
if ((search_for_option = arg_input.find("c", 0)) && (search_for_option != string::npos) && (search_for_option = arg_input.find("c", search_for_option)) ) {
cout << "Note: Copy does not support excluding hidden files.\n" ;
cout << "Do you want to use copy? y/n " ;
yesno=cin.get();
cin.ignore(256,'\n');
//If y, set to copy
if ( yesno == 'y' ) {
archive_type = "cp" ;
extension = "" ;
options_present = 1 ;
}
} */
//-i
if ((search_for_option = arg_input.find("i", 0)) && (search_for_option != string::npos) && (search_for_option = arg_input.find("i", search_for_option)) ) {
cout << "Enter the location of the folder you wish to archive. Remember to end with / ! Path: " ;
cin >> path_in ;
cout << "Getting files from " << path_in ;
cout << "\n" ;
options_present = 1 ;
}
//-h
if ((search_for_option = arg_input.find("h", 0)) && (search_for_option != string::npos) && (search_for_option = arg_input.find("h", search_for_option)) ) {
include_hidden_files = 1 ;
options_present = 1 ;
}
//-o
if ((search_for_option = arg_input.find("o", 0)) && (search_for_option != string::npos) && (search_for_option = arg_input.find("o", search_for_option))) {
cout << "Enter the location you wish to put the backup. Remember to end in / ! Note that this does not change the default location of " << settings_outpath ;
cout << "\nLocation:" ;
cin >> settings_outpath ;
options_present = 1 ;
}
//-t
if ((search_for_option = arg_input.find("t", 0)) && (search_for_option != string::npos) && (search_for_option = arg_input.find("t", search_for_option))) {
//Confirmation
cout << "Do you want to use .tar.gz? y/n " ;
yesno=cin.get();
cin.ignore(256,'\n');
//If y, set to tar
if ( yesno == 'y' ) {
archive_type = "tar" ;
options_present = 1 ;
}
}
//-z
if ((search_for_option = arg_input.find("z", 0)) && (search_for_option != string::npos) && (search_for_option = arg_input.find("z", search_for_option))) {
//Warning
cout << "\nZip format is the least efficiant method of compression. The only advantage of .zip is all modern operating systems have default support. \n" ;
cout << "This is only a concern if you intend to open the archive while on a computer that does not have or allow you to get .tar.gz support. If your issue is not having support for tar.gz preinsalled, see http://www.gzip.org/#exe \n\n" ;
cout << "Do you want to use .zip? y/n " ;
yesno=cin.get();
cin.ignore(256,'\n');
//If y, set to zip
if ( yesno == 'y' ) {
archive_type = "zip" ;
options_present = 1 ;
}
}
//-7
if ((search_for_option = arg_input.find("7", 0)) && (search_for_option != string::npos) && (search_for_option = arg_input.find("7", search_for_option)) ) {
//Notice
cout << "\nUsing 7zip will take a bit longer, but the end result will be a smaller file.\n" ;
cout << "Do you want to use .7z? y/n " ;
yesno=cin.get();
cin.ignore(256,'\n');
//If y, set to 7zip
if ( yesno == 'y' ) {
archive_type = "7z" ;
options_present = 1 ;
}
}
}
// } No need?
}
//If no args, run, or if options_present = 1, run
if((args.size() <= 1) || (options_present)) {
//Give attributes based on archive format
if ( archive_type == "tar" ) {
options_to_terminal = "-czvf" ;
extension = ".tar.gz" ;
exclude_hidden_files = "-x .*" ;
}
if ( archive_type == "zip" ) {
options_to_terminal = "-r" ;
extension = ".zip" ;
astrisk = "*" ;
}
if ( archive_type == "7z" ) {
options_to_terminal = "a -t7z" ;
extension = ".7z" ;
}
//If include_hidden_files, remove the exclude command
if ( include_hidden_files ) {
exclude_hidden_files = "" ; //-h
}
final_command = archive_type + " " + options_to_terminal + " " + settings_outpath + date + "_backup" + extension + " " + path_in + astrisk + " " + exclude_hidden_files ; //Creates a .tar.gz file called mm-dd_backup .
//To terminal
system (final_command.c_str()) ;
ofstream appendlog ("./.backup_prefs/log", ios::app );
if (appendlog.is_open())
{
appendlog << final_command ;
appendlog << " at " ;
appendlog << date ;
appendlog << ".\n" ;
appendlog.close();
}
else {
cout << "Unable to record to log.\n";
}
}
End:;
}
Well, 3 cin's SHOULD work. Your problem is most probably somewhere else.
Just by skimming through your red code,
You are not checking the return value of open, which is bad. What if the open fails because of permission problems, path problems, not enough disk space, network offline (if it's on a network share), IO problems...?Quote:
Code:ofstream format ;
format.open (".backup_prefs/format") ;
format << new_format_full ;
format.close() ;
I see you are using is_open() for other instances, did you just forgot to do it for this one?
Also, properly indenting the code will make it a lot easier to read.
And do you know how your program exits? Does it crash? Have you tried using GDB? (compile with g++ -g)
I'm just taking a stab in the dark here but I noticed you said exit and not crash.
Cprogramming.com FAQ > Stop my Windows Console from disappearing everytime I run my program?
The cin stream will leave some stuff to read occasionally (particularly newlines or things that caused it to enter a fail state). So clean up after yourself with ignore and a big number until you learn how to deal with C++ input (hint: read what the faq says about it).
The OP is probably using a UNIX-like OS.
Quote:
Code:
system ( "mkdir ~/.backup_prefs" ) ; //Make directory (assuming that no log = no directory)
It seems my reply didn't send.
I've never hear of checking open's return. Useful.
As to testing, I've just tested putting outputs in and seeing what it gets to.
I wouldn't call it a crash, since it just, open pressing y, enter, displays the next line as me@computer:~$.
Edit: this is Ubuntu Linux, though just 'Linux' is the important part.
Through your link I found an example for Linux ( Cprogramming.com FAQ > How do I get my program to wait for a keypress? ), but I think this is talking about making it stay when the program is completed, and has no more code to run.
Testing proved it to be the yes/no if statements. hey're messing up when run with --emulate. I'll see if I can find why.