ProgrammingThis forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
i have my program to read games.db, and inside it i have path:gamename so e.g /home/twirl/bf2/./start.sh:Battlefield2 the problem is when i try and run the game from my menu i get this error below, can someone please help me so it runs the game like it should do please? code is below also :-
Run Game1. Battlefield 2
Please select game you wish to run: 1
sh: line 1: 1: command not found
Code:
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
int main()
{
int i=0;
char s1[30],s2[40],s3[90],s4[100]; // set char size for input
ofstream outfile("games.db", ios::app);
string whole,p1,p2;
ifstream infile;
// Start Main Menu
char choice='\0';//NULL;
bool finished=false;
while (finished != true)
{
cout<<"MAIN MENU\n";
cout<<"1. AddGame\n";
cout<<"2. Options\n";
cout<<"3. RunGame\n";
cout<<"4. Exit\n";
cout << "Please enter your choice: ";
cin>>choice;
cout<<"\n\n";
// Start function for submenu
switch(choice)
{
case '1': cout << "1. Add Game To DB\n";
cout << "2. Go back\n";
cout << "Please enter your choice: ";
cin>>choice;
if(choice == '1')
{
cout << "\n\nPlease enter full-path to game start file: ";
cin.get();
cin.getline (s1, 30); // Input goes in$
outfile << s1 << ":"; // add : after eachpath
cout << "\n\nPlease enter game name: ";
cin.getline (s2, 40);
outfile << s2 << "\n";
if (outfile.is_open())
{
outfile.close();
}
}
/* Just break if choice != 1 */
break;
case '2': cout<<"Options\n";
cout<<"1. Edit Game Config\n";
cout<<"2. Go back\n";
cout << "Please enter your choice: ";
cin>>choice;
if(choice=='1')
{
cout << "Please enter full path to config file to edit: "; // ask user for path to config file
cin.get();
cin.getline (s3, 256); // input goes in
string cmd = string("pico ") + string(s2);
system(cmd.data()); // open up pico to edit config
}
// Here we would check 'choice' and probably move to another functi$
cout<<"\n\n";
break;
case '3': cout<<"Run Game";
i=0;
infile.open ("games.db", ios::in);
while(getline(infile,whole)){
i++;
p2=whole.substr(whole.find(':')+1,whole.length());
cout << i << ". " << p2 << endl;
}
cout << "Please select game you wish to run: ";
cin.get();
cin.getline(s3, 100);
system ( (string(s3)+" > system_errors").c_str() );
// Here we would check 'choice' and probably move to another functi$
cout<<"\n\n";
break;
case '4': //Finished so set finished 'true' to break out of loop
finished=true;
cout<<"Exiting....\n";
break;
default: //If choice !=1/2/3 then do what it says here
break;
// end functions
}
choice='\0'; //NULL
}
return 1;
}
Run Game1. Battlefield 2
Please select game you wish to run: 1
sh: line 1: 1: command not found
THe text in blue indicates the system tried to execute a program that wasn't found. Specifically, something tried to run "1" as a program.
If you look at your case statement for the "Fun Game" portion of your code:
Code:
case '3': cout<<"Run Game";
i=0;
infile.open ("games.db", ios::in);
while(getline(infile,whole)){
i++;
p2=whole.substr(whole.find(':')+1,whole.length());
cout << i << ". " << p2 << endl;
}
cout << "Please select game you wish to run: ";
cin.get();
cin.getline(s3, 100);
system ( (string(s3)+" > system_errors").c_str() );
// Here we would check 'choice' and probably move to another functi$
cout<<"\n\n";
break;
The code in blue tells the computer to read the user's response (from the example above, the input was "1"), then executes a command through the system after appending some redirection. Specifically, the system tries to run the following command:
Code:
1 > system_errors
THe "1" executable can't be found, which is why you get the error above. The program needs the user to enter the executable name (which you're trying to avoid), or the program needs to translate the user input into a command name. For example, it needs to recognize a "1" should mean "/home/twirl/bf2/./start.sh". Then, after it makes that translation, it should submit the command to the system.
As a side note, I would suggest adding an "endl" to the cout statement in orange above:
Code:
cout << "Please select game you wish to run: " << endl;
Thankyou for your reply, i am trying to get "1" should mean "/home/twirl/bf2/./start.sh". Then, after it makes that translation, it should submit the command to the system., and continue on that way throughout the program and counting how many servers are in games.db so itl be like in the db.:-
/home/twirl/bf2/./start.sh:Battlefield2 (will show as "1" in run game menu)
/home/twirl/bf1942/./start.sh:Battlefield (will show as "2" in run game menu)
/home/twirl/cs/./runcstrike.sh:Counter Strike Source (will show as "3" in run game menu)
and should continue that pattern if you understand what i mean?
Yes, you've got the right idea. Earlier in the code, you created the menu by reading each line of the file and extracting the game name. You'll have to do something very similar. Instead of extracting the game name, you'll need to extract the command. So, if the user enters "2", you need to open the file again, read the first line (ignore it), read the second line, and then pull out the text before the first colon. That text should be what you copy into s3. Then you can send that command to the system (plus the output redirection).
First, your use of substr() is not correct from what I can tell. When you use whole.find(), it returns the location of the first character that matches what you are looking for. In this case, a ':'. The first time you use it (to extract the game name), it's not completely correct, but "good enough". The second time you use it is where you run into problems. Replace the second use to this:
Code:
p1=whole.substr(0, whole.find(':'));
If you're not sure why it should be that way, then you need to look over some material on how strings are organized, and review exactly what the arguments to substr() mean.
Second, you're going to loop through the file until you reach the end no matter what. Regardless of what the user enters, your second loop will read through the entire file. There needs to be a condition on the loop that causes the loop to end when the number of lines read from the file equals the number entered by the user.
Third, the program is still relying on s3 to contain the name of the executable. s3 is used to store the user's numeric choice, but it's never updated. That is, you either need to copy the executable name from the file (p1) into s3, or you need to use p1 in your system() call.
Lastly, it's not absolutely necessary, but good, clean programming practice suggests that you close a file after you've finished reading it. It won't break the program if you don't, but it's a good habit to "clean up after yourself".
Last edited by Dark_Helmet; 09-12-2005 at 03:53 PM.
ok ty, this is what iv got so far, but aint worked out the loop part.
Code:
cout << "Please select game you wish to run: " << endl;
cin.get();
cin.getline(s3, 100);
i=0;
infile.open ("games.db", ios::in);
while(getline(infile,whole)){
i--;
p1=whole.substr(0, whole.find(':'));
cout << i << ". " << p1 << endl;
}
system ( (string(s3)+"p1 > system_errors").c_str() );
// Here we would check 'choice' and probably move to another functi$
cout<<"\n\n";
break;
case '4': //Finished so set finished 'true' to break out of loop
finished=true;
cout<<"Exiting....\n";
break;
default: //If choice !=1/2/3 then do what it says here
break;
outfile.close(); /
Well, I see you have another thread working on this same problem. It's not a good idea to split the thread into two separate ones. So since the other thread has been going for quite a while, I'll let them take it from here.
I will point out one thing though: You're still using s3 in your system command. That still means the command you submit to the system will have the user's number selection in it. You need to rip out s3, or replace s3's contents with p1. Focus on this line:
Code:
system ( (string(s3)+"p1 > system_errors").c_str() );
In addition to the s3 I just mentioned, you've also got a mistake in using p1. When p1 is used in quotes (like above), the computer is going to think you meant to use it literally. That is, the contents of p1 (the name of the executable) will not be substituted in the string. For example:
Code:
system ((string(s3)+"p1 > system_errors").c_str() );
That is equivalent to typing "1p1 > system_errors" on the command line. The initial 1 is the string contained in s3. So if the user selected 2, the same command before would be equivalent to "2p1 > system_errors"
You really need to pick up a resource or tutorial somewhere to explain strings. Trust me. Well, I shouldn't because it won't help you learn, but here's what that system command ought to be:
Code:
system ((string(p1)+" > system_errors").c_str() );
Try to figure out why that is. Seriously. Experiment with the code to try and determine why things work the way they do. If you don't understand, then do a search online to find a tutorial.
Ok, it seems you cant run them like that, so i need a way of the programming going into the dir of the path and then executing ./start.sh or whatever its called in games.db
I mean, looks like im going have to get the program to go into the directory of path specified in the games.db file and then run ./start.sh or whatever that way...
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.