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.
1) Use grep and the exit status to determine if it's a number:
Code:
#!/bin/bash
echo -n "Give number (1-40) : "
read input
echo $input | grep "[0-9][0-9]*" > /dev/null 2>&1
if [ "$?" -ne 0 ]
then
echo "Use a number please"
fi
I tried this solution and it works excellent, BUT one problem. If a user types a number and a letter eg. 2a or w4, the script can not yet hadle this. How should I add another "checker" to prevent this?
Hi,
I integrated your solutions to the the script and I guess it is ready. Could you perhaps try to find something that is missing?
------------------------------------------------------------------------------------------------------------------------------
# Guessing game
# !/bin/bash
clear
times=0# Guessing game
# !/bin/bash
clear
times=0
guess=$[$RANDOM * 40 / 32767]
try=0
echo "You have 10 tries ..... good luck! "
echo
while [ $times -ne $guess ]
do
echo
echo -n "Please enter a number between 1 and 40 : "
read input
try=$[$try+1]
if [ $try = 10 ]
then
echo "You have exhausted all tries"
echo
exit
else
echo $input | grep "^[1-9][0-9]*$" > /dev/null 2>&1
if [ "$?" -ne 0 ]
then
echo "Please only integers (1-40) "
else
if [ $input -eq $guess ]
then
echo "Congratulation "
echo
exit
else
if [ $input -lt $guess ]
then
echo "Too small "
else
echo "Too big "
fi
fi
fihttp://search.yahoo.com/search?p=intergrate&prssweb=Search&ei=UTF-8&fr=yfp-t-501&x=wrt
fi
done
guess=$[$RANDOM * 40 / 32767]
try=0
echo "You have 10 tries ..... good luck! "
echo
while [ $times -ne $guess ]
do
echo
echo -n "Please enter a number between 1 and 40 : "
read input
try=$[$try+1]
if [ $try = 10 ]
then
echo "You have exhausted all tries"
echo
exit
else
echo $input | grep "^[1-9][0-9]*$" > /dev/null 2>&1
if [ "$?" -ne 0 ]
then
echo "Please only integers (1-40) "
else
if [ $input -eq $guess ]
then
echo "Congratulation "
echo
exit
else
if [ $input -lt $guess ]
then
echo "Too small "
else
echo "Too big "
fi
fi
fi
fi
done
-------------------------------------------------------------------------------------------------------------
The above code (the relevant part of it) works. But why the 'double' bash code and the URL?
You did not use the 'code' tags in your post, so the following could be done by you but removed by the lack of code tags:
It is common practise to indent code for better readability and easier debugging (true for most, if not all programming languages).
After removing the extra/unneeded stuff and some indenting the 'final' code looks like this:
Code:
# !/bin/bash
clear
times=0
guess=$[$RANDOM * 40 / 32767]
try=0
echo "You have 10 tries ..... good luck! "
echo
while [ $times -ne $guess ]
do
echo
echo -n "Please enter a number between 1 and 40 : "
read input
try=$[$try+1]
if [ $try = 10 ]
then
echo "You have exhausted all tries"
echo
exit 0
else
echo $input | grep "^[1-9][0-9]*$" > /dev/null 2>&1
if [ "$?" -ne 0 ]
then
echo "Please only integers (1-40) "
else
if [ $input -eq $guess ]
then
echo "Congratulation "
echo
exit 0
else
if [ $input -lt $guess ]
then
echo "Too small "
else
echo "Too big "
fi
fi
fi
fi
done
If things get more complicated it's also a good idea to add some comments to explain what the script does and/or why you did it a certain way.
#!/bin/bash
function cando
{
echo cando
return 0
}
cando
if [ $? -ne "0" ]; then echo this will never happen; exit 1; fi
function candomore
{
echo function arguments = $*
}
candomore and more and more
After "please only integers" slap a "continue". This will start the next loop, skipping the rest of the current loop which contains only irrelevant tests. "break" breaks out of the loop altogether, but you don't need that.
thanks for your advice. Actually I am suprised the way my post came out. As I am new here I dodnt know there was an option of to format a post to look good. The error in my post I guess was due to the fact that I pasted from Linux enviroment. Anyway lets go on.Now I know
Quote:
Originally Posted by druuna
Hi,
The above code (the relevant part of it) works. But why the 'double' bash code and the URL?
You did not use the 'code' tags in your post, so the following could be done by you but removed by the lack of code tags:
It is common practise to indent code for better readability and easier debugging (true for most, if not all programming languages).
If things get more complicated it's also a good idea to add some comments to explain what the script does and/or why you did it a certain way.
Hi,
Ok now the code looks like as shown below.I commented it and I found something interesting. The user has 10 tries, that is ok. But the user doesn´t get rewarded at the last try(the tenth)even if they guessed correctly. In other words the program exits after the 10th try and doesnt inform whether there was a guess or not even if the guess was there.
Code:
# !/bin/bash
clear #just clear for me the screen
times=0 #a variable to help me check the while loop
guess=$[$RANDOM * 40 / 32767] #my randomly generated number to be guessed
try=0 #this will set my counter to count number of guesses
echo "You have 10 tries ..... good luck! "
echo
while [ $times -ne $guess ] #while true; as long as everything is ok
do
echo
echo -n "Please enter a number between 1 and 40 : "
read input
try=$[$try+1] #start counting number og guesses
if [ $try = 10 ] #if the guess was the tenth, then.....
then
echo "You have exhausted all tries"
echo
exit 0
else
echo $input | grep "^[1-9][0-9]*$" > /dev/null 2>&1 #check to see that only integers a used
if [ "$?" -ne 0 ] #if my special variable $? stored a value other than 0, it means a letter or #another character or combination of letters and characters were used. So tell the user to use 1-40
then
echo "Please only integers (1-40) "
else
if [ $input -eq $guess ]#if the user used a number equal to that which was randomly generated
then
echo "Congratulation " #then the user has won
echo
exit 0
else
if [ $input -lt $guess ]#else the user used a smaller number
then
echo "Too small "
else
echo "Too big " #or the user used a greater number than the one needed
fi
fi
fi
fi
done
Looks a lot better. Personally I like to place the comments above the command, but that's a taste issue.
It does matter where the # is placed. On certain lines there's no space between the last character of the command and the # (bash will complain and fail).
Quote:
I commented it and I found something interesting. The user has 10 tries, that is ok. But the user doesn´t get rewarded at the last try(the tenth)even if they guessed correctly. In other words the program exits after the 10th try and doesnt inform whether there was a guess or not even if the guess was there.
You can solve this by changing this:
if [ $try = 10 ] #if the guess was the tenth, then.....
by
if [ $try -gt 10 ] #if the guess was the tenth, then.....
The -gt operator stands for greater than. See bash manpage for all the possibilities (the CONDITIONAL EXPRESSIONS section).
Looks a lot better. Personally I like to place the comments above the command, but that's a taste issue.
It does matter where the # is placed. On certain lines there's no space between the last character of the command and the # (bash will complain and fail).
You can solve this by changing this:
if [ $try = 10 ] #if the guess was the tenth, then.....
by
if [ $try -gt 10 ] #if the guess was the tenth, then.....
The -gt operator stands for greater than. See bash manpage for all the possibilities (the CONDITIONAL EXPRESSIONS section).
What I wanted is(I know from other languages it is possible).
if [ $try -eq 10 ] AND [ $try -eq $guess]
#if the guess was the tenth(the last), and it was the correct guess then inform of this and the quit.....
if [ $input -eq $guess ] #if the user used a number equal to that which was randomly generated
then
[ $try -eq 10 ] && echo "And on the very last guess......."
echo "Congratulation " #then the user has won
echo
exit 0
else
This: [ $try -eq 10 ] && echo "And on the very last guess......." is a short way of saying:
Code:
if [ $try -eq 10 ]
then
echo "And on the very last guess......."
fi
Only if the first part (before &&) is true, the second part is executed.
if [ $input -eq $guess ] #if the user used a number equal to that which was randomly generated
then
[ $try -eq 10 ] && echo "And on the very last guess......."
echo "Congratulation " #then the user has won
echo
exit 0
else
I applied your suggestions and the do exactly what I wanted. I discover now that the more succesful you become the more you want :-)
I now wanted to check if a user just pressed <enter> without typing anything. So far this works without adding any code, but
I just wanted to check this and I tried the following but I got errors.
Code:
#just setting my variable returnchar to store the return key
retunchar=$'\r'
echo $eingabe | grep "[1-9][0-9]*" > /dev/null 2>&1
if [ "$?" -ne 0 ]
then
#here is where I get error "integer expression expected"
["$?" -eq $returnchar ] && echo "you didn't type anything(you only pressed the return key"
echo " use only numbers please "
fi
#If the input is not a number this will return the empty string
#If it is a number it will return the number
raffiniert=$(echo $eingabe | grep '^[1-9][0-9]*$')
# -z and -n test for empty and non-empty strings respectively
if [ -z "$raffiniert" ]
then
echo " enter a number please "
else
# ... code as before
fi
As you already noticed the code catches anything that is not a number and tells you so. But that's not what you wanted to know.
The return character is (most often) not part of the string that is given to bash. An empty input is just that: empty (NULL) and the return char is not present in that string.
Bash has a few ways to check if a string has a (non-) zero length: The -z and the -n operator (there are more, see man bash , the CONDITIONAL EXPRESSIONS section). -z checks to see if a string is zero, -n checks for a non-zero string. I.e:
Code:
$ foo=""
$ [ -z $foo ] && echo "foo is not set ($foo)"
foo is not set ()
$ foo="bar"
$ [ -z $foo ] && echo "foo is not set ($foo)"
$ [ -n $foo ] && echo "foo is set ($foo)"
foo is set (bar)
I'll leave it up to you to try to implement this in your current code.
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.