I'm writing a code for an ATM project that reads a text file. The text file is written this format:
account number * name * pin * check balance * saving balance
So, I pass it into a method that splits them into an array.
public void linesplitter (string line)
{
string[] split = line.Split('*');
account = int.Parse(info [0]) ;
name = info [1] ;
pin = int.Parse(info [2]) ;
check = info [3] ;
saving = info [4] ;
}
So, when the user enter the account number, it goes to a log in screen where they will enter the name and pin associated with the account number.
My question is how can I compare the name and pin with the account number?
Sample for you.
List<AccountDetails> accountDetails = new List<AccountDetails>();
//Declare class to store your info
public class AccountDetails
{
public String account { get; set; }
public String name { get; set; }
public String pin { get; set; }
public String check { get; set; }
public String saving { get; set; }
}
//This function is a just an example, you need to expand it to fit your solution
public void linesplitter(String line)
{
//You can place your text file reader code here.
//And call this function from Page_Load.
AccountDetails dtl = new AccountDetails();
string[] split = line.Split('*');
dtl.account = int.Parse(info[0]);
dtl.name = info[1];
dtl.pin = int.Parse(info[2]);
dtl.check = info[3];
dtl.saving = info[4];
//Every line from your text file will store to the Global List as declare in 1st line.
accountDetails.Add(dtl);
}
//this is the function that trigger by your Button Event.
//Pass in parameters to this function to get account details.
//So the output for this function, something like
//if(result == null)
// login fail. etc
public AccountDetails GetAccountDetails(String AccountNumber, String Name, String Pin)
{
var result = (from a in accountDetails
where a.account == AccountNumber
&& a.name == Name
&& a.pin == Pin
select a).FirstOrDefault();
return result;
}
As an option, you must gather all information from text file into collection of wrapper class instances, and then after user enteres account number, you find an item in your collection by number, and if such item exists, you expect the desired pin and name, make your validation checks, and etc...
For example you create class:
class AccountInfo
{
public long AccountNumber { get;set; }
public int Pin { get;set; }
public string Name { get;set; }
public string Check { get;set; }
public string Saving { get;set; }
}
And convert yout text data into collection of items:
var textLines = sourceTextData.Split('\r\n').ToList();
var accountsCollection = textLines.Select(i =>
new AccountInfo
{
AccountNumber = Convert.ToDouble(i.Split('*')[0]),
Pin = Int32.Parse(i.Split('*')[1]),
Name = i.Split('*')[2],
Check = i.Split('*')[3],
Saving = i.Split('*')[4]
}).ToList();
Or instead of a list you can prepare a dictionary, where Dictionary keys will be account numbers.
Create a class to store all the account information. As you read the line, create instance of that class and fill up the info and store in the List. Now to compare name and pin you can just use Linq query.
Class AccountInfo
{
public int AccountNumber {get;set;}
public string Name {get;set;}
public int AtmPin {get;set;}
public string Check {get;set;}
public string Saving {get;set;}
}
// Now in your Main program, use that class like this
List<AccountInfo> accountInfoList= new List<AccountInfo>();
foreach(string line in File.ReadAllLines("filename"))
{
AccountInfo ai =new AccountInfo();
string[] split = line.Split('*');
ai.AccountNumber = int.Parse(info [0]) ;
ai.Name = info [1] ;
ai.AtmPin = int.Parse(info [2]) ;
ai.Check = info [3] ;
ai.Saving = info [4] ;
accountInfoList.Add(ai);
}
// Some code to accept name and pin from user
// Now compare name and pine like this
var validationSuccessful = accountInfoList.Any(x=>x.AccountNumber==userEnteredAccountNumber &&
x.Name==userEnteredName &&
x.AtmPin==userEnteredPin);
if(validationSuccessful)
// Display next screen
else
// Display message log in failure
Please keep in mind this is simplest approach. I am assuming you are working on some practice project..Real ATM Project will have lot of security and will do comparison of Pin using Salt and Hash mechanism. It will definitely have some database or service.
As Jannik suggested, this is how you could do comparison without Linq query
bool validationSuccessful=false;
foreach(AccountInfo accountInfo in AccountInfoList)
{
if(accountInfo.AccountNumber==userEnteredAccountNumber &&
accountInfo.Name==userEnteredName &&
accountInfo.AtmPin==userEnteredPin)
{
validationSuccessful = true;
break;
}
}
I prefer you to create a Class for account like the following:
public class Account
{
public int account { get; set; }
public string name { get; set; }
public int pin { get; set; }
public string check { get; set; }
public string saving { get; set; }
}
Then Form a List of accountObjects that includes all the account details from file where the account information ware stored. The iterate the list to check whether there is any matching credentials ware available or not. The code for this complete scenario will be like the following:
List<Account> ATMAccountList = new List<Account>();
foreach (var line in File.ReadAllLines("your Path Here"))
{
ATMAccountList.Add(linesplitter(line));
}
int accountNumberInput = 123, pinInput = 6565;
// This will be the input values from the user
bool matchFound = false;
foreach (var accountItem in ATMAccountList)
{
if (accountItem.account == accountNumberInput && accountItem.pin == pinInput)
{
matchFound = true;
break;
}
}
if (matchFound)
{
//Proceed with account
}
else
{
// display error ! in valid credential
}
Where the method linesplitter will be defined as Like this:
public Account linesplitter(string line)
{
Account AccountObject = new Account();
string[] info = line.Split('*');
AccountObject.account = int.Parse(info[0]);
AccountObject.name = info[1];
AccountObject.pin = int.Parse(info[2]);
AccountObject.check = info[3];
AccountObject.saving = info[4];
return AccountObject;
}
Note :
You can do the same by using LINQ
if (ATMAccountList.Where(x => x.account == accountNumberInput && x.pin == pinInput).Count() == 1)
{
//Proceed with account
}
else
{
// display error ! in valid credentials
}
Here is a basic Console Application that might give you some ideas....
using System;
using System.Collections.Generic;
using System.Data;
using System.IO;
using System.Linq;
using System.Xml.Linq;
namespace ConsoleApplication1
{
class Program
{
//private static XElement AccountData = new XElement("Root");
private static DataSet dataSet = new DataSet();
static void Main(string[] args)
{
DataSet dataSet = new DataSet();
string[] readText = File.ReadAllLines(#"<Path to your account data file>\AccountData.txt");
string strAccountNumber = string.Empty;
string strPin = string.Empty;
string strName = string.Empty;
dataSet.ReadXml(new StringReader(new XElement("Root",
from str in readText
let fields = str.Split('*')
select new XElement("AccountData",
new XAttribute("AccountNo", fields[0]),
new XAttribute("Name", fields[1]),
new XAttribute("Pin", fields[2]),
new XAttribute("ChkBalance", fields[3]),
new XAttribute("SavBalance", fields[4])
)
).ToString()));
do
{
Console.WriteLine("Please enter your Account Number (press 'Q' to exit)");
strAccountNumber = Console.ReadLine().ToLower();
if (dataSet.Tables[0].Select(string.Format("AccountNo = '{0}'", strAccountNumber)).Count() == 1)
{
Console.WriteLine("Please enter your Pin");
strPin = Console.ReadLine().ToLower();
Console.WriteLine("Please enter your Name");
strName = Console.ReadLine();
if (dataSet.Tables[0].Select(string.Format("Pin = '{0}' AND Name = '{1}'", strPin, strName)).Count() == 1)
{
DataRow[] result = dataSet.Tables[0].Select(string.Format("Pin = '{0}' AND Name = '{1}'", strPin, strName));
foreach (DataRow row in result)
{
Console.WriteLine(string.Format("Account Info for :: {0}", strName));
Console.WriteLine("{0}, {1}, {2}, {3}, {4}", row[0], row[1], row[2], row[3], row[4]);
}
}
else
{
Console.WriteLine("Incorrect Details");
}
}
} while (strAccountNumber != "q");
}
}
}
Don't forget the replace the path in.....
string[] readText = File.ReadAllLines ....
with the path to your data.....
Related
Here are the full details of my code:
public partial class Form1 : Form
{
List<Sales> sales = new List<Sales>();
BindingSource bs = new BindingSource();
public Form1()
{
InitializeComponent();
LoadCSV();
bs.DataSource = sales;
dgvSales.DataSource = bs;
}
private void Form1_Load(object sender, EventArgs e)
{
}
private void LoadCSV()
{
string filePath = #"c:\Users\demo\Task3_shop_data.csv";
List<string> lines = new List<string>();
lines = File.ReadAllLines(filePath).ToList();
foreach (string line in lines)
{
List<string> items = line.Split(',').ToList();
Sales s = new Sales();
s.TextBook = items[0];
s.Subject = items[1];
s.Seller = items[2];
s.Purchaser = items[3];
s.purchasedPrice = float.Parse(items[4]);
s.SalePrice = items[6];
s.Rating = items[7];
sales.Add(s);
}
}
}
}
my sales class:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace MichaelSACU301task3
{
internal class Sales
{
public string TextBook { get; set; }
public string Subject { get; set; }
public string Seller { get; set; }
public string Purchaser { get; set; }
public float purchasedPrice { get; set; }
public string SalePrice { get; set; }
public string Rating { get; set; }
}
}
I tried launching it but the error message keeps appearing can someone please help me fix this problem.
Use float.TryParse prior to assigning to purchasedPrice property, if the value can not be converted remember it in a list. In the example below the code to read file data is in a separate class which returns a list of sales and a list of int which is used to remember invalid lines where purchasedPrice data is invalid. You should also consider validating other data and also ensure proper amount of data after performing the line split.
public class FileOperations
{
public static (List<Sales>, List<int>) LoadSalesFromFile()
{
List<Sales> sales = new List<Sales>();
List<int> InvalidLine = new List<int>();
string filePath = #"c:\Users\demo\Task3_shop_data.csv";
List<string> lines = File.ReadAllLines(filePath).ToList();
for (int index = 0; index < lines.Count; index++)
{
var parts = lines[0].Split(',');
// validate purchase price
if (float.TryParse(parts[4], out var purchasePrice))
{
Sales s = new Sales();
s.TextBook = parts[0];
s.Subject = parts[1];
s.Seller = parts[2];
s.Purchaser = parts[3];
s.purchasedPrice = purchasePrice;
s.SalePrice = parts[6];
s.Rating = parts[7];
sales.Add(s);
}
else
{
// failed to convert purchase price
InvalidLine.Add(index);
}
}
return (sales, InvalidLine);
}
}
Call the above code in your form
var (salesList, invalidLines) = FileOperations.LoadSalesFromFile();
if (invalidLines.Count > 0)
{
// use to examine bad lines in file
}
else
{
// uses sales list
}
the error sis probably due the impossiability of float.Parse() parse the items[4] in float
you may track value of items[4] using brake point in VS
I am very new to C#. I am writing a program using visual studio c# where it will first ask the user to enter an employee name. Next, it will pass that name through an API and will retrieve and display the employee signature. I have completed this portion.
Next, the program will ask the user to enter a designated "to" and "from" date. Next, the program should pass the date information as well as the signature obtained previously through a second API and retrieve and display information on to a grid data table accordingly.
For the Grid view data table, I understand that I should be connected to a SQL data server, which I am.
My problem is that
I am not sure how to write a code which will pass three parameters to an API (the "to" and "from" date, and the employee signature). I have tried the code below, however, I receive an error when I try to link the corresponding button to the JSON code to retrieve data. The error states that
"There is no argument given that corresponds to the required formal
parameter 'toDate' of 'WebAPI.GetTime(double, double, string).'
I am not sure how to pass the signature previously obtained from a different API through the new API.
Any help would be much appreciated.
Code for defining the JSON variables:
namespace TimeSheet_Try11_Models
{
// Root myDeserializedClass = JsonConvert.DeserializeObject<Root>(myJsonResponse);
public class OracleHour
{
public string orderNumber { get; set; }
public DateTime dateOfWork { get; set; }
public string description { get; set; }
public string surveyor { get; set; }
public string hourType { get; set; }
public double hours { get; set; }
public int status { get; set; }
public string savedInOlsonTimezone { get; set; }
public double invoicelinevalue { get; set; }
public string articleType { get; set; }
public DateTime dateOfWorkInSavedTimezone { get; set; }
}
public class MyArray
{
public string orderNumber { get; set; }
public string projectnumber { get; set; }
public string noteToInvoicer { get; set; }
public List<object> oracleCosts { get; set; }
public List<OracleHour> oracleHours { get; set; }
}
public class Root1
{
public List<MyArray> MyArray { get; set; }
}
}
Code calling out the JSON:
namespace TimeSheets_Try_11.Controllers
{
class WebAPI
{
public string[] GetTime(double fromDate, double toDate, string username)
{
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
var cookies = FullWebBrowserCookie.GetCookieInternal(new Uri(StaticStrings.UrlNcert), false);
WebClient wc = new WebClient();
wc.Encoding = System.Text.Encoding.UTF8;
wc.Headers.Add("Cookie:" + cookies);
wc.Headers.Add("Content-Type", "application/x-www-form-urlencoded");
wc.UseDefaultCredentials = true;
string url = "";
url = $"{StaticStrings.UrlNcert}?user={username}&fromDate={fromDate:yyyy-MM-dd}&toDate={toDate:yyyy-MM-dd}";
var respons = wc.DownloadString(url);
OracleHour ndata = JsonConvert.DeserializeObject<OracleHour>(respons);
var Get_Odnum = ndata.orderNumber;
var Dt_Work = ndata.dateOfWork;
var hrType = ndata.hourType;
var hr = ndata.hours;
var des = ndata.description;
var surname = ndata.surveyor;
string[] myncertdata = { Get_Odnum, Dt_Work.ToString(), hrType, hr.ToString(), des, surname };
return myncertdata;
}
}
Partial code attempting to connect the corresponding button to retrieve data (the error appears at the very last line):
namespace TimeSheets_Try_11
{
public partial class Form3 : Form
{
WebAPI WA = new WebAPI();
public Form3()
{
InitializeComponent();
webBrowser2.Url = new Uri(StaticStrings.UrlNcert);
}
private void Form3_Load(object sender, EventArgs e)
{
// TODO: This line of code loads data into the 'timesDataSet.NCert_Data' table. You can move, or remove it, as needed.
this.nCert_DataTableAdapter.Fill(this.timesDataSet.NCert_Data);
}
private void dataGridView1_CellContentClick(object sender, DataGridViewCellEventArgs e)
{
}
private void GtData_Click(object sender, EventArgs e)
{
var connetionString = ConfigurationManager.ConnectionStrings["Times"].ConnectionString;
try
{
using (SqlConnection conn = new SqlConnection(connetionString))
{
using (SqlCommand cmd = new SqlCommand())
{
conn.Open();
using (SqlCommand Sqlcmd = new SqlCommand("NCert_Data", conn))
{
Sqlcmd.CommandType = CommandType.StoredProcedure;
int counter; string projectnumber; double hrs; string respname; string describe; string[] prjstat; DateTime dates;
for (counter = 0; counter < (dataGridView1.RowCount) - 1; counter++)
{
hrs = 0;
projectnumber = dataGridView1.Rows[counter].Cells[1].Value.ToString();
prjstat = WA.GetTime(projectnumber);
}
}
}
}
}
}
}
public string[] GetTime(double fromDate, double toDate, string username)
needs 3 parameter but
prjstat = WA.GetTime(projectnumber);
has only one...?
Looks like you have to add 2 more parameters
prjstat = WA.GetTime((double), (double), "text");
double fromDate, but you have "projectnumber" a .toString() ...?
Without knowing how the structure of your table looks like there is no way to know what the parameters are. How ever I think your function call should look like this:
prjstat = WA.GetTime((double)dataGridView1.Rows[counter].Cells["fromDate"], (double)(double)dataGridView1.Rows[counter].Cells["toDate"], dataGridView1.Rows[counter].Cells["username"].toString());
Where ["fromDate"], ["toDate"] and ["username"] should be the correct indexes of your expected data.
You may could loop through the cols and output the data with something like that:
for (counter = 0; counter < (dataGridView1.RowCount) - 1; counter++)
{
for (int i = 0; i < dataGridView1.Columns.Count, i++)
{
if (dataGridView1.Columns[i].HeaderText != null) {
System.Console.WriteLine(dataGridView1.Columns[i].HeaderText);
}
System.Console.WriteLine(dataGridView1.Rows[counter].Columns[i].ValueType.ToString());
System.Console.WriteLine(dataGridView1.Rows[counter].Columns[i].Value.ToString());
}
if (counter == 2) { break; }
}
Or just give some dummy values and look what happens ( :P ):
prjstat = WA.GetTime(0, 0, "bla");
Edit: Please note that .Value can be different types like numbers colors dates or what ever. So you have to cast it to a type (double) or use Convert.XYZ. By ValueType.toString() you maybe know what type it is. Or you already know it at all, no idea... ;)
...should pass the date information as well as the signature obtained previously through a second API and retrieve and display information on to a grid data table accordingly.
Well now I'm confused. Could you clarify if you want to store data received by WA.GetTime to dataGridView1 or do you want to send data to WA.GetTime obtained by the dataGridView1?
Btw.: A DataGridView do not "require" an sql database. It can also use xml as example.
Cannot seem to find where I am going wrong, should have tested earlier pretty sure there is a major logic error here
. I am trying to list countries from a text file based on user input, and I am getting this error, I have tried removing most of the code and tried typing other test codes and still get a major error, no idea what I am doing wrong here if anyone can show me what the issue is here, it would be great thanks. Basically this program is supposed to also list all the countries later if the user input is a capital letter but I can get to that later.
class CountryProgram
{
static void Main(string[] args)
{
CountryList printSearch = new CountryList();
printSearch.findAll();
}
public class CountryList
{
//declare all variable lists for each search
public StreamReader filePath = new StreamReader("countries.txt");
public static List<string> countryItems = new List<string>();
public static List<string> capitalItems = new List<string>();
public static List<string> populationItems = new List<string>();
public static List<string> allItems = new List<string>();
Country memberName = new Country();
//string retriever read all inputs
public string getString()
{
//<<<<<==============Country Search===================>>>>>
Console.WriteLine("Enter the first letter of the countries you wish to search: "); //prompts user to enter the country
string upperCaseInput = Console.ReadLine(); //gets input
string line = ""; //creates a empty string
bool finished = false;
List<string> upperList = new List<string>(); //creates a list for user input chars
foreach (char item in upperCaseInput) //adds all chars into a list named chars
{
if ( Char.IsUpper(item)) //checks if upper case and add to list if true
{
upperList.Add(item.ToString());
memberName.startsWith = true; //Assigns startsWith to true the moment a char entered is uppercase
}
}
//Begin listing countries once startsWith == true
while (((line = filePath.ReadLine()) != null) && (finished = false))
{
if (memberName.startsWith == true) // if upper case in inputted loop through the first column listing countries
{
countryItems.Add("test output"); //supposed to write results based on inputted upper case char item above
}
else //if not upper case show error message and end program
{
finished = true;
}
if (finished == true)
{
Console.WriteLine("Please enter one character in capital letters");
Console.ReadLine();
}
}
//<<<<<==============Capital Search===================>>>>>//
return countryItems.ToString();
}
//executing write to control panel depending on userinput
public void findAll()
{
Console.WriteLine(memberName.getString());
Console.ReadLine();
}
}
class Country : CountryList
{
//list variable properties
public string name { get; set; }
public string capital { get; set; }
public int population { get; set; }
public bool startsWith { get; set; }
public bool capitalHas { get; set; }
public bool lesserPopulation { get; set; }
//list counstructors
public Country()
{
}
public Country(string n, string c, int p)
{
name = n;
capital = c;
population = p;
}
}
Country is derived from CountryList. When you try to create an instance of CountryList, it also tries to create an item of Country (for the memberName field). However, Country also contains a memberName field, and also needs to create it. For every instance of Country, you create another instance of Country until you run out of stack space - StackOverflowException.
There's really no reason why you'd want to derive Country from CountryList. If CountryList is supposed to be a list of countries, just have the list contain the items.
I have never done something like this so I'm really curious on how this can be performed. I imagine it can be either done via regex or in c# somehow...
I have a textual file with data in following format:
12.23.45.56:8080:username:password
12.23.45.56:8080:username:password
12.23.45.56:8080:username:password
12.23.45.56:8080:username:password
I have prepared a class which looks like following:
public class ParsedData
(
public string IP { get; set; }
public string Port { get; set; }
public string Username { get; set; }
public string Password { get; set; }
)
The desired output how I would like it to be is that I can parse each line individually and 1 line should have the data stored in a parsed object (list of ParsedData);
How could do this, and to parse the each line of data individually ?
Can someone help me out ?
var completedList = text.Split(':').Select(pr => new ParsedData
{
IP = pr.ElementAt(0).ToString() // this should be the IP But I'm getting the
// Index was outside the bounds of the array. exception in this part
/*My elements here*/
}).ToList();
It looks like at least one row doesn't have any data in it, maybe there is an empty row in the input data?
Try printing out each row of data before selecting the first element of the array - then you can see which input is causing the exception.
You may use Regex (.+?):(.+?):(.+?):(.+), here example:
using System;
using System.Text.RegularExpressions;
using System.Collections.Generic;
namespace Main {
public struct ParsedData {
public string IP { get; set; }
public string Port { get; set; }
public string Username { get; set; }
public string Password { get; set; }
}
class Prog {
static List<ParsedData> pdl = new List<ParsedData>();
static string file = #"12.23.425.56:90:kukur:psiar%4
151.23.255.52:3131:Zandga:Ikurit
52.23.45.56:5125:Ningame:Mirsga!#
112.223.45.56:4000:Bisgo:One0ne";
static void Main() {
var re = new Regex(#"(.+?):(.+?):(.+?):(.+)");
foreach (Match m in re.Matches(file)) {
pdl.Add(new ParsedData() { IP = m.Groups[1].Value, Port = m.Groups[2].Value, Username = m.Groups[3].Value, Password = m.Groups[4].Value });
Console.WriteLine("IP: " + m.Groups[1] + " PORT: " + m.Groups[2] + " USR_NM: " + m.Groups[3] + " PASS: " + m.Groups[4]);
}
}
}
}
Also I added an List which contains the data.
class Program
{
static void Main(string[] args)
{
//I think you know how to read the file so:
string text =
#"12.23.45.56:8080:username:password
12.23.45.56:8080:username:password
12.23.45.56:8080:username:password
12.23.45.56:8080:username:password";
List<ParsedData> ps = new List<ParsedData>();
text.Split(new char[] { '\r','\n' }, StringSplitOptions.RemoveEmptyEntries).ToList().ForEach(c =>
{
var cols = c.Split(new char[] { ':' }, StringSplitOptions.RemoveEmptyEntries).ToList();
//you can check too if cols have content here
ps.Add(new ParsedData()
{
IP = cols[0]!=null?cols[0]:"", //and check if inside it's content..
Port = cols[1],
Username = cols[2],
Password = cols[3]
});
});
foreach(ParsedData p in ps)
{
Console.WriteLine(p.IP + "\t" + p.Port + "\t" + p.Username + "\t" + p.Password);
}
}
}
public class ParsedData
{
public string IP { get; set; }
public string Port { get; set; }
public string Username { get; set; }
public string Password { get; set; }
}
I think you make misunderstood about the pr, it not array now, it the element in the array.
var text = "12.23.45.56:8080:username:password";
var array = text.Split(':');
var data = new ParsedData()
{
IP = array[0],
Port = array[1],
Username = array[2],
Password = array[3]
};
Is there any solution to use set and get for arraylist ?
I want to put all of my arraylists in one class but then i need them to fill a bidimensional array to use them. (1 list=1 column)
I want to put this
ArrayList listanume = new ArrayList();
In this :
class Beneficiar
{}
And use it to fill an bidimensional array like
listanume -> a[i,0]
I really don't know how to say it right, but this is the idea...
You should do something like that
class Program
{
public static void Main(string[] args)
{
List<Account> accounts = new List<Account>();
Account a1 = new Account { Name = "Peter", Password = "lalala", Mail = "mail#yahoo.com", TotalSold = 100M };
accounts.Add(a1);
}
}
public class Account
{
public string Name { get; set; }
public string Password { get; set; }
public string Mail { get; set; }
public decimal TotalSold { get; set; }
}
To access any account by some field you can do this
string searchNameString = "Peter";
var foundAccount = accounts.FirstOrDefault(x => x.Name == searchNameString);
if (foundAccount != null)
{
//Code which uses found account
}
//Here you will get all accounts with total sold > 1000. You can then iterate over them with for or foreach
var foundAccountsByTotalSold = accounts.Where(x => x.TotalSold > 1000);