What is the meaning of "{0}" in strings? - c#

When I used {0} in following code:
class Program
{
double width;
double height;
public void getData() {
Console.WriteLine("Enter Width:");
width = Convert.ToDouble(Console.ReadLine());
Console.WriteLine("Enter Height:");
height = Convert.ToDouble(Console.ReadLine());
}
public double calcArea() {
return width * height;
}
public void display() {
Console.WriteLine("Area is : {0}",calcArea());
}
}
class Area
{
static void Main(string[] args)
{
Program p = new Program();
p.getData();
p.display();
}
}
The output was:
Enter Width:6Enter Height:9Area is : 54
And when I used {0} in this:
class NewArea
{
static void Main(String[] args) {
double width;
double height;
double area;
Console.WriteLine("Enter Width: ");
width = Convert.ToDouble(Console.ReadLine());
Console.WriteLine("Enter Height: ");
height = Convert.ToDouble(Console.ReadLine());
area = width * height;
Console.WriteLine("Area is: {0}" +area);
}
}
The output was
Enter Width:4Enter Height:5Area is: {0}20
What does {0} mean?

There are two different meaning for {0} as you have used.
Console.WriteLine("Area is : {0}",calcArea());
In above sentence once you give {0} it means that you may provide some value after comma in same sentence as you provide the value 54 after comma so Console figured that and place that value at 0.
In similar way you can provide many values like
Console.WriteLine("Area for Width {0} and Height {1} is {2}",
width, height, calcArea());
OutPut: Area for Width 4 and Height 5 is 20
In another line you used it like
Console.WriteLine("Area is: {0}" +area);
As in this statement format did not find any comma after {0}" instead found + area so it replace varibale area with value and printed {0} as there is not any matching value {0} which should be given after comma like earlier statement.

It's a placeholder for the matching parameter in String.Format and WriteLine
For example:
String.Format("My name is {0} and I love {1}!", "Orel Eraki", "Snooker");
Output:
My name is Orel Eraki and I love Snooker!

String.Format(String,Object[])
The String argument obviously takes your string, then you can insert multiple object values although this is not necessary. The {0} is just a way to signify that the value of the first object argument will be placed there, similarly {1} means the second and {2} the third. It uses array index syntax.
if you write:
String.Format("Value = {0}",val);
and val is an integer with the value of 20 then the output will be:
'Value=20'
but if you write
String.Format("Value = {0}"+val)
then you are not giving two arguments to the method but only one, a concatenated string that consists of the "Value= {0}" string and the return value of the ToString() method of val.
Since there is no second argument the {0} is treated as just a part of the string and not as something with special meaning. That's why the output is: Value = {0}20

It injects the returning value of calcArea() into the string before printing it on the console window

If you use more than one parameter, you need to use {1}, {2}, etc. You might also use one parameter in more than one place by specifying e.g. {0} more than once.

Just see the example below,
static void Main()
{
int a=10;
int b=20;
Console.WriteLine(" The value of A is {0} " ,a);
Console.WriteLine(" The value of A is {0}, the Value of B is {1}",a,b);
Console.Read();
}
see the first WriteLine statement, i'm printing A alone. {0} is the place my printing variable will be seen in output. The same way i have written the second statement with two outputs {0}, {1} So it will be printed accordingly.

Related

Having trouble fixing null reference errors

