Checking if A objects property exist - c#

I was wanted to ask a question cause I can't really find what I'm looking for online. I want to see/check if a student IdNum already exist for example.
I don't know the right term that I'm looking for to google it, and the book I have isn't really that useful as to what to do when needing to do this sort of check.
Here is the code what i have been tried so far :
static void Main(string[] args)
{
Class1[] c1 = new Class1[10]
for (int i = 0; i < c1.Length; i++)
{
Console.WriteLine("enter Student ID");
string text = Console.ReadLine();
int value;
while (!Int32.TryParse(text, out value))
{
Console.WriteLine("ID Was not a Valid ID Number. Try Again");
text = Console.ReadLine();
}
// maybe here say if IdNum exist or not
{
// Try a different number
}
}
}
Class Class1
{
public int IdNum { get; set; }
public int SomethingElse { get; set; }
// and so on
}
Thanks

IEnumerable<Class1> c1 = GetStudents();
string text = Console.ReadLine();
int value;
while (!Int32.TryParse(text, out value))
{
Console.WriteLine("ID Was not a Valid ID Number. Try Again");
text = Console.ReadLine();
}
bool exist = c1.Any(s = > s.IdNum == value);
If you don't want to use linq, you can just rewrite the last line with:
bool exist = false;
foreach (var s in c1)
{
if (s.IdNum == value)
{
exist = true;
break;
}
}

Related

C# Assigning to strings from a public class and list

so far my code does the following.
Ask user for a numeric amount for 'players'
Then asks for names for each of the players which is added to a list and class
I'd like to call those names from the list or class (not really sure how class works) and assign it to a new string. Here's what I got so far:
public class NameVariable
{
public int ID { get; set; }
public string Name { get; set; }
}
class Program
{
static void Main(string[] args)
{
bool IsUserWrong = false;
Console.WriteLine("Write amount of players");
while (!IsUserWrong)
{
int TotalPlayers;
while (!Int32.TryParse(Console.ReadLine(), out TotalPlayers))
{
Console.WriteLine("Value must be numeric.");
}
if (TotalPlayers >= 12 && TotalPlayers <= 16)
{
List<NameVariable> PlayerList = new List<NameVariable>();
for (int index = 0; index < TotalPlayers; index++)
{
Console.WriteLine("Enter player {0}'s name:", index + 1);
PlayerList.Add(new NameVariable
{
Name = Console.ReadLine(),
ID = index
});
}
// string player1 = ???
// string player2 = ???
// and so on for 12-16 players
}
else
{
Console.WriteLine("Please enter a value between 12 and 16.");
}
}
}
}
I know that a foreach loop can be used to display all of the variables in the NameVariable class. Would just like to know how to assign each variable to a different string.
Before using the class I just used the list which worked by using
string player1 = PlayerList[0];
string player2 = PlayerList[1];
// and so on for the remaining players
Thanks in advance!
it's just
string player1 = PlayerList[0].Name;
string player2 = PlayerList[1].Name;
...
Essentially your list contains NameVariable objects. PlayerList[index] gives you the object, and .Name gives you the property value of the object.
If you want a specific player name by a specific ID number, you can use LINQ (just to give you a hint)
string player = PlayerList.Where(p => p.ID == WhateverIDNumber).First().Name;
While the answer to your immediate question, i.e., how to access properties of a class object, is as others have shown, I feel like this code has a bigger problem. That is you're trying to do too much in one function, namely, Main(). So I advice to in fact try and refactor your code so that one function does one thing. Something like:
public static int GetNumberOfPlayers()
{
Console.Write("Enter number of players: ");
int totalPlayers;
while (!Int32.TryParse(Console.ReadLine(), out totalPlayers))
{
Console.WriteLine("Value must be numeric.");
}
return totalPlayers;
}
public static List<NameVariable> GetPlayerList(int num)
{
var list = new List<NameVariable>();
for (int i = 0; i < num; i++)
{
Console.WriteLine("Enter player {0}'s name:", i + 1);
list.Add(new NameVariable
{
Name = Console.ReadLine(),
ID = i
});
}
return list;
}
public static void DisplayPlayers(List<NameVariable> list)
{
foreach(var player in list)
{
Console.WriteLine("Player {0}, Name: {1}", player.ID, player.Name);
}
}
public static void CantThinkOfAGoodName()
{
while (true)
{
int totalPlayers = GetNumberOfPlayers();
if (totalPlayers > 16 || totalPlayers < 12)
{
Console.WriteLine("Please enter a value between 12 and 16.");
}
else
{
var playerList = GetPlayerList(totalPlayers);
DisplayPlayers(playerList);
break;
}
}
}
public static void Main()
{
CantThinkOfAGoodName();
Console.ReadLine();
}
Not sure if it helps but you can use an indexer to get players by name.
public NameVariable this[string name]
Let's say you create a class for the colection
public class NameColection : List<NameVariable>
{
public NameVariable this[string name]
{
get
{
return this.FirstOrDefault(n => n.Name == name);
}
}
}
Then you access players by name
var players = new NameColection()
{
new NameVariable() { ID = 1 , Name = "John" },
new NameVariable() { ID = 2 , Name = "Paul" },
new NameVariable() { ID = 3 , Name = "George" },
new NameVariable() { ID = 4 , Name = "Ringo" }
};
var player1 = players["John"];
As NameColection inhertits from List, you will be able to add, remove or modify items the usual way.

