C# values between functions - c#

So Im learning basic C# and wonders how I can return x and y from AGE(); and NUMBER(); and use those variables in Name();
Right now x and y in the Name(); parameters are understandably wrong since there are no local variables in the constructor. But I returned x and y from the function. So how can I use them in the Name function?
namespace CSharp_001
{
class Program
{
public Program()
{
Name(x, y);
AGE();
NUMBER();
}
public int AGE()
{
int x;
Console.WriteLine(" And enter age: ");
x = Console.Read();
return x;
}
public int NUMBER()
{
int y;
Console.WriteLine(" And favorite number: ");
y = Console.Read();
return y;
}
public void Name(int x, int y)
{
Console.WriteLine("Enter your name: ");
string test = Console.ReadLine();
Console.WriteLine("Hi " + test);
}
static void Main(string[] args)
{
new Program();
Console.ReadLine();
}
}
}

In c#, the Type of a value is really important. When you read from the console, you get a string. However, your Age() and NUMBER() functions return ints. A function that is declared to return an int cannot return a string. You need to convert those values to int before you can return them:
public int AGE() {
Console.WriteLine(" And enter age: ");
return int.Parse(Console.Read());
}
After you fix both functions, you can call Name() like this:
public Program()
{
int x = AGE();
int y = NUMBER();
Name(x, y);
}
or like this:
public Program()
{
Name(AGE(), NUMBER());
}
In either case, if you want to pass those values to the Name() function, the calls to AGE() and NUMBER() must be resolved before the the call to Name(). The console text indicates you want the prompts in Name() to come first. In that case, you might do this:
public void Name()
{
Console.WriteLine("Enter your name: ");
string test = Console.ReadLine();
Console.WriteLine("Hi " + test);
int age = AGE();
int number = NUMBER();
}
public Program()
{
Name();
}

For educational purposes:
public Program()
{
var age = AGE();
var num = NUMBER();
Name(age, num);
}

When a function returns a value, you need to store it or use it immediately. If you look at your example, in the AGE method, you have
x = Console.Read();
Console.Read is returning the value you're storing in x. But this x is local to the AGE method, nothing else called x will have that value (its scope is local to the AGE method). The AGE method returns this value, but that doesn't mean you can use the variable x anywhere else.
When you call AGE in the Program constructor, you need to save its return value. If you have that value saved, then you can pass it in as an argument to Name.
int age = AGE();
Name(age, y);
(assuming y is set by your call to NUMBER). When Name is called, you'll be able to use x, and it will have the value you passed in (which above, is called age).

A few comments:
Console.Read only read one character and returns the UTF-16 code of that character - you should use Console.ReadLine instead and parse the results if necessary.
Functions should be named to describe what they do, so GetAge and GetName would be more appropriate function names
Constructors should only be used to initialize the object to a usable state. Your code should either be in the Main function or in a separate function of Program that Main calls.
variables should have meaningful names. x and y do not give any indication of what they represent.
So something like this would be more appropriate:
class Program
{
public void Run()
{
int age = GetAge();
int number = GetNumber();
GetName(age, number);
}
public int GetAge(){
string age;
Console.WriteLine(" And enter age: ");
age = Console.ReadLine();
return int.Parse(x); // or TryParse and loop until the parse succeeds
}
public int GetNumber(){
string number;
Console.WriteLine(" And favorite number: ");
number = Console.ReadLine();
return int.Parse(number); // or TryParse and loop until the parse succeeds
}
public void Name(int x, int y)
{
Console.WriteLine("Enter your name: ");
string test = Console.ReadLine();
Console.WriteLine("Hi " + test);
}
static void Main(string[] args) {
new Program().Run();
Console.ReadLine();
}
}

Related

Can someone help me fix the error, "There is no argument given that corresponds to the required formal parameter 'num1' of Program.Year (int)

