Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ruby how read user input in scanf-style like in C++

Tags:

c++

ruby

scanf

I am new in Ruby. I need to read from user input (n) numbers and in C++ i used this code

for(i=0;i<N;i++)
{
  scanf("%d",&array[i]);
}

this code read exactly (n) numbers separated by any white spaces (tabs, spaces, newlines).

How i can do this in ruby?

in Ruby I tried to do it like this

require 'scanf'
n = scanf("%d");
arr = Array.new()
n.times { arr << scanf("%d") }

but this code don't work when i intut string like this:

1   4    8

but works fine if i input this

1
4
8
like image 280
tty6 Avatar asked Feb 09 '13 11:02

tty6


People also ask

How do I scanf in Ruby?

scanf is an implementation of the C function scanf(3), modified as necessary for Ruby compatibility. the methods provided are String#scanf, IO#scanf, and Kernel#scanf. Kernel#scanf is a wrapper around STDIN. scanf.

What is %s in scanf?

In general scanf() function with format specification like %s and specification with the field width in the form of %ws can read-only strings till non-whitespace part. It means they cannot be used for reading a text containing more than one word, especially with Whitespaces.

What can I use instead of scanf in C?

To convert the input, there are a variety of functions that you can use: strtoll , to convert a string into an integer. strtof / d / ld , to convert a string into a floating-point number. sscanf , which is not as bad as simply using scanf , although it does have most of the downfalls mentioned below.


2 Answers

Use String#scan

I'm not 100% sure that I know what you really want to do here. If you just want to scan a string for digits, you can use String#scan to do something like this:

digits = '1   4    8'.scan /\d+/
# => ["1", "4", "8"]

This will return an array of digits found in the string, and you can access your digits array with any Array or Enumerable method you like.

If you want to handle newlines as well as tabs or spaces, all you need to do is add the m flag for multi-line matching. For example:

digits = '1
          4 8'.scan /\d+/m
# => ["1", "4", "8"]
like image 178
Todd A. Jacobs Avatar answered Nov 03 '22 21:11

Todd A. Jacobs


Have to admit in this instance I'm unable to make a program that is quite as compact as the C++ version. It seems in Ruby scanf does not work like the C++ version for IO streams, and for strings you will need to provide a block to achieve multiple scans per line.

So here's one solution:

a = Array.new
n = gets.to_i

while a.length < n
  gets.scanf("%d") { |d| a << d[0] }
end

The only problem you get here is if you request for example 3 numbers, and then the user inputs 10 numbers on one line, then a will contain all those 10 numbers. To fix it you can just always truncate the array after the loop is done:

a = a.take(n)

This solution will read n numbers from the input regardless of white space. The user can input them all on one line, or on separate lines, or a mix of both (which I assume was your original requirement).

like image 20
Casper Avatar answered Nov 03 '22 19:11

Casper