Long story short, I am making an ATM application for a school assignment. Bank account information needs to be stored into a file to keep those account balances up to date.
I have two questions - (1) In the serialization process I get an error on line 49 that says:
(field)Account[] RunAccount.acctArray
An object reference is required for the non-static field, method, or property 'RunAccount.acctArray'
(2) Do my read-in and read-out serialization locations make sense?
I am very new at this and feel like I have no idea what I am doing so all advice is appreciated and welcome. Thanks!
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml.Serialization;
namespace Bank_Midterm_Project
{
public class RunAccount
{
Account[] acctArray = new Account[3];
private static int i;
bool acctscreated = false;
bool acctsloaded = false;
private object test;
public static void Main(String[] args)
{
RunAccount ra = new RunAccount();
int input;
do
{
Console.WriteLine("Please enter a choice:");
Console.WriteLine("1) Populate Accounts");
Console.WriteLine("2) Load Accounts From File");
Console.WriteLine("3) Select Account");
Console.WriteLine("4) Exit");
input = Convert.ToInt32(Console.ReadLine());
if (input == 1 && ra.acctscreated == false)
{
ra.populateArray();
}
else if (input == 2 && ra.acctsloaded == false)
{
ra.readArray();
}
else if (input == 3 && ra.acctscreated == true)
{
ra.pickAccountMenu();
}
else if (input == 4)
{
Stream FileStream = File.Create("test.xml");
XmlSerializer serializer = new XMLSerializer(typeof(Account[]));
serializer.Serialize(FileStream, acctArray);
FileStream.Close();
}
else
{
if (input == 1 && ra.acctscreated == true)
{
Console.WriteLine("You have already populated the accounts. Please try again.");
}
else if (input == 2 && ra.acctscreated == true)
{
Console.WriteLine("You have already loaded the accounts. Please try again.");
}
else if (input == 3 && ra.acctscreated == false)
{
Console.WriteLine("You must create the accounts first. Please try again.");
}
}
} while (input != 5);
//ATM atm = new ATM();
//atm.topMenu();
//ra.writeArray();
//{
//}
}
//private void readArray()
//{
// throw new NotImplementedException();
public void readArray()
{
Stream FileStream = File.OpenRead("test.xml");
XmlSerializer deserializer = new XmlSerializer(typeof(Account[]));
acctArray = (Account[])deserializer.Deserialize(FileStream);
FileStream.Close();
}
//}
public void populateArray()
{
//int[] acctArray = new int[3];
//prompt for username
Console.WriteLine("Please enter three account numbers, separated by spaces:");
string[] tokens = Console.ReadLine().Split();
for (int i = 0; i < acctArray.Length; i++)
{
acctArray[i] = new Account(tokens[i]);
}
acctscreated = true;
}
public void pickAccountMenu()
{
string sinput = null;
int input = -1;
while (input != 4)
{
Console.WriteLine("Please enter 0, 1, or 2 for your account. 4 to quit.");
sinput = Console.ReadLine();
input = Convert.ToInt32(sinput);
if (input != -99)
{
acctArray[input].menu();
}
}
}
}
internal class XMLSerializer : XmlSerializer
{
public XMLSerializer(Type type) : base(type)
{
}
}
}
Use ra.acctArray. You have to access that property using the class instance variable.
Related
for a school project i am building a c# code with a login, multiple users and a database, but the problem is everytime i login it shows the menu (partly) and it also
shows the login and after 3 times, no matter good or false it exits the program my teacher told me i needed to break it somewhere, heres the code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace UserId
{
class Program
{
static void Main (string[] args)
{
Boolean loginOK = Login();
if (loginOK)
{
hoofdMenu();
} else
{
Console.WriteLine("no, exit program");
}
}
static Boolean Login()
{
Boolean loginOK = true;
int MaxAttempts = 0;
for (int i = 0; i < 3; i++)
do
{
Console.WriteLine("Type username");
String User = Console.ReadLine();
Console.WriteLine("Type password");
String Pass = Console.ReadLine();
Console.Clear();
if (User == "ad" && Pass == "min")
{
loginOK = true;
hoofdMenu();
}
}
while (MaxAttempts > 2);
if (loginOK)
{
return true;
}
else
{
return false;
}
}
static void hoofdMenu()
{
Console.Clear();
Console.WriteLine("Hello admin");
Console.WriteLine("___________________________________________");
List<string> menuItem = new List<string>()
{
"UserInterface",
"Buying menuu",
"storage",
"Exit the Enivoriment",
};
}
}
}
I guess you just need a single loop that counts from zero to three. By "you need to break somewhere" your teacher ment if the credentials are correct, use break to exit the loop, even if you´re at the first iteration. So this should do it:
static Boolean Login()
{
bool loginOK = false;
for (int i = 0; i < 3; i++)
{
Console.WriteLine("Type username");
String User = Console.ReadLine();
Console.WriteLine("Type password");
String Pass = Console.ReadLine();
Console.Clear();
if (User == "ad" && Pass == "min")
{
loginOK = true;
hoofdMenu();
break; // <------------- see her, you exit the loop
}
}
return loginOk;
}
Alternativly instead of the break you can also use return true, which will also exit the loop and return true.
I am having an issue where my method is running endlessly i have tested and it runs through the do while loop fine and terminates, but despite it having a return; statement. My program is not ending the method and returning to main.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApp2
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Hello, What would you like to do?\n1. add a phonebook entry.\n2. search for a specific phonebook entry.\n3. see all phonebook entries.\n4. quit.");
var choice = Console.ReadLine();
int Choice;
var END = "";
do
{
if (int.TryParse(choice, out Choice) && Choice >= 1 && Choice <= 4)
{
switch (Choice)
{
case 1:
addName();
Choice = 0;
break;
case 2:
findName();
break;
case 3:
seeNames();
break;
case 4:
END = "123898761hgasdbfasd";
break;
default:
Console.WriteLine("Hello, What would you like to do?\n1. add a entry.\n2. search for a specific entry.\n3. see all entries.\n4. quit.");
break;
}
}
else { Console.WriteLine("Hello, What would you like to do?\n1. add a entry.\n2. search for a specific entry.\n3. see all entries.\n4. quit.");
choice = Console.ReadLine();
}
}while(END != "123898761hgasdbfasd");
}
private static void seeNames()
{
throw new NotImplementedException();
}
private static void findName()
{
throw new NotImplementedException();
}
private static void addName()
{
int place = 1,end = 0;
string name = null, address = null, numer = null;
do {
switch (place)
{
case 1:
Console.WriteLine("What name would you like to add?");
var User = Console.ReadLine();
Console.WriteLine("You entered {0} is that right?", User);
name = User;
User = Console.ReadLine();
if (User == "y" || User == "Y") { place = 2; }
else { place = 1; }
break;
case 2:
Console.WriteLine("What address would you like to add?");
User = Console.ReadLine();
address = User;
Console.WriteLine("You entered {0} is that right?", User);
User = Console.ReadLine();
if (User == "y" || User == "Y") { place = 3; } else { place = 2; }
break;
case 3:
Console.WriteLine("What phone number would you like to add?");
User = Console.ReadLine();
Console.WriteLine("You entered {0} is that right?", User);
numer = User;
User = Console.ReadLine();
if (User == "y" || User == "Y") { place = 4; } else { place = 3; }
break;
case 4:
using (System.IO.StreamWriter file = new System.IO.StreamWriter("Addressbook.txt", true))
{ file.WriteLine("Name : {0} Address: {1} Phone-Numer: {2}", name, address, numer); file.Close(); }
Console.WriteLine("Would you like to subbmit another entry?");
User = Console.ReadLine();
if (User == "y" || User == "Y") { place = 1; }
else { end = 5; return; }
break;
default:
break;
}
} while (end != 5);
return;
}
}
}
After reaching place 4 and telling the program i do not want to input another address it loops back and ask for another name. I cant seem to break this loop and cause the program to go back to the main program(main is a 4 choice menu that call other methods.)
There is an issue with my current code, not sure how I can keep looping through my code while the ID length != 8 and the ID number is already taken. This may be as simple as adding in a new procedure but I am unsure.
static void GetIDInput(ref int ID)
{
int tempID = 0;
while (tempID.ToString().Length != 8)
{
Console.WriteLine("Please enter your desired ID number");
tempID = Convert.ToInt32(Console.ReadLine());
}
ID = tempID;
}
static void AddStock()
{
int stockQuantity = 0;
double stockPrice = 0.00;
string stockName = "";
string s = ""; // Being Lazy here, to convert to when needed.
int tempID = 0;
int IDNumber = 0;
string lineValues;
bool taken = false;
GetIDInput(ref tempID);
using (StreamReader sr = new StreamReader("Stockfile.txt"))
{
while (sr.EndOfStream == false && taken != true)
{
lineValues = sr.ReadLine();
if (lineValues.Contains(tempID.ToString()))
{
taken = true;
}
else
{
taken = false;
}
}
if (taken == false)
{
IDNumber = tempID;
}
else if (taken == true)
{
Console.WriteLine("Sorry this ID is already taken, try again");
// Want to re-loop here but not sure how...
}
}
using (StreamWriter sw = new StreamWriter("Stockfile.txt", true))
{
s = IDNumber.ToString();
sw.Write(s + "\t"); // Will only accept an 8 figure digit so is safe to have a single value here.
using (StreamWriter sw = new StreamWriter("Stockfile.txt", true))
{
s = IDNumber.ToString();
sw.Write(s + "\t"); // Will only accept an 8 figure digit so is safe to have a single value here.
while (stockName.Length <= 2) // No fancy brands here......
{
Console.Write("Please enter the name of the stock: ");
stockName = Console.ReadLine();
}
s = stockName;
sw.Write(s + "\t");
while (stockQuantity < 1) // Running a small shop here...
{
Console.Write("Please enter the quanity of stock: ");
stockQuantity = Convert.ToInt32(Console.ReadLine());
}
s = stockQuantity.ToString();
sw.Write(s + "\t");
while (stockPrice < 0.01) // Running a very small shop....
{
Console.Write("Please enter the price of the stock: ");
stockPrice = Convert.ToDouble(Console.ReadLine());
}
s = stockPrice.ToString();
sw.Write(s + "\t");
sw.WriteLine(); // TO create the new line.....
}
Purpose of this is to check that in the file the ID number hasn't already been taken as that would be an error for when a user looks up.
Just think about the words you said yourself
Keep looping through my code while the ID length != 8 and the number
is taken
And shuffle exactly what you have around to do that.
I took the liberty to ditch the ref param as well, feel free to put it back
static int GetIDInput()
{
int tempID = 0;
bool taken = true;
bool isInputValid = false;
while (taken == true && isInputValid == false)
{
Console.WriteLine("Please enter your desired ID number");
tempID = Convert.ToInt32(Console.ReadLine());
if (tempID.ToString().Length != 8)
{
isInputValid = false;
Console.WriteLine("ID number must be 8 digits long.")
}
else
{
isInputValid = true;
}
if (isInputValid) // this wont run if the input wasnt 8 characters, so the loop will restart
{
using (StreamReader sr = new StreamReader("Stockfile.txt"))
{
while (sr.EndOfStream == false && taken != true)
{
lineValues = sr.ReadLine();
if (lineValues.Contains(tempID.ToString()))
{
taken = true;
}
else
{
taken = false;
}
}
if (taken == false)
{
ID = tempID;
}
else if (taken == true)
{
Console.WriteLine("Sorry this ID is already taken, try again");
// statements will lead us back to the while loop and taken == true so it will run again
}
}
}
}
return tempID;
}
static void AddStock()
{
int stockQuantity = 0;
double stockPrice = 0.00;
string stockName = "";
string s = ""; // Being Lazy here, to convert to when needed.
int IDNumber = 0;
string lineValues;
IDNumber = GetIDInput();
using (StreamWriter sw = new StreamWriter("Stockfile.txt", true))
{
s = IDNumber.ToString();
sw.Write(s + "\t"); // Will only accept an 8 figure digit so is safe to have a single value here.
using (StreamWriter sw = new StreamWriter("Stockfile.txt", true))
{
s = IDNumber.ToString();
sw.Write(s + "\t"); // Will only accept an 8 figure digit so is safe to have a single value here.
while (stockName.Length <= 2) // No fancy brands here......
{
Console.Write("Please enter the name of the stock: ");
stockName = Console.ReadLine();
}
s = stockName;
sw.Write(s + "\t");
while (stockQuantity < 1) // Running a small shop here...
{
Console.Write("Please enter the quanity of stock: ");
stockQuantity = Convert.ToInt32(Console.ReadLine());
}
s = stockQuantity.ToString();
sw.Write(s + "\t");
while (stockPrice < 0.01) // Running a very small shop....
{
Console.Write("Please enter the price of the stock: ");
stockPrice = Convert.ToDouble(Console.ReadLine());
}
s = stockPrice.ToString();
sw.Write(s + "\t");
sw.WriteLine(); // TO create the new line.....
}
I didn't actually run this so you may need to error check.
You can use this code. It will keep asking for an ID until the user inputs one that is not already used:
//Get the input
static int GetIDInput()
{
int id;
do
{
Console.WriteLine("Please enter your desired ID number");
id = Convert.ToInt32(Console.ReadLine());
}
while (isIDAlreadyUsed(id));
return id;
}
// Check if ID is already used
public static bool isIDAlreadyUsed(int IDToCheck)
{
using (StreamReader sr = new StreamReader("Stockfile.txt"))
{
while (!sr.EndOfStream)
{
string lineValues = sr.ReadLine();
if(lineValues.Contains(IDToCheck.ToString())
return true;
}
}
return false;
}
static void AddStock()
{
// Your init
// ...
int id = GetIDInput(); // Get the ID
//... Your logic to apply
Okay for those interested,#plast1k had the original code, just edited for my needs.
static int GetIDInput()
{
int tempID = 0;
bool taken = false;
bool isInputValid = false;
string lineValues;
while (isInputValid == false)
{
Console.WriteLine("Please enter your desired ID number");
tempID = Convert.ToInt32(Console.ReadLine());
if (tempID.ToString().Length != 8)
{
isInputValid = false;
Console.WriteLine("ID number must be 8 digits long.");
}
else if (tempID.ToString().Length == 8)
{
isInputValid = true;
}
if (isInputValid) // this wont run if the input wasnt 8 characters, so the loop will restart
{
using (StreamReader sr = new StreamReader("Stockfile.txt"))
{
while (sr.EndOfStream == false && taken != true)
{
lineValues = sr.ReadLine();
if (lineValues.Contains(tempID.ToString()))
{
taken = true;
}
else
{
taken = false;
}
if (taken == false)
{
}
else if (taken == true)
{
Console.WriteLine("Sorry this ID is already taken, try again");
isInputValid = false;
// statements will lead us back to the while loop and taken == true so it will run again
}
}
}
}
}
return tempID;
}
I would like to call the database for a text and display it. Then let the user edit the displayed text as if she/he opened it in a text editor. Of course at the end I would like to save the edited version back to the database.
Unfortunately all of my ideas were dead ends, so eventually I decided to ask you, professionals and more experienced programmers, to help me as I am really just a beginner.
Here is my starting point:
Database.xml
<?xml version="1.0" encoding="utf-8" ?>
<Database>
<Texts>
<Text Id="00">Default text 00</Text>
<Text Id="01">Default text 01</Text>
<Text Id="02">Default text 02</Text>
</Texts>
</Database>
C# file
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml.Linq;
namespace EditableText
{
class Program
{
static void Main(string[] args)
{
SelectMenuOption();
Console.WriteLine("Thanks for stopping by!");
Console.ReadLine();
}
private static void SelectMenuOption()
{
bool tf = true;
while (tf)
{
Menu();
string userInput = Console.ReadLine().ToLower();
Console.WriteLine("--------------------------------------------------");
if (userInput == "text_00")
{
Console.Write(CallDatabase("00"));
tf = false;
}
else if (userInput == "text_01")
{
Console.Write(CallDatabase("01"));
tf = false;
}
else if (userInput == "text_02")
{
Console.Write(CallDatabase("02"));
tf = false;
}
else if (userInput == "quit")
{
tf = false;
}
else
{
Console.WriteLine("Error");
}
Console.ReadLine();
Console.Clear();
}
}
private static void Menu()
{
Console.WriteLine("You may play or write quit to say bye.");
Console.WriteLine("");
string[] texts = new string[]
{
"Text_00",
"Text_01",
"Text_02"
};
Console.WriteLine("Choose: ");
foreach (var text in texts)
{
Console.Write(" " + text);
}
Console.WriteLine("");
}
private static string CallDatabase(string idNumber)
{
XElement database = XElement.Load(#"Database.xml");
string dText = database.Element("Texts").Elements("Text").Where(x => x.Attribute("Id").Value == idNumber).FirstOrDefault().Value.ToString();
return dText;
}
}
}
Edited
I've tried this:
string text = "It's a text.";
char[] textC = text.ToCharArray();
foreach (var textL in textC)
{
Console.Write(textL);
}
int n = 0;
while (0 <= textC.Length - n)
{
if (Console.ReadKey().Key == ConsoleKey.LeftArrow)
{
Console.SetCursorPosition(textC.Length - n, 0);
n++;
}
}
And the problem was that when the cursor moved, the previous letter disappeared.
private static void SelectMenuOption()
{
bool tf = true;
while (tf)
{
Menu();
string userInput = Console.ReadLine().ToLower();
Console.WriteLine("--------------------------------------------------");
string id = string.Empty;
if (userInput == "text_00")
{
Console.Write(CallDatabase("00"));
id = "00";
tf = false;
}
else if (userInput == "text_01")
{
Console.Write(CallDatabase("01"));
id = "01";
tf = false;
}
else if (userInput == "text_02")
{
Console.Write(CallDatabase("02"));
id = "02";
tf = false;
}
else if (userInput == "quit")
{
tf = false;
}
else
{
Console.WriteLine("Error");
}
var chage = Console.ReadLine();
Replace(id, chage);
Console.Clear();
}
}
private static void Replace(string id, string chage)
{
XmlDocument xml = new XmlDocument();
xml.Load(#"Database.xml");
XmlNodeList elements = xml.SelectNodes("//Text");
foreach (XmlNode element in elements)
{
if (element.Attributes["Id"].Value == id)
{
element.InnerText = chage;
xml.Save("Database.xml");
}
}
}
Replace your functions(SelectMenuOption) from the code below. and Add one more method Replace in it as below. It will work. You can improve the code for sure, I just provided a solution. Hope it will help.
i am trying to pass a add or subtract function to main method args. in cmd if i run the program with 1 it should display the AddFunction and if i press it with 2 it should display the minusFunction. this is what i have done so far im a little stuck
using System;
namespace addSubtractProject
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Welcome to Add and Subtract Program!");
Console.WriteLine("============================");
if (args.Length > 0)
{
if (args[0] == "1")
{
Console.WriteLine("You are using the AddFunction");
(AddTwo);
}
else if (args[0] == "2")
{
Console.WriteLine("You are using the subtractFunction");
(subtractTwo);
Console.ReadLine();
}
int x = 10, y = 5;
int z = AddTwo(x, y); // function that returns a value
int i = subtractTwo(x, y);
}
}
//function Add Two Numbers
static int AddTwo(int a, int b)
{
return (a + b);
}
//function Minus Two Numbers
static int subtractTwo(int a, int b)
{
return (a - b);
}
}
}
With little modification, you can do this:
if (args.Length > 0)
{
int x = 10, y = 5;
if (args[0] == "1")
{
Console.WriteLine("You are using the AddFunction");
Console.WriteLine(string.Format("Result = {0}", AddTwo(x,y) ));
}
else if (args[0] == "2")
{
Console.WriteLine("You are using the subtractFunction");
Console.WriteLine(string.Format("Result = {0}", subtractTwo(x,y) ));
}
}
Hopefully, this can give you some ideas. The code can be improved even further and I'll leave this for you to try by yourself.