namespace ConsoleApp4
{
class Program
{
public static int Year(int num1)
{
Console.WriteLine("Enter a year.");
num1 = Convert.ToInt32(Console.ReadLine());
if (num1 % 4 == 0)
{
Console.WriteLine("This is a leap year mate.");
Console.ReadLine();
}
return num1;
}
static void Main(string[] args)
{
Console.WriteLine(Year());
Console.ReadLine();
}
}
}
You have an unnecessary parameter on public static int Year(int num1) ... you don't need int num1 because you don't even use it. But the error message is because you called Year without giving it a parameter. Your parenthesis were empty:
Year()
It would work if you used Year(0) or gave it some kind of other int parameter, but as you're not even using the parameter you should delete it:
public static int Year() { /* ... your code here */ }
But your error message is what you get whenever you try to call methods or constructors without supplying the proper arguments.
You don't need an input parameter in Year method. Remove it and try this
public static int Year()
{
Console.WriteLine("Enter a not leap year.");
var num1 = Convert.ToInt32(Console.ReadLine());
while (num1 % 4 == 0)
{
Console.WriteLine("This is a leap year mate. Try again");
num1 = Convert.ToInt32(Console.ReadLine());
}
return num1;
}
static void Main(string[] args)
{
Console.WriteLine(Year());
Console.WriteLine("Press any key to exit");
Console.ReadLine();
}

Beginner to Array c#

