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?
This is a discussion on Issue with >2 cin commands within the C++ Programming forums, part of the General Programming Boards category; I found that when I use more than two user inputs, the program will immediately exit after the third. Is ...
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.
No one has time for that. Make the simplest compilable program that demonstrates the problem.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:; }
Last edited by Muscovy; 07-23-2009 at 08:03 PM.
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...?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).
Originally Posted by phantomotap
The OP is probably using a UNIX-like OS.
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.
Last edited by Muscovy; 07-23-2009 at 08:19 PM.
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.