So I'm trying to find the last character from user input in Ruby.
I've tried the following-
print "Enter in a string: "
user_input = gets
end_char = user_input[-1,1]
puts "#{end_char} is the last char!"
But it returns
" is the last char!".
I've tried
end_char = "test"[-1,1]
and that works as it should (returns t). But its not working when I use user input as the string instead of just typing in a string itself. Help?
So when you say "Enter in a string" and you type "foo", what's the last thing you do? Well you hit enter obviously! So what you actually capture is "foo\n".
Calling user_input[-1,1] actually gives back the \n return symbol which just prints a break return in the output.
print "Enter in a string: "
user_input = gets.chomp
end_char = user_input[-1,1]
puts "#{end_char} is the last char!"
the #chomp method actually removes the return character from the input.
Now when I run it:
stacko % ruby puts.rb
Enter in a string: hi Lupo90
0 is the last char!
Consider this IRB session:
I'll enter "foo":
irb(main):001:0> user_input = gets
foo
"foo\n"
I entered "foo", and to terminate the input I had to press Return (or Enter depending on the OS and keyboard), which is the "\n" (or "\r\n") line-ending, depending on whether your OS is *nix or Windows.
Looking at what I entered:
irb(main):002:0> user_input[-1]
"\n"
Here's what is output. Notice that the single-quotes are on separate lines because a "\n" is a new-line character:
irb(main):003:0> puts "'\n'"
'
'
nil
(The trailing nil is the result of puts and isn't important for this example.)
So, gets returned everything entered, including the trailing new-line. Let's fix that:
irb(main):004:0> user_input = gets.chomp
foo
"foo"
irb(main):005:0> user_input[-1]
"o"
irb(main):006:0> puts '"%s" is the last char' % [user_input[-1]]
"o" is the last char
chomp is used to strip trailing line-end from the end of a string:
irb(main):010:0> "foo\n".chomp
"foo"
irb(main):011:0> "foo\r\n".chomp
"foo"
This is a really common question on Stack Overflow. Perhaps searching for it would have helped?
Related
This question already has answers here:
Why does Ruby's 'gets' includes the closing newline?
(5 answers)
Closed 3 years ago.
My Ruby program evaluates strings in a function called func1. It asks for user input when it runs. The string comparison if statement
does not work on user input no matter what. I can interactively enter the string that should be the same as the program-defined variable constant. But the function interprets the two strings differently. I have added extra debugging steps to verify the string is correct. But I still fail to see why the func1 sees user input different from the way I, a human, sees the input. I expect func1 to receive the user-inputted string foobar and recognize it. This is not what is happening. What am I doing wrong?
Here is my Ruby program:
def func1(x)
if x == 'foobar' then
print "you gave this function foobar"
puts " "
else
print "you did NOT give this function foobar"
end
end
def prompt(*args)
print("Enter a string: ")
coolstring = gets
return coolstring
end
func1("foobar")
y = prompt
print(y)
func1(y)
Here is some output that shows I entered the string "foobar":
you gave this function foobar
Enter a string: foobar
foobar
you did NOT give this function foobar
When you call gets the newline that ends the input is stored in the variable:
pry(main)> gets
qwe
# => "qwe\n"
To remove it, use String#chomp. It removes a separator (by default a newline) from the end of the string:
pry(main)> a = gets
asd
#=> "asd\n"
pry(main)> a.chomp
#=> "asd"
And in your case:
def prompt(*args)
print("Enter a string: ")
coolstring = gets.chomp # <<<<<<<<<<<< here
return coolstring
end
I want to write a program that asks for two strings from the user and searches for one within the other, but I'm having some trouble making it work. The following returns "not" even when the given character is present within the string. Does anyone know what I'm doing wrong?
puts 'Enter the string that you would like to search'
content = gets
puts 'What character would you like to find?'
query = gets
if content.include? query
puts "here"
else
puts "not"
end
gets returns the string from the user including the newline character '\n' at the end. If the user enters "Hello world" and "Hello", then the strings really are:
"Hello World\n"
"Hello\n"
That makes it obvious, why your code does not find a match.
Use chomp to remove that newline characters from the end of the string.
puts 'Enter the string that you would like to search'
content = gets.chomp
puts 'What character would you like to find?'
query = gets.chomp
if content.include?(query)
puts "here"
else
puts "not"
end
As I understand it, the way to accept user input is
puts "Can you guess what number the computer is thinking of?"
userguess = gets.chomp
gets.chomp is a string method and so if the user enters the number 5, userguess stores the value "5" as string. I would then have to do userguess.to_i! to convert this to an int. However, I would not like to do this. I want to accept the user input either as a string or an int and then have the program do something like:
if #guess.is_a?(Integer) == true
puts "I got your number. Let me get back to you."
# do something
elsif #guess.is_a?(Integer) == false
puts "That's not a number. You MUST enter a number! Try again"
# Ask the user to guess again.
else
#something else
end
I don't want to accept the user input explicitly as a string because I want to check if it is a string or an int later on in the program. How would I do this?
That is impossible. All user input from the terminal are a string. If it were possible, how would you think a user can input a number 5 as opposed to a string "5"?
No, that is not possible.
But you can define a little function to check whether that string can be an integer or not:
def is_i?(s)
s.to_i.to_s == s
end
Be aware that string with spaces will not be an integer in this case:
is_i? '123' # true
is_i? '123 ' # false
is_i? ' 123' # false
is_i? '12 123' # false
To handle second and third example you can strip your user input.
Your code will look like:
guess = gets.chomp.strip
if is_i? guess
puts 'is integer'
else
puts 'is not an integer'
end
To check if a string contains valid integer (or float, etc.) you could use this approach:
def coerce(string)
Integer(string) rescue Float(string) rescue string
end
coerce('115').class # Fixnum
coerce('115.12').class # Float
coerce('115.aa').class # String
Also check out highline gem, it provides lots of helpful functionality when it comes to cli.
You don't understand how a keyboard device and the console input work.
ALL input typed on the keyboard and read via gets or anything else, is always a String. You can not get anything else.
We use gets.chomp to remove the trailing newline that is entered when the user presses Return or Enter. For instance, a bare gets will return a line-end if I enter nothing else:
gets #=> "\n"
Adding additional characters results in those characters, plus the terminating line-end:
gets #=> "foo\n"
We use chomp to remove that trailing line-end. Repeating the same inputs and using chomp:
gets.chomp #=> ""
gets.chomp #=> "foo"
Ruby makes it easy to tell if what was input can be cleanly converted to an integer. Simply use Integer(). Here is some output from an IRB session:
>> Integer('1') #=> 1
>> Integer('123') #=> 123
>> Integer('foo')
ArgumentError: invalid value for Integer(): "foo"
from (irb):14:in `Integer'
from (irb):14
from /usr/local/bin/irb:12:in `<main>'
>> Integer('1a')
ArgumentError: invalid value for Integer(): "1a"
from (irb):15:in `Integer'
from (irb):15
from /usr/local/bin/irb:12:in `<main>'
Using a rescue makes it easy to handle the exception:
begin
Integer('1')
rescue ArgumentError
puts 'not a number'
end #=> 1
Or:
begin
Integer('a')
rescue ArgumentError
'not a number'
end #=> "not a number"
I understand about the \n that's automatically at the end of puts and gets, and how to deal with those, but is there a way to keep the display point (the 'cursor position', if you will) from moving to a new line after hitting enter for input with gets ?
e.g.
print 'Hello, my name is '
a = gets.chomp
print ', what's your name?'
would end up looking like
Hello, my name is Jeremiah, what's your name?
You can do this by using the (very poorly documented) getch:
require 'io/console'
require 'io/wait'
loop do
chars = STDIN.getch
chars << STDIN.getch while STDIN.ready? # Process multi-char paste
break if ["\r", "\n", "\r\n"].include?(chars)
STDOUT.print chars
end
References:
http://ruby-doc.org/stdlib-2.1.0/libdoc/io/console/rdoc/IO.html#method-i-getch
http://ruby-doc.org/stdlib-2.1.0/libdoc/io/wait/rdoc/IO.html#method-i-ready-3F
Related follow-up question:
enter & IOError: byte oriented read for character buffered IO
Perhaps I'm missing something, but 'gets.chomp' works just fine does it not? To do what you want, you have to escape the apostrophe or use double-quotes, and you need to include what the user enters in the string that gets printed:
print 'Hello, my name is '
a = gets.chomp
print "#{a}, what's your name?"
# => Hello, my name is Jeremiah, what's your name?
Works for me. (Edit: Works in TextMate, not Terminal)
Otherwise, you could just do something like this, but I realise it's not quite what you were asking for:
puts "Enter name"
a = gets.chomp
puts "Hello, my name is #{a}, what's your name?"
I'm currently going through some programs to learn Ruby. I've been playing around with a palindrome program for a bit, though no matter the input (a palindrome) I end up on else.
Here is some of the code I've been trying:
print "enter a string:\n"
string = gets
if string.reverse == string
print "it's a palindrome"
else
print "not a palindrome.\n"
end
Any help/advice is greatly appreciated.
The newline character is not being deleted from the string. Try this code:
print "enter a string:\n"
string = gets.chomp
if string.reverse == string
print "it's a palindrome"
else
print "not a palindrome.\n"
end
Here is some more explanation:
>> string = gets
racecar # input string
=> "racecar\n"
>> "racecar\n" == "racecar\n".reverse # "racecar\n" is not a palindrome with newline character
=> false
>> string = gets.chomp # chomp method deletes newline character
racecar
=> "racecar"
>> "racecar" == "racecar".reverse # "racecar" without a newline character is a palindrome
=> true
Learn how Ruby's puts works: It's like print, only smarter.
If a string ends with "\n", it prints it as is. If it doesn't end with "\n", it prints the line and adds "\n". Either way, you're guaranteed to have new-line added.
Knowing that, consider this:
puts "enter a string:"
string = gets
if string.reverse == string
puts "it's a palindrome"
else
puts "not a palindrome."
end
As a result, no new-lines need to be added to the strings. puts is the standard method for outputting lines to files and the console in Ruby.
The following statement will return true if it's a palindrome and false otherwise:
string == string.reverse