c# how to make my program run through multiple times without setting the amount

Here is my code:
class Main
{
public string Name()
{
string employee = "";
while (employee == "")
{
try
{
Console.Write("Please enter employee name: ");
employee = Console.ReadLine();
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
}
return employee;
}
public float hoursWorked()
{
string yesno = "";
List<float> hWorked = new List<float>();
float hours = 0;
for (int i = 0; yesno == "" || yesno =="Yes"|| yesno== "yes"; i++)
{
try
{
Console.Write("Please enter hours worked: ");
hours = float.Parse(Console.ReadLine());
if (hours > 0)
{
Console.WriteLine("Hours added");
hWorked.Add(hours);
}
else
{
Console.WriteLine("Please enter valid hours");
}
Console.Write("Do you want to add more hours? Please state Yes or No: ");
yesno = Console.ReadLine();
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
}
return hWorked.Sum();
}
}
class Program
{
static void Main(string[] args)
{
Main a = new Main();
string name = a.Name();
float hWorked = a.hoursWorked();
string more = "";
Console.WriteLine("Name: {0}\nHours worked: {1}", name, hWorked);
Console.Write("Add another employee?: ");
more = Console.ReadLine();
if (more == "Yes" || more == "yes")
{
Main b = new Main();
string name1 = a.Name();
float hWorked1 = a.hoursWorked()
Console.WriteLine("Name: {0}\nHours worked: {1}", name, hWorked1);
Console.ReadLine();
}
else
{
Console.ReadLine();
}
}
}
What i want to do is allow the user to answer Yes or No to the question "Add another employee?:" I can do this by just using the if statement you see at the bottom. How am i able to allow this without presetting the number of times they can add another employee?
The code is very rustic. I changed your hoursWorked method just a little do get what you need:
public float hoursWorked()
{
string yesno = "";
List<float> hWorked = new List<float>();
float hours = 0;
do
{
try
{
Console.Write("Please enter hours worked: ");
hours = float.Parse(Console.ReadLine());
if (hours > 0)
{
Console.WriteLine("Hours added");
hWorked.Add(hours);
}
else
{
Console.WriteLine("Please enter valid hours");
}
Console.Write("Do you want to add more hours? Please state Yes or No: ");
yesno = Console.ReadLine();
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
} while (yesno != null && yesno.ToUpper() != "NO");
return hWorked.Sum();
}
I did not change anything else. You can drastically improve this logic.
You could try using do
do
{
input data
} while(some condition to continue)
MSDN documentation
I think part of the problem is that you're mixing the program flow with the work you're trying to do. I have done a quick version which shows the program flow being controlled by Main while using an Employee class to encapsulate the name and list of hours worked.
Note that I have also simplified the input by looking for an empty string to determine when they want to stop entering data, but that could easily be changed to use your yes/no responses if required.
static void Main(string[] args)
{
// Add new employees
while(true)
{
Console.WriteLine("Please enter employee name: ");
var employeeName = Console.ReadLine();
if (string.IsNullOrWhiteSpace(employeeName))
break;
var employee = new Employee(employeeName);
// Add employee hours
while(true)
{
Console.WriteLine("Please enter hours worked: ");
var inputHours = Console.ReadLine();
if (string.IsNullOrWhiteSpace(inputHours))
{
Console.WriteLine("Name: {0}\nHours worked: {1}", employee.Name, employee.HoursWorked.Sum());
break;
}
var hours = float.Parse(inputHours);
if (hours > 0)
{
employee.HoursWorked.Add(hours);
Console.WriteLine("Hours added");
}
else
{
Console.WriteLine("Please enter valid hours");
}
}
}
}
public class Employee
{
private readonly string _name;
public Employee(string name)
{
_name = name;
HoursWorked = new List<float>();
}
public string Name
{
get { return this._name; }
}
public List<float> HoursWorked { get; set; }
}

Trying to figure out how to access list in a different method

This is my Code inside my Class. I'm trying to figure out how to access Questions list in DisplayQuestion. I have a program.cs that display a menu for a quiz and I can't have anything static.
public string Question { get; set; }
public List<string> Choices { get; set; }
public char[] CorrectChoice = { 'A', 'B', 'C', 'D' };
public List<string> Questions { get; set; }
These are my methods inside my class. I will need to access this list multiple times inside this class.
public void NewQuestion()
{
Questions = new List<string>();
Choices = new List<string>();
Console.WriteLine("Enter the question: ");
Questions.Add(Console.ReadLine());
Console.WriteLine("Enter Choice 1 for the question:");
Choices.Add(Console.ReadLine());
Console.WriteLine("Enter Choice 2 for the question: ");
Choices.Add(Console.ReadLine());
Console.WriteLine("Enter Choice 3 for the question: ");
Choices.Add(Console.ReadLine());
Console.WriteLine("Enter Choice 4 for the question:");
Choices.Add(Console.ReadLine());
// Console.WriteLine("Enter the correct choice(A,B,C,D)");
foreach (string choice in Choices)
{
Console.WriteLine();
Console.WriteLine(choice);
}
}
public void DisplayQuestions()
{
foreach(string question in Questions)
{
Console.WriteLine();
Console.WriteLine(question);
}
}
try declaring and initializing it to null in the global section or create a class with proper getter setter methods for it.
Don't feel constrained to do everything in one class. Even a rough, verbose attempt at separating concerns into separate classes helps with readability, maintainability, and sanity. Then, you're just a thoughtful refactor away from good code.
You are using C#, an OBJECT-oriented language. So go with the grain and embrace using objects.
using System;
using System.Collections.Generic;
using System.Linq;
namespace Quiz_StackOverflow
{
class Program
{
static void Main(string[] args)
{
var quizGenerator = new QuizGenerator();
var quiz = quizGenerator.GenerateQuiz();
var quizProctor = new QuizProctor();
var grade = quizProctor.ProctorQuiz(quiz);
Console.WriteLine(grade.ToString());
Console.WriteLine("Done. Press any key to exit.");
Console.ReadKey();
}
}
public class QuizGenerator
{
public Quiz GenerateQuiz()
{
var problems = GenerateProblems();
var quiz = new Quiz()
{
Problems = problems
};
return quiz;
}
private List<Problem> GenerateProblems()
{
List<Problem> problems = new List<Problem>();
int numChoices = InputValidator.GetPositiveNumber("Enter number of problems: ");
for (int i = 0; i < numChoices; i++)
{
Problem problem = GenerateProblem();
problems.Add(problem);
}
return problems;
}
private Problem GenerateProblem()
{
var question = GenerateQuestion();
var choices = GenerateChoices();
var answer = GenerateAnswer(choices);
var problem = new Problem()
{
Question = question,
Choices = choices,
Answer = answer
};
return problem;
}
private string GenerateQuestion()
{
Console.WriteLine("Enter the question: ");
string question = Console.ReadLine();
return question;
}
private List<string> GenerateChoices()
{
List<string> choices = new List<string>();
int numChoices = InputValidator.GetPositiveNumber("Enter number of choices for the question: ");
for (int i=1; i<=numChoices; i++)
{
string choice = GenerateChoice(i);
choices.Add(choice);
}
return choices;
}
private string GenerateChoice(int index)
{
Console.WriteLine($"Enter Choice {index} for the question: ");
string choice = Console.ReadLine();
return choice;
}
private Answer GenerateAnswer(List<string> choices)
{
Console.WriteLine("Enter the answer: ");
string userChoice = InputValidator.GetUserChoice(new Problem() { Choices=choices });
var answer = new Answer()
{
Value = userChoice
};
return answer;
}
}
public class QuizProctor
{
public Grade ProctorQuiz(Quiz quiz)
{
var answers = new List<Answer>();
foreach(Problem problem in quiz.Problems)
{
Answer answer = ProctorProblem(problem);
answers.Add(answer);
}
Grade grade = quiz.Grade(answers);
return grade;
}
private Answer ProctorProblem(Problem problem)
{
string userChoice = InputValidator.GetUserChoice(problem);
var answer = new Answer()
{
Value = userChoice
};
return answer;
}
}
public class Quiz
{
public List<Problem> Problems { get; set; }
public Grade Grade(List<Answer> answers)
{
List<Answer> answerKey = Problems.Select(x => x.Answer).ToList();
var rawResults = new List<Tuple<Answer, Answer>>();
for(int i=0; i<answers.Count; i++)
{
Answer correct = answerKey[i];
Answer provided = answers[i];
rawResults.Add(new Tuple<Answer, Answer>(correct, provided));
}
return new Grade(rawResults);
}
}
public class Grade
{
private List<Tuple<Answer, Answer>> RawResults { get; set; }
public decimal Percent
{
get { return decimal.Divide(RawResults.Count(x => x.Item1.Equals(x.Item2)), RawResults.Count); }
}
public Grade(List<Tuple<Answer, Answer>> rawResults)
{
RawResults = rawResults;
}
public override string ToString()
{
return string.Format("You scored a {0:P2}.", Percent);
}
}
public class Problem
{
public string Question { get; set; }
public List<string> Choices { get; set; }
public Answer Answer { get; set; }
public string Prompt()
{
Func<int, char> numberToLetter = (int n) =>
{
return (char)('A' - 1 + n);
};
string prompt = Question;
for (int i=0; i<Choices.Count; i++)
{
string choice = Choices[i];
prompt += $"\n{numberToLetter(i+1)}) {choice}";
}
return prompt;
}
}
public class Answer
{
public string Value { get; set; }
public override string ToString()
{
return Value + "";
}
public override bool Equals(object obj)
{
if (obj == null || GetType() != obj.GetType())
{
return false;
}
return (obj as Answer).Value.Equals(Value);
}
public override int GetHashCode()
{
return Value.GetHashCode();
}
}
public static class InputValidator
{
public static int GetPositiveNumber(string prompt)
{
int number = -1;
while (number < 0)
{
Console.Write(prompt);
string input = Console.ReadLine();
try
{
number = int.Parse(input);
}
catch (Exception)
{
Console.WriteLine("ERROR: Please input a positive number.");
}
}
return number;
}
public static string GetUserChoice(Problem problem)
{
Func<char, int> letterToNumber = (char c) =>
{
if (char.IsLower(c))
{
return (int)(c - 'a' + 1);
}
return (int)(c - 'A' + 1);
};
char userChoiceLetter = '_';
while (!char.IsLetter(userChoiceLetter))
{
Console.WriteLine(problem.Prompt());
Console.Write("Answer: ");
var input = Console.ReadLine();
try
{
userChoiceLetter = char.Parse(input);
}
catch (Exception)
{
Console.WriteLine("ERROR: Please input a letter corresponding to your choice.");
}
}
int answerIndex = letterToNumber(userChoiceLetter) - 1;
return problem.Choices[answerIndex];
}
}
}

Adding up Multiple Checkbox values to a label, Based on if they are Checked or notC#

Alright I have 8-10 check boxes and radio buttons, and i need to sum up the double values that are assigned to them. The only problem is that I only want to check some of the boxes not all of them. If you could help me out that would be great. Also any pointers on my code will also help
double SpringMix = 2.00;
double Avocado = 1.50;
double Beans = 2.00;
double Cheese = 2.00;
double Tomato = 1.50;
double HoneyMustard = 2.00;
double Ranch = 2.00;
double Italian = 2.00;
double BlueCheese = 2.00;
double FoodCost;
I'm using if statements to see if the check boxes are checked. I need a way to add them all up depending on if they are checked.
public double TotalOrderCost()
{
if (cbSpringMix.Checked)
{
FoodCost + 2.00;
}
if (cbAvocado.Checked)
{
FoodCost + 1.50;
}
if (cbBeans.Checked)
{
FoodCost + 2.00;
}
if (cbCheese.Checked)
{
I have this version as a solution:
private readonly Dictionary<CheckBox, double> mapping;
public MainWindow()
{
InitializeComponent();
mapping = new Dictionary<CheckBox, double>
{
{cbBean, 2d},
{cbSpringMix, 2d}
//...
};
}
public double TotalOrderCost()
{
double foodCost = 0d;
foreach (KeyValuePair<CheckBox, double> keyValuePair in mapping)
{
if (keyValuePair.Key.Checked)
{
foodCost += keyValuePair.Value;
}
}
return foodCost;
}
LINQ version of TotalOrderCost:
public double TotalOrderCost()
{
return mapping.Where(keyValuePair => keyValuePair.Key.Checked).Sum(keyValuePair => keyValuePair.Value);
}
You can add more comboboxes without modifiing the code multiple places.
This should help. I wrote a simple Console Application to demonstrate how to do this. It looks a lot more complicated than it is, and that is only because I had to put extra stuff in there to simulate a Sql or what ever you might be using. I would just focus on the Food class and the Ingredient class. How they are set up mainly. Also, take a look at the bottom of the static void main to see how I called the methods that I made in the food class. I have updated this with regions and comments to make it easier to read.
class Program
{
static void Main(string[] args)
{
#region SimulatedDb
// Technically a Food object from the Database
var myFood = new Food() { Name = "Sub", Ingredients = new List<IngredientViewModel>(), Price = 8.00 };
// Technically Ingredients from the Database
var cbSpringMixIn = new Ingredient() { Name = "Spring Mix", Price = 2.00 };
var cbAvacodoIn = new Ingredient() { Name = "Avacodo", Price = 1.50 };
var cbBeansIn = new Ingredient() { Name = "Beans", Price = 2.00 };
#endregion
// This would actually be in your code
// You would probably just do a for each statement to turn all of these into
// Objects and add them to the list of available ingredients
var cbSpringMix = new IngredientViewModel(cbSpringMixIn);
var cbAvacodo = new IngredientViewModel(cbAvacodoIn);
var cbBeans = new IngredientViewModel(cbBeansIn);
#region SimulatedUserInterface
Console.WriteLine("What would you like on your {0} ({1:C})", myFood.Name, myFood.Price);
Console.WriteLine();
Console.WriteLine("Would you like {0} ({1:C})", cbSpringMix.Name, cbSpringMix.Price);
Console.WriteLine("yes or no");
var answer = Console.ReadLine();
if (answer == "yes")
{
cbSpringMix.Selected = true;
}
Console.WriteLine();
Console.WriteLine("Would you like {0} ({1:C})", cbAvacodo.Name, cbAvacodo.Price);
Console.WriteLine("yes or no");
var answer1 = Console.ReadLine();
if (answer1 == "yes")
{
cbAvacodo.Selected = true;
}
Console.WriteLine();
Console.WriteLine("Would you like {0} ({1:C})", cbBeans.Name, cbBeans.Price);
Console.WriteLine("yes or no");
var answer2 = Console.ReadLine();
if (answer2 == "yes")
{
cbBeans.Selected = true;
}
#endregion
// This would actually be in your code
// You would probably just do a for each statement to turn all of these into
// Objects and add them to the list of available ingredients
myFood.Ingredients.Add(cbAvacodo);
myFood.Ingredients.Add(cbBeans);
myFood.Ingredients.Add(cbSpringMix);
#region SimulatedUserInterfaceContinued
Console.WriteLine("You are ready to check out! Press any key to continue...");
var checkout = Console.ReadLine();
Console.Write("You have ordered a {0} with ", myFood.Name);
foreach (var ingredient in myFood.GetSelectedNames())
{
Console.Write(ingredient + " ");
}
Console.WriteLine();
Console.WriteLine("Your Final Price is:");
Console.WriteLine(String.Format("{0:C}", myFood.GetFullPrice()));
Console.ReadLine();
#endregion
}
public class Food
{
public Food()
{
}
public IEnumerable<string> GetSelectedNames()
{
return (
from f in this.Ingredients
where f.Selected
select f.Name).ToList();
}
public IEnumerable<double> GetSelectedValues()
{
return (
from f in this.Ingredients
where f.Selected
select f.Price).ToList();
}
public double GetFullPrice()
{
var selectedIngredients = GetSelectedValues();
return selectedIngredients.Sum() + this.Price;
}
public string Name { get; set; }
public double Price { get; set; }
public virtual List<IngredientViewModel> Ingredients { get; set; }
}
public class IngredientViewModel
{
public IngredientViewModel(Ingredient ingredient)
{
this.Name = ingredient.Name;
this.Price = ingredient.Price;
this.Selected = false;
}
public string Name { get; set; }
public double Price { get; set; }
public bool Selected { get; set; }
}
public class Ingredient
{
public string Name { get; set; }
public double Price { get; set; }
}
}
}

Parsing text file using C#

Looking for a good way to parse out of this text file, the values highlighted with the yellow boxes using C#. Each section is delineated by a TERM # which I forgot to highlight. Tried this:
string fileName = "ATMTerminalTotals.txt";
StreamReader sr = new StreamReader(fileName);
string[] delimiter = new string[] { " " };
while (!sr.EndOfStream)
{
string[] lines = sr.ReadLine().Split(delimiter, StringSplitOptions.RemoveEmptyEntries);
foreach (string line in lines)
{
Console.WriteLine(line);
}
}
Console.ReadLine();
Safe to say I am reading lines correctly and removing "white spaces." Although, as an amateur to programming, not sure of a valid way to accurately "know" that I am getting the values from this report that I need. Any advice?
i've tested this with a very simple program to parse the given file,
basically i've created two basic classes, a page class holding a collection of terminal report class (the tran type rows)
these rows maybe even can be represented as transaction and a billing class too
first parsed the data, setting the parameters needed and lastly just accessing the properties
just rushed it to be as simple as possible, no error handling etc... its just to give you a sense of how id start solving these kind of tasks, hope it helps
Adam
namespace TerminalTest
{
class Program
{
public class TerminalReport
{
public string Word { get; set; }
public int Denials { get; set; }
public int Approvals { get; set; }
public int Reversals { get; set; }
public double Amount { get; set; }
public int ON_US { get; set; }
public int Alphalink { get; set; }
public int Interchange { get; set; }
public int Surcharged { get; set; }
public static TerminalReport FromLine(string line)
{
TerminalReport report = new TerminalReport();
report.Word = line.Substring(0, 11);
line = line.Replace(report.Word, string.Empty).Trim();
string[] split = line.Split(' ');
int i = 0;
// transaction summary
report.Denials = int.Parse(split[i++]);
report.Approvals = int.Parse(split[i++]);
report.Reversals = int.Parse(split[i++]);
report.Amount = double.Parse(split[i++]);
// billing counts
report.ON_US = int.Parse(split[i++]);
report.Alphalink = int.Parse(split[i++]);
report.Interchange = int.Parse(split[i++]);
report.Surcharged = int.Parse(split[i++]);
return report;
}
}
public class TerminalPage
{
public int PageNumber { get; set; }
public double TotalSurcharges { get; set; }
public List<TerminalReport> Rows { get; set; }
public TerminalPage(int num)
{
PageNumber = num;
Rows = new List<TerminalReport>();
}
public int TotalDenials
{
get
{
return rows.Sum(r => r.Denials);
}
}
public int TotalApprovals
{
get
{
return Rows.Sum(r => r.Approvals;
}
}
public int TotalReversals
{
get
{
return Rows.Sum(r => r.Reversals;
}
}
public double TotalAmount
{
get
{
return Rows.Sum(r => r.Amount);
}
}
public int TotalON_US
{
get
{
return Rows.Sum(r => r.ON_US);
}
}
public int TotalAlphalink
{
get
{
return Rows.Sum(r => r.Alphalink);
}
}
public int TotalInterchange
{
get
{
return Rows.Sum(r => r.Interchange);
}
}
public int TotalSurcharged
{
get
{
return Rows.Sum(r => r.Surcharged);
}
}
}
private static string CleanString(string text)
{
return Regex.Replace(text, #"\s+", " ").Replace(",", string.Empty).Trim();
}
private static List<TerminalPage> ParseData(string filename)
{
using (StreamReader sr = new StreamReader(File.OpenRead(filename)))
{
List<TerminalPage> pages = new List<TerminalPage>();
int pageNumber = 1;
TerminalPage page = null;
bool parse = false;
while (!sr.EndOfStream)
{
string line = sr.ReadLine();
line = CleanString(line);
if (line.StartsWith("TRAN TYPE"))
{
// get rid of the ----- line
sr.ReadLine();
parse = true;
if (page != null)
{
pages.Add(page);
}
page = new TerminalPage(pageNumber++);
}
else if (line.StartsWith("="))
{
parse = false;
}
else if (line.StartsWith("TOTAL SURCHARGES:"))
{
line = line.Replace("TOTAL SURCHARGES:", string.Empty).Trim();
page.TotalSurcharges = double.Parse(line);
}
else if (parse)
{
TerminalReport r = TerminalReport.FromLine(line);
page.Rows.Add(r);
}
}
if (page != null)
{
pages.Add(page);
}
return pages;
}
}
static void Main(string[] args)
{
string filename = #"C:\bftransactionsp.txt";
List<TerminalPage> pages = ParseData(filename);
foreach (TerminalPage page in pages)
{
Console.WriteLine("TotalSurcharges: {0}", page.TotalSurcharges);
foreach (TerminalReport r in page.Rows)
Console.WriteLine(r.Approvals);
}
}
}
}
I'm not sure I'd split it by spaces actually.. the textfile looks like its split into columns. You might want to read like 10 chars (or whatever the width of the column is) at a time... and I'd parse the whole file into a dictionary so you get entries like
dict["WDL FRM CHK"]["# DENIALS"] = 236
then you can easily retrieve the values you want from there, and if you ever need more values in the future, you've got them.
Alternatively, you can use regexs. You can grab the first value with a regex like
^WDL FRM CHK\s+(?<denials>[0-9,]+)\s+(?<approvals>[0-9,]+)$
using
m.Groups["approvals"]
anyway I recommend you to wrap your StreamReader with using block:
using (StreamReader sr = new StreamReader(fileName))
{
// do stuff
}
Read more on MSDN
Given that it seems to have a standard, regular format, I would use regular expressions. You can check the starting code to figure out what row you're on, then an expression that will parse out the numbers and ignore whitespace will, very likely, be easier than handling it manually.
using System;
using System.Text.RegularExpressions;
namespace ConsoleApplication3
{
class Program
{
static void Main(string[] args)
{
Regex exp = new Regex(#"WDL FRM CHK(\s)+[1-9,]+(\s)+(?<approvals>[1-9,]+)(\s)+");
string str = "WDL FRM CHK 236 1,854 45,465 123 3";
Match match = exp.Match(str);
if (match.Success)
{
Console.WriteLine("Approvals: " + match.Groups["approvals"].Value);
}
Console.ReadLine();
}
}
}
Apdated from the following article to parse one of your numbers:
How to match a pattern by using regular expressions and Visual C#

Categories