I don't really understand arrays and I need to create a variable of type 'array of songs' then initialize it to a new Array so it can store 4 references to Songs. How would I then create a loop that would run enough times to fill the array whilst calling the InputSOngDetails() method and store the return value in that method?
namespace Songs
{
class Program
{
static void Main(string[] args) {
InputSongDetails();
}
static Song InputSongDetails()
{
Console.WriteLine("What is the name of your song");
string name = Console.ReadLine();
Console.WriteLine("What is the artists name");
string artist = Console.ReadLine();
int records;
Console.WriteLine("How many records did it sell");
while (!int.TryParse(Console.ReadLine(), out records) || records < 0)
{
Console.WriteLine("That is not valid please enter a number");
}
return new Song(name, artist, records);
}
}
}
This is my Songs class if needed
namespace Songs
{
class Song
{
string name;
string artist;
int copiesSold;
public Song(string name, string artist, int copiesSold)
{
this.name = name;
this.artist = artist;
this.copiesSold = copiesSold;
}
public Song()
{
}
public string GetArtist()
{
return artist;
}
public string GetDetails()
{
return $"Name: {name} Artist: {artist} Copies Sold: {copiesSold},";
}
public string GetCertification()
{
if (copiesSold<200000)
{
return null;
}
if (copiesSold<400000)
{
return "Silver";
}
if (copiesSold<600000)
{
return "gold";
}
return "Platinum";
}
}
}
Fist, initialize your array of songs with new Song[ length ], then a simple for-loop will suffice.
static void Main(string[] args)
{
Song[] songs = new Song[4];
for(int i = 0; i < songs.Length; i++)
{
songs[i] = InputSongDetails();
}
}
Or as the commenters suggest, just use a variable-length List<Song>.
static void Main(string[] args)
{
List<Song> songs = new List<Song>();
for(int i = 0; i < 4; i++)
{
songs.Add(InputSongDetails());
}
}
Once you've mastered the basics, you can also accomplish this with a bit of Linq (though I wouldn't actually recommend it in this case):
static void Main(string[] args)
{
var songs = Enumerable.Range(0, 4)
.Select(i => InputSongDetails())
.ToList();
}
This is not really an answer as much as it is a tip for getting input from the user in a console application which might be useful to you (well, the answer is in the last code snippet, but p.s.w.g has already covered that very well).
Since an interactive console session usually ends up with a lot of Console.WriteLine("Ask the user a question"); string input = Console.ReadLine();, and, as you've already done very well, include some validation on the input in some cases, I've found it handy to write the following methods below.
Each of them take in a string, which is the prompt for the user (the question), and return a strongly-typed variable that represents their input. Validation (when needed) is all done in a loop in the method (as you've done):
private static ConsoleKeyInfo GetKeyFromUser(string prompt)
{
Console.Write(prompt);
var key = Console.ReadKey();
Console.WriteLine();
return key;
}
private static string GetStringFromUser(string prompt)
{
Console.Write(prompt);
return Console.ReadLine();
}
public static int GetIntFromUser(string prompt = null)
{
int input;
int row = Console.CursorTop;
int promptLength = prompt?.Length ?? 0;
do
{
Console.SetCursorPosition(0, row);
Console.Write(prompt + new string(' ', Console.WindowWidth - promptLength - 1));
Console.CursorLeft = promptLength;
} while (!int.TryParse(Console.ReadLine(), out input));
return input;
}
With these methods in place, getting input is as simple as:
string name = GetStringFromUser("Enter your name: ");
int age = GetIntFromUser("Enter your age: ");
And it makes writing the method to get a Song from the user that much easier:
private static Song GetSongFromUser()
{
return new Song(
GetStringFromUser("Enter song name: "),
GetStringFromUser("Enter Artist name: "),
GetIntFromUser("Enter number of copies sold: "));
}
So now our main method just looks like (and this is the answer to your question):
private static void Main()
{
var songs = new Song[4];
for (int i = 0; i < songs.Length; i++)
{
songs[i] = GetSongFromUser();
}
Console.WriteLine("\nYou've entered the following songs: ");
foreach (Song song in songs)
{
Console.WriteLine(song.GetDetails());
}
GetKeyFromUser("\nDone! Press any key to exit...");
}
Additionally, here are some suggestions for improving the Song class.

If statements and methods

first time posting and have a question about if statements with methods.
I have been trying multiple ways of doing this and haven't gotten it to work. I am trying to call methods based on if the user types a number between 1 and 6. This is what I got so far, please don't judge the dialogue of the calculator (I'm only 14).
class Program
{
static void Main(string[] args)
{
Console.WriteLine(Work());
}
public static void Work(int input)
{
if (input < 0)
{
Console.WriteLine("Please enter a number between 1 and 6");
}
else if (input == 1)
{
Console.WriteLine(Add());
}
else if (input == 2)
{
Console.WriteLine(Subtract());
}
}
public static int Add()
{
Console.WriteLine("Hey bro, need a new number man!");
string input1 = Console.ReadLine();
Console.WriteLine("Gnarly dude, how 'bout a second one?");
string input2 = Console.ReadLine();
Console.WriteLine("Here botine-shake, there is your final number.");
int num1 = int.Parse(input1);
int num2 = int.Parse(input2);
int result = num1 + num2;
return result;
}
public static int Subtract()
{
Console.WriteLine("Number. Now. Please hurry.");
string input1 = Console.ReadLine();
Console.WriteLine("Need another number. Hurry.");
string input2 = Console.ReadLine();
Console.WriteLine("Here is your number. Now please leave.");
int num1 = int.Parse(input1);
int num2 = int.Parse(input2);
int result = num1 - num2;
return result;
}
public static int Multiply()
{
Console.WriteLine("Gimme that number.");
string input1 = Console.ReadLine();
Console.WriteLine("Ok, how would you like to give me another?");
string input2 = Console.ReadLine();
Console.WriteLine("Here you go baby.");
int num1 = int.Parse(input1);
int num2 = int.Parse(input2);
int result = num1 * num2;
return result;
}
public static decimal Divide()
{
Console.WriteLine("/enter.Num1");
string input1 = Console.ReadLine();
Console.WriteLine("/enter.Num2");
string input2 = Console.ReadLine();
Console.WriteLine("/final.Dividend");
decimal num1 = decimal.Parse(input1);
decimal num2 = decimal.Parse(input2);
decimal result = num1 / num2;
return result;
}
public static int Square()
{
Console.WriteLine("What number do you want SQUARED?");
string input1 = Console.ReadLine();
Console.WriteLine("Here's your square!");
int num1 = int.Parse(input1);
int result = num1 * num1;
return result;
}
public static int Cube()
{
Console.WriteLine("What have thine want CUBED?");
string input1 = Console.ReadLine();
Console.WriteLine("Here, I bestow upon you your cube...");
int num1 = int.Parse(input1);
int result = num1 * num1 * num1;
return result;
}
}
I didn't quite understand what you mean, but there should be something needs to be fixed:
static void Main(string[] args)
{
Console.WriteLine(Work());
}
public static void Work(int input)
......
You can see the Work() is an "Action", not a "Function". Because it returns nothing, so it's not appropriate to WriteLine the result from Work()
By the way, you can see the Work(int input) needs an input, which obviously you didn't provide.
Try This:
static void Main(string[] args)
{
int myInput = int.Parse(Console.ReadLine());
Work(myInput);
}
public static void Work(int input)
{ .....
From the code that you provided it looks like you're not asking for user input before calling your Work method, so nothing will happen since there is no argument being passed to the Work method.
You should try something like this:
static void Main(string[] args)
CaptureUserInput();
}
public static void WriteInstructions() {
Console.WriteLine("Enter a number between 1 and 6 to perform a calculation");
// instruct the user for each available operation
Console.WriteLine("1: Addition");
Console.WriteLine("2: Subtraction");
}
public static void CaptureUserInput() {
WriteInstructions();
// capture the user's input and convert it to an integer
string stringInput = Console.Readline();
int input = int.Parse(stringInput);
// validate that it is a valid integer
if (Enumerable.Range(1,6).Contains(input)) {
// this is a valid number in the range we want, call the Work method
Work(input);
} else {
// the user has entered an invalid entry, prompt them and wait for another attempt
Console.WriteLine("Sorry, that is an invalid option.");
CaptureUserInput();
}
}
Note that this is setup so that you can recursively handle when a user enters something that that's not a number or outside the range from 1 - 6. This will prompt the user they entered something invalid and then wait for the next attempt to enter a number.

Returning string and int from same method

public static int getInfo(string info)
{
string inputValue;
int infor;
Console.WriteLine("Information of the employee: {0}", info);
inputValue = Console.ReadLine();
infor = int.Parse(inputValue);
return infor;
}
In the above code, how can I get the name(string) and salary(int) of a person? Specifications are that I need to call the method twice for the information retrieval.
You can pass it separately or better if you create a class which holds of info and the salary
public static int getInfo(string info,int salary)
or create a class,
public class MyInfo
{
public int info { get; set; }
public int salary { get; set; }
}
and the method signature goes as,
public static int getInfo(MyInfo info)
If you want to return both string and int , better to change the method signature as of type class MyInfo
public static MyInfo getInfo(MyInfo info)
You could make it return a tuple with both values like this:
internal Tuple<int, string> GetBoth(string info)
{
string inputValue;
int infor;
Console.WriteLine("Information of the employee: {0}", info);
inputValue = Console.ReadLine();
infor = int.Parse(inputValue);
return new Tuple<int, string>( infor, inputValue );
}
internal void MethodImCallingItFrom()
{
var result = GetBoth( "something" );
int theInt = result.Item1;
string theString = result.Item2;
}
For returning multiple values from a method we can use Tuples or (DataType, DataType,..).
Tuples are readonly. As a result assigning values is possible only via constructor at the time of declaration.
Below example is using multiple data types as return type. Which is both read and write enabled.
public (string, int) Method()
{
(string, int) employee;
employee.Item1="test";
employee.Item2=40;
return employee;
}
You can call the above method in your main code, as shown below:
static void Main(string[] args)
{
(string name,int age) EmpDetails = new Program().Method();
string empName= EmpDetails.name;
int empAge = EmpDetails.age;
//Not possible with Tuple<string,int>
EmpDetails.name = "New Name";
EmpDetails.age = 41;
}
However, the best practice is to use class with properties, as mentioned in above answers.
public static void Main(string[] args)
{
string eName, totalSales;
double gPay, tots, fed, sec, ret, tdec,thome;
instructions();
eName = getInfo("Name");
totalSales = getInfo("TotalSales");
tots = double.Parse(totalSales);
gPay = totalGpay(tots);
}
public static string getInfo(string info)
{
string inputValue;
Console.WriteLine("Information of the employee: {0}", info);
inputValue = Console.ReadLine();
return inputValue;
}
This is what was required. Could have done with other tricks mentioned by you guys. Anyway thank you.
Why dont you just return a String array with a size of 2? at the first (array[0]) there is the string and at the second (array[0]) there is the int...
public static string[] GetInfo (string info)
I hope I understood your question right ^^
you need to create a person class and read name and salary
public class Person
{
public string Name {get; set;}
public decimal Salary {get; set;}
}
and your function will be:
public static Person getInfo(string info)
{
string inputName;
string inputSalary;
Console.WriteLine("Information of the employee: {0}", info);
Console.WriteLine("Name:");
inputName = Console.ReadLine();
Console.WriteLine("Salary:");
inputSalary = Console.ReadLine();
Person person = new Person();
person.Name = inputName;
person.Salary = int.Parse(inputSalary);
return person;
}
If you want one method to return different types of information, then I would use generics:
public static T GetInfo<T>(string name);
// This can be called as following:
string name = GetInfo<string>("name");
int salary = GetInfo<int>("salary");
There's one problem, though: Console.ReadLine returns a string, while our method could return any type. How can it convert a string to its 'target' type? You could check T and write custom logic for all types you want to support, but that's cumbersome and brittle. A better solution is to let the caller pass in a little function that knows how to transform a string into a specific type:
public static T GetInfo<T>(string name, Func<string, T> convert);
// This can be called as following:
string name = GetInfo<string>("name", s => s);
int salary = GetInfo<int>("salary", int.Parse);
Now how do you implement that method?
public static T GetInfo<T>(string name, Func<string, T> convert)
{
Console.WriteLine("Please enter " + name);
string input = Console.ReadLine();
return convert(input);
}
A few notes:
Type parameters are often just named T, but I find it useful to give them more descriptive names, such as TInfo.
The <string> and <int> parts can be left out in the second example, because the compiler has sufficient information to infer their types.
I've left our error handling to keep the examples short and simple. In production code, you'll want to come up with a strategy to handle invalid input, though.

C# Constructors and Contexes

I am trying to create a console application that converts centimeters to meters
Here are my objectives
Store number of centimeters entered in an attribute
Use a default constructor to store zero in the attribute that stores the number of centimeters meters entered
Use a primary constructor to accept and store number of centimeters entered.
A function call getMeters to return the number of meters
A function called Remainder to get the number of centimeter remanding after conversion
A function called Printout that will display the results
The application should carry on accepting values for conversion until the user decides to end it.
What I have so far:
using System;
namespace Conv
{
public class Centimeter
{
public int cmvar;
public Centimeter()
{
cmvar = 0;
}
}
//primary const to be added
public class MeterToCenti
{
public static void Main()
{
char choice;
char n = 'n';
do
{
Console.WriteLine("Do you want to continue? (y/n)");
//choice = Console.ReadLine();
choice = Console.ReadKey().KeyChar;
Centimeter c = new Centimeter();
Console.WriteLine("enter value in centimeters");
c.cmvar = int.Parse(Console.ReadLine());
Printout();
}
while(choice.CompareTo(n) == 0);
}
public static void getMeterst()
{
int meters = c.cmvar / 100;
}
public static void Remainder ()
{
int cmremain = c.cmvar % 100;
}
public static void Printout()
{
Console.WriteLine("{0} Meters and {1} Centimeters", meters, cmremain);
}
}
}
I am getting errors regarding:
prog.cs(24,5): warning CS0168: The variable `meters' is declared but never used
prog.cs(41,11): error CS0103: The name `c' does not exist in the current context
prog.cs(41,2): error CS0103: The name `meters' does not exist in the current context
prog.cs(47,24): error CS0103: The name `c' does not exist in the current context
prog.cs(53,61): error CS0103: The name `meters' does not exist in the current context
prog.cs(53,69): error CS0103: The name `cmremain' does not exist in the current contex
Any help would be appreciated.
In some programming languages, a context is usually defined by { and }, meaning that given this:
{
int a = ...
}
a exists specifically within that block. Assuming that no other variable named a has been declared outside the braces, doing something like so:
{
int a = ...
}
print(a)
Will result in a fault, since a no longer exists.
In your case for instance, you are declaring the following variable: Centimeter c = new Centimeter();. Notice that this is enclosed within the do...while scope, so it exists only in there. Thus, when you try to access your variable from another method, which has its own scope, you get the exception you are getting.
To start solving the issue, you should move the 3 methods getMeterst, Remainder and Printout in their appropriate class, which is Centimeter.
I would recommend you start by looking at some tutorials, since you have other issues with your code.
As pointed out by #user2864740, different languages treat scopes differently. Taking Javascript in consideration:
function hello()
{
{
var i = 44;
}
{
alert(i);
}
}
Yields an alert with the value of 44.
However, the code below does not compile in C#:
private static void Hello()
{
{
int i = 0;
}
{
Console.WriteLine(i); //The name i does not exist in the current context.
}
}
you've got a lot of issues with scope in your code, when you declare something, it can (as a rule) only be accessed inside whatever set of brackets you declare it in, so when you try and access c and cmremainand things like that without specifying their location or accessing them correctly you get errors like this.
I have working code below, but feel free to ask any extra questions as to 'why' this works.
using System;
namespace Conv
{
public class Centimeter
{
public int cmvar;
public Centimeter()
{
cmvar = 0;
}
}
//primary const to be added
public class MeterToCenti
{
public static void Main()
{
char choice;
char n = 'n';
do
{
Centimeter c = new Centimeter();
Console.WriteLine("enter value in centimeters");
c.cmvar = int.Parse(Console.ReadLine());
Printout(c);
Console.WriteLine("Do you want to continue? (y/n)");
choice = Console.ReadKey().KeyChar;
Console.WriteLine();
}
while (choice != n);
}
public static int getMeters(Centimeter c)
{
int meters = c.cmvar / 100;
return meters;
}
public static int Remainder(Centimeter c)
{
int cmremain = c.cmvar % 100;
return cmremain;
}
public static void Printout(Centimeter c)
{
Console.WriteLine("{0} Meters and {1} Centimeters", getMeters(c), Remainder(c));
}
}
}
you need to learn oriented object programming before programming any oop language.
Basic is good but polute your mind by not thinking object, but sequencial...
Here is your code fixed
using System;
namespace Conv
{
public class Centimeter
{
public int cmvar;
public Centimeter()
{
cmvar = 0;
}
public Centimeter(int mm)
{
cmvar = mm;
}
public int getMeterst()
{
return cmvar / 100;
}
public int Remainder()
{
return cmvar % 100;
}
public void Printout()
{
Console.WriteLine("{0} Meters and {1} Centimeters", this.getMeterst(), this.Remainder());
}
}
public class MeterToCenti
{
public static void Main()
{
char choice;
char n = 'n';
do
{
Console.WriteLine("Do you want to continue? (y/n)");
choice = Console.ReadKey().KeyChar;
Console.WriteLine(); // for pure design needs
Centimeter c = new Centimeter();
Console.WriteLine("enter value in centimeters");
c.cmvar = int.Parse(Console.ReadLine());
c.Printout();
}
while (choice != n);
}
}
}

Categories