Im very new to C# and I am trying to complete my assignment but I came across some errors that I don't understand how to fix or even what they are implying.
using System;
public class Assignment1B
{
public static void Main(string[] args)
{
string item_one, itemtwo;
int itemone_quantity, itemtwo_quantity;
float itemone_cost, itemtwo_cost, itemone_total, itemtwo_total;
// Asking first item
Console.Write("What are you buying? ");
item_one = Console.ReadLine();
Console.Write("How many? ");
itemone_quantity = int.Parse(Console.ReadLine());
Console.Write("What do they cost? ");
itemone_cost = float.Parse(Console.ReadLine());
Console.WriteLine();
// Asking second item
Console.Write("What else are you buying? ");
itemtwo = Console.ReadLine();
Console.Write("How many? ");
itemtwo_quantity = int.Parse(Console.ReadLine());
Console.Write("What do they cost? ");
itemtwo_cost = float.Parse(Console.ReadLine());
Console.WriteLine();
// Math
itemone_total = itemone_quantity * (float)itemone_cost;
itemtwo_total = itemtwo_quantity * (float)itemtwo_cost;
// Listing everything
Console.WriteLine("Your list:");
Console.WriteLine("--------");
Console.WriteLine("{0} ({1})", item_one, itemone_quantity);
Console.WriteLine("{0} ({1})", itemone_cost, itemone_total);
Console.WriteLine();
Console.WriteLine("{0} ({1})", itemtwo, itemtwo_quantity);
Console.Write("{0} ({1})", itemtwo_cost, itemtwo_total);
}
}
The assignment wants me to asks you for the name, quantity, and price of two grocery store items. Then display them as a list.
What I have tried:
I have tried looking up the error codes individually to try and see if I can find an example to get a better understanding of why I am getting the error but I haven't found anything that deeply explains everything. Sorry I am still learning and I am open to any advice or tips.
Errors that I have:
item_one = Console.ReadLine(); Warning CS8600: Converting null literal or possible null value to non-nullable type
itemone_quantity = int.Parse(Console.ReadLine()); Warning CS8604: Possible null reference argument for parameter 's' in 'int int.Parse(string s)'.
itemone_cost = float.Parse(Console.ReadLine()); Warning CS8604: Possible null reference argument for parameter 's' in 'float float.Parse(string s)'.
itemtwo = Console.ReadLine(); Warning CS8600: Converting null literal or possible null value to non-nullable type.
itemtwo_quantity = int.Parse(Console.ReadLine()); Warning CS8604: Possible null reference argument for parameter 's' in 'int int.Parse(string s)'.
itemtwo_cost = float.Parse(Console.ReadLine()); Warning CS8604: Possible null reference argument for parameter 's' in 'float float.Parse(string s)'.
You should change the variable names to be more descriptive and related to grocery items, such as itemOneName, itemOneQuantity, itemOnePrice, itemTwoName, itemTwoQuantity, and itemTwoPrice.
In the prompts for item one, use the appropriate variable names instead of "What are you buying?" "How many?", and "What do they cost?"
Similarly, for item two, use the appropriate variable names instead of "What else are you buying?" "How many?", and "What do they cost?".
try changing the output section, change the format to display the list of items in a clearer way, for example:
Console.WriteLine("Your list:");
Console.WriteLine("--------");
Console.WriteLine("Item: {0}, Quantity: {1}, Price: {2}, Total: {3}", itemOneName, itemOneQuantity, itemOnePrice, itemOneQuantity * itemOnePrice);
Console.WriteLine("Item: {0}, Quantity: {1}, Price: {2}, Total: {3}", itemTwoName, itemTwoQuantity, itemTwoPrice, itemTwoQuantity * itemTwoPrice);
something like this in the end?
using System;
public class Assignment1B
{
public static void Main(string[] args)
{
string itemOneName, itemTwoName;
int itemOneQuantity, itemTwoQuantity;
float itemOnePrice, itemTwoPrice, itemOneTotal, itemTwoTotal;
// Asking first item
Console.Write("What is the name of the first item? ");
itemOneName = Console.ReadLine();
Console.Write("How many of {0} do you want? ", itemOneName);
itemOneQuantity = int.Parse(Console.ReadLine());
Console.Write("What is the price of {0}? ", itemOneName);
itemOnePrice = float.Parse(Console.ReadLine());
Console.WriteLine();
// Asking second item
Console.Write("What is the name of the second item? ");
itemTwoName = Console.ReadLine();
Console.Write("How many of {0} do you want? ", itemTwoName);
itemTwoQuantity = int.Parse(Console.ReadLine());
Console.Write("What is the price of {0}? ", itemTwoName);
itemTwoPrice = float.Parse(Console.ReadLine());
Console.WriteLine();
// Math
itemOneTotal = itemOneQuantity * itemOnePrice;
itemTwoTotal = itemTwoQuantity * itemTwoPrice;
// Listing everything
Console.WriteLine("Your list:");
Console.WriteLine("--------");
Console.WriteLine("Item: {0}, Quantity: {1}, Price: {2}, Total: {3}", itemOneName, itemOneQuantity, itemOnePrice, itemOneTotal);
Console.WriteLine("Item: {0}, Quantity: {1}, Price: {2}, Total: {3}", itemTwoName, itemTwoQuantity, itemTwoPrice, itemTwoTotal);
}
}

