Home > Back-end >  how to get any number of inputs from user and put it into a "params" method in c#?
how to get any number of inputs from user and put it into a "params" method in c#?

Time:12-20

so we can give any number of parameters to a method, like this:

static int sumPrices(params int[] prices) {
            int sum = 0;
            for (int i = 0; i < prices.Length; i  ) {
                sum  = prices[i];
            }
            return sum;
        }
        static void Main(string[] args)
        {
            int total = sumPrices(100, 50, 200, 350);
            Console.WriteLine(total);
            Console.ReadKey();
        }

but ... what if we wanted to get the "100, 50, 200, 350" from the USER? in above example it's the coder giving the sumPrices method its arguments/parameters.

i mean, it would be one solution to just pass the method an array.

static int sumPrices(int[] prices) {
            int sum = 0;
            for (int i = 0; i < prices.Length; i  ) {
                sum  = prices[i];
            }
            return sum;
        }
        static void Main(string[] args)
        {
            //get up to 9999 inputs and sum them using a method
            bool whileLoop = true;
            int[] inputs = new int[9999];
            int index = 0;
            while (whileLoop == true)
            {
                Console.WriteLine("entering price #"   index   ", type 'stop' to sum prices");
                string check = Console.ReadLine();
                if (check == "stop") {
                    whileLoop = false;
                    break;
                }
                inputs[index] = int.Parse(check);
                index  ;
            }
            int[] prices = new int[index];
            for (int i = 0; i < index; i  )
            {
                prices[i] = inputs[i];
            }
            Console.WriteLine("-----------------");
            Console.WriteLine(sumPrices(prices));
            Console.ReadKey();
            
        }

BUT... longer code... and has limits.

our professor basically wanted the first code, however, i don't see how and where it's supposed be used if we didn't know the user's inputs and if params arguments were coming from the coder (unless of course, coder using the same function multiple times for convenience)

i have tried to think of a solution and i'm not exactly sure how it could be done. but it basically goes like this. we could get inputs from the user separated by commas:

100,200,50

and the program would translate it into params arguments:

sumPrices("100,200,50");

but as you can see... it's a string. i wonder if there's a JSON.parse() thing like in js.

CodePudding user response:

The code in the OP has some unnecessary code as well as some limitations such as 9999.

Let's examine the following code:

bool whileLoop = true;

while (whileLoop == true)
{
}

This could be re-written as:

while (true == true)
{
}

or

while (true)
{
}

Next, let's examine the following code:

if (check == "stop") {
    whileLoop = false;
    break;
}

You've set whileLoop = false; which is unnecessary because once break is executed, excution has moved to after the loop.

Since the input array has a hard-code size of 9999, you've limited yourself to 9999 values. You may consider using a List instead or resize the array.

Try the following:

using System;
using System.Collections.Generic;
using System.Linq;

namespace UserInputTest
{
    internal class Program
    {
        static void Main(string[] args)
        {
            decimal price = 0;
            List<decimal> _values = new List<decimal>();

            if (args.Length == 0)
            {
                //prompts for user input

                Console.WriteLine("The following program will sum the prices that are entered. To exit, type 'q'");

                do
                {
                    Console.Write("Please enter a price: ");
                    string userInput = Console.ReadLine();

                    if (userInput.ToLower() == "q")
                        break; //exit loop
                    else if (Decimal.TryParse(userInput, out price))
                        _values.Add(price);  //if the user input can be converted to a decimal, add it to the list
                    else
                        Console.WriteLine($"Error: Invalid price ('{userInput}'). Please try again.");
                } while (true);
            }
            else
            {
                //reads input from command-line arguments instead of prompting for user input
                foreach (string arg in args)
                {
                    if (Decimal.TryParse(arg, out price))
                    {
                        //if the user input can be converted to a decimal, add it to the list
                        _values.Add(price); //add
                    }
                    else
                    {
                        Console.WriteLine($"Error: Invalid price ('{arg}'). Exiting.");
                        Environment.Exit(-1);
                    }  
                }
            }
            
            Console.WriteLine($"\nThe sum is: {SumPrices(_values)}");
        }

        static decimal SumPrices(List<decimal> prices)
        { 
            return prices.Sum(x => x);
        }

        static decimal SumPricesF(List<decimal> prices)
        {
            decimal sum = 0;

            foreach (decimal price in prices)
                sum  = price;

            return sum;
        }
    }
}

Usage 1:

UserInputTest.exe

Usage 2:

UserInputTest.exe 1 2 3 4 5

Resources:

CodePudding user response:

The trick is input from the user always starts out as strings. You must parse those strings into integers. We can do it in very little code like this:

static int sumPrices(IEnumerable<int> prices) 
{
    return prices.Sum();
}

static void Main(string[] args)
{
    int total = sumPrices(args.Select(int.Parse));
    Console.WriteLine(total);
    Console.ReadKey();
}

See it here (with adjustments for the sandbox environment):

https://dotnetfiddle.net/Pv6B6e

Note this assumes a perfect typist. There is no error checking if a provided value will not parse.

But I doubt using linq operations are expected in an early school project, so we can expand this a little bit to only use techniques that are more familiar:

static int sumPrices(int[] prices) 
{
    int total = 0;
    foreach(int price in prices)
    {
        total  = price;
    }
    return total;
}

static void Main(string[] args)
{
    int[] prices = new int[args.Length];
    for(int i = 0; i<args.Length; i  )
    {
        prices[i] = int.Parse(args[i]);
    }

    int total = sumPrices(prices);
    Console.WriteLine(total);
    Console.ReadKey();
}

If you're also not allowed to use int.Parse() (which is nuts, but sometimes homework has odd constraints) you would keep everything else the same, but replace int.Parse() with your own ParseInt() method:

static int ParseInt(string input)
{
   int exponent = 0;
   int result = 0;
   for(int i = input.Length -1; i>=0; i--)
   {
     result  = ((int)(input[i]-'0') * (int)Math.Pow(10, exponent));    
     exponent  ;
    }
    return result;
}

Again: there's no error checking here for things like out-of-bounds or non-numeric inputs.

  • Related