How do I accept blanks in C#?

I am trying to create a program which calculates the result of exams by taking in the number of marks obtained in each subject. It is almost done but I'm encountering an error that is, if the user just presses enter instead of entering a value, the application wont proceed. Also is there any way to shortening this code?
Console.WriteLine("Danyal's result calculator for students of class IX. Enter the marks requested, if not applicable leave blank and press enter :)");
Console.Write("Enter your Urdu marks: ");
int urdu = int.Parse(Console.ReadLine());
Console.Write("Enter your Maths marks: ");
int maths = int.Parse(Console.ReadLine());
Console.Write("Enter your English Literature marks: ");
int lit = int.Parse(Console.ReadLine());
Console.Write("Enter your Biology marks: ");
int bio = int.Parse(Console.ReadLine());
Console.Write("Enter your Chemistry marks: ");
int chem = int.Parse(Console.ReadLine());
Console.Write("Enter your Islamiat marks: ");
int isl = int.Parse(Console.ReadLine());
Console.Write("Enter your Physics marks: ");
int physics = int.Parse(Console.ReadLine());
Console.Write("Enter your Computer marks: ");
int comp = int.Parse(Console.ReadLine());
Console.Write("Enter your English Language marks: ");
int lang = int.Parse(Console.ReadLine());
Console.Write("Enter your Pakistan Studies marks: ");
int pst = int.Parse(Console.ReadLine());
int total = urdu + maths + lit + lang + bio + chem + physics + isl + comp + pst;
Console.WriteLine("Your total marks are {0} out of 1000", total);
float percentage = total * 100 / 1000;
Console.WriteLine("Your percentage is: {0}%",percentage);
Console.WriteLine("Note: the percentage has been rounded off. Please share this program with other classmates, also I am open to suggestions for creating more helpful programs.");
Console.ReadLine();
I'm not sure what you would want to do in case the user leaves it blank, or enters an invalid value, but you could do something like this.
Dictionary<string,int> grades = new Dictionary<string, int>
{
{ "Urdu", 0 },
{ "Maths", 0 },
{ "English", 0 },
{ "Biology", 0 },
{ "Chemistry", 0 },
{ "Islamiat", 0 },
{ "Physics", 0 },
{ "Computer", 0 },
{ "English Language", 0 },
{ "Pakistan Studies", 0 },
};
foreach (string grade in grades.Keys.ToArray())
{
Console.WriteLine(string.Format("Enter your {0} marks: ", grade));
int mark;
if (int.TryParse(Console.ReadLine(), out mark))
grades[grade] = mark;
}
int total = grades.Sum((g) => g.Value);
In this example, if bad input is used the grade will default to 0. If you wanted to you could change the if try parse to a loop and request a good value until one is entered as well.
This is a clear case of not adhering to the DRY principle. You are repeating operations that are essentially the same, don't do that. Refactor the code so that common patterns or behaviors are solved in one single place.
How would you do that here?
Create a method that prompts the user to enter certain information. What does the user need? A descriptive message of what he has to do. What does the user need to do? Enter a valid input. Ok, with that in mind, the following prototype of a method seems like a good starting point:
private static int GetUserInput(string message) { ... }
Hmmm...enter a valid input. This means we need some sort of validation, so again let's think of how we can solve this:
private static int ValidateUserInput(string input) { ... }
Is this good enough? Well...no quite. What happens if the user enters an incorrect number? There is no convenient way of conveying that the input is not valid to the caller. We could return -1, or we could throw an exception, but both seem offish.
The best solution would be to return two values; one telling us if the input is valid and another telling us what the input is. In c# this isn't very striaghtforward (at least until c# 7 comes along). The way to do it is using out arguments:
private static bool ValidateUserInput(string message, out int input) { ... }
Now this method serves our purpose perfectly. The return value tells us if the input is valid and the out argument input gives us the validated value (or we simply ignore it if the validation failed).
Why are you creating an int variable for each mark if you essentially only want sums and averages? Lets create a List<int> where we store all the marks.
Another option, if you want to keep track of what mark corresponds to what subject, would be to use a Dictionary<string, key> where the key would be the subject name and the value its corresponding mark. But lets use List<int> for now.
With all that in mind we can build up our solution:
public static void ComputeMarksSummary()
{
var marks = new List<int>();
marks.Add(GetUserInput("Enter your Urdu marks: "));
marks.Add(GetUserInput("Enter your Maths marks: : "));
marks.Add(GetUserInput("Enter your English Literature marks: "));
marks.Add(GetUserInput("Enter your Biology marks: "));
marks.Add(GetUserInput("Enter your Chemistry marks: "));
marks.Add(GetUserInput("Enter your Islamiat marks: "));
marks.Add(GetUserInput("Enter your Computer marks: "));
marks.Add(GetUserInput("Enter your English language marks: "));
marks.Add(GetUserInput("Enter your Pakistan studies marks: "));
var total = marks.Sum();
Console.WriteLine("Your total marks are {0} out of 1000", total);
Console.WriteLine("Your percentage is: {0}%", total/10.0); //note the 10.0 to force double division, not integer division where 44/10 would be 4 not 4.4
Console.WriteLine("Note: the percentage has been rounded off. Please share this program with other classmates, also I am open to suggestions for creating more helpful programs.");
//WRONG! Percentage is not rounded off, its truncated: 9/10 is 0 in integer division.
Console.ReadLine();
}
private static int GetUserInput(string message)
{
int mark;
while (true)
{
Console.WriteLine(message);
var input = Console.ReadLine();
if (!ValidateUserInput(input, out mark))
{
Console.WriteLine("Invalid input, please try again.");
}
else
{
return mark;
}
}
}
private static bool ValidateUserInput(string message, out int input)
{
//left as an excerice. Hint: look into int.TryParse(...);
//here you could decide if a blank input should be valid and parsed as zero.
}
Wow, now that seems a lot cleaner....but hey, we can still do a little bit better. Whats up with all those marks.Add(....)? Can't we refactor the code some more? Well yes, we are essentially asking always the same thing, only the subject name changes. How about we do something like this:
public static void ComputeMarksSummary(IEnumerable<string> subjectNames)
{
var marks = new List<int>();
foreach (var subject in sujectNames)
{
marks.Add(GetUserInput(string.Format("Enter your {0} marks: ", subject)));
}
var total = marks.Sum();
Console.WriteLine("Your total marks are {0} out of 1000", total);
Console.WriteLine("Your percentage is: {0}%", total/10.0); //note the 10.0 to force double division, not integer division where 44/10 would be 4 not 4.4
Console.WriteLine("Note: the percentage has been rounded off. Please share this program with other classmates, also I am open to suggestions for creating more helpful programs.");
Console.ReadLine();
}
And you could call it like this:
ComputeMarksSummary(new string[] { "Urdu", "Maths", ... );
Doesn't that seem so much cleaner?

Reading float variable from user input inside a function

I am modifying a simple c# program that shows the area of a rectangle whose width and height you write in the console(initially the width and height's values were given in the program).However, the user input part doesn't seem to work.I have tried Convert.ToInt32() and I even changed the variables to be integers even though they should be float's, thinking that the conversion will work that way, but to no avail.The error I get is :"error CS0266: Cannot implicitly convert type 'double' to 'int'.".
The question is, what do I do to make this work?I think I could just remove the function and just write the code in the main one, but I'm trying to learn to use the functions and I would be thankful if you could show me a way of giving the variable's value the keyboard input without removing the function.
'
class Rectangle
{
// member variables
double length;
double width;
public void Acceptdetails()
{
//read length and width from the keyboard
length = Convert.ToDouble(Console.ReadLine());
width = Convert.ToDouble(Console.ReadLine());
}
public double GetArea()
{
return length * width;
}
public void Display()
{ //display the length width and area
Console.WriteLine("Length: {0}", length);
Console.WriteLine("Width: {0}", width);
Console.WriteLine("Area: {0}", GetArea());
}
}
class ExecuteRectangle
{
static void Main(string[] args)
{
Rectangle r = new Rectangle();
r.Acceptdetails();
r.Display();
Console.ReadLine();
}
}
'
I would suggest using decimal.TryParse()
see this answer for details: Need help with accepting decimals as input in C#
Console.ReadLine() is a function you forgot ()
this should work
length = Convert.ToInt32(Console.ReadLine());
width = Convert.ToInt32(Console.ReadLine());

How to check for a double type response in an if statement

I'm trying to check if the user's response is a double or an int, but the int is specific, whereas the double is not, as I probably made a right mess of explaining it, here's the code:
Console.WriteLine("\n 2) Q: How old is Sally? \n");
int nSallyAge = Convert.ToInt32(Console.ReadLine());
double dSallyAge = Convert.ToDouble((nSallyAge));
if (nSallyAge == 62 || dSallyAge == 62.0)
{
// Increase Score
sUser1Score++;
Console.WriteLine("\n A: Correct, Sally's age is 62, you have been awarded 1 point. \n");
Console.ReadLine();
}
What I'm trying to do, is instead of dSallyAge HAS to equal 62.0, it just has to equal any double figure.
I would approach this problem by first creating a method that gets a double from the user (that will, of course, also accept an int). This removes error handling from your main code.
NOTE in the code below, Math.Truncate can be replaced by Math.Floor, with the same result:
private static double GetDoubleFromUser(string prompt)
{
double input;
while (true)
{
if (prompt != null) Console.Write(prompt);
if (double.TryParse(Console.ReadLine(), out input)) break;
Console.WriteLine("Sorry, that is not a valid number. Please try again.");
}
return input;
}
Then, in my main code, I would get the number from the user, and use the Math.Truncate method to just read the first part of the double passed in by the user (this is what it sounds like you want to do). This means that if the user enters anything from 62 to 62.0 to 62.999, it will truncate the result to '62':
double nSallyAge = GetDoubleFromUser("2) Q: How old is Sally? ");
if (Math.Truncate(nSallyAge) == 62)
{
// Increase Score
sUser1Score++;
Console.WriteLine("A: Correct, Sally's age is 62, you have been awarded 1 point.");
Console.ReadLine();
}
Other alternative ways to use this are:
int sallyAge = Math.Truncate(GetDoubleFromUser("2) Q: How old is Sally? "));
if (sallyAge == 62)
{
// Increase Score
sUser1Score++;
Console.WriteLine("A: Correct, Sally's age is 62, you have been awarded 1 point.");
Console.ReadLine();
}
Or, you could use an input function that returns an int in the first place:
private static int GetIntFromUser(string prompt)
{
return Math.Truncate(GetDoubleFromUser(prompt));
}
In your code above, you are converting the input to an integer and then converting the int result to a double.
Assuming that you are only allowing numerical values to be entered, why not try something like this. This will identify if the input contained decimals or not:
string input = Console.ReadLine();
int iSallyAge;
double dSallyAge;
if (!Int32.TryParse(input, iSallyAge))
{
dSallyAge = Double.Parse(input);
}
You should be using Double.TryParse to parse the user input to a double and then test that value to see whether it's equal to 62.0.
double age;
if (double.TryParse(Console.ReadLine(), out age) && age == 62.0)
{
// age is 62.
// ...
}

C# Variable int assumes a different value

I'm trying to create a simple program to calculate an average. The user should enter a positive number, then I create a loop to sum from 0 to the number entered. Then the average is the total divided by the number entered.
Problem: When I enter a number, for example, 10, the variable becomes 58. To any value that I enter, it always adds 48. Anyone have a clue about this issue?
Here is the code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace inClass1
{
class Loops
{
static void Main(string[] args)
{
int total = 0;
int num;
Console.Write("Enter a positive number: ");
num = Convert.ToInt32(Console.Read());
for (int i = 0; i <= num; i++)
{
total = total + i;
}
double average = total / (double)num;
Console.WriteLine("The average is = " + average);
Console.ReadLine();
}
}
}
It's because Console.Read method reads the first char and returns its ASCII value. And it only reads one char, so you can't read more than one number at the same time. To fix that just use Console.ReadLine to take a string as input:
um = Convert.ToInt32(Console.ReadLine());
In case where the user inputs an invalid number this will fail. To prevent that you can look into int.TryParse method.
The problem is that you are using Console.Read.
That method returns a int, not a string. That int is the Unicode character code of the read character. The overload of Convert.ToInt32 that takes a int looks like this:
public static int ToInt32(int value) {
return value;
}
(Reference Source)
Which means that its just returning the passed value (instead of parsing). Unicode '1' is the number 49.
Instead, use Console.ReadLine which in addition to getting the whole input (not just the first character) will return a string, so that int.Parse is called on it instead of casting when you use Convert.ToInt32.

Categories