Related
i have made a 2D array in c#. I want have a method to fill in some numbers and a method to print it. But this doesnt work. Since it is for school. The static void main cant be changed. Can anyone help me? the if statement is true and will say invalid number of arguments here is some code:
static void Main(string[] args)
{
if (args.Length != 2)
{
Console.WriteLine("invalid number of arguments!");
Console.WriteLine("usage: assignment[1-3] <nr of rows> <nr of columns>");
return;
}
int numberOfRows = int.Parse(args[0]);
int numberOfColumns = int.Parse(args[1]);
Program myProgram = new Program();
myProgram.Start(numberOfRows, numberOfColumns);
}
void Start(int numberOfRows, int numberOfColumns)
{
int[,] matrix = new int[numberOfRows, numberOfColumns];
InitMatrix2D(matrix);
DisplayMatrix(matrix);
}
void InitMatrix2D(int[,] matrix)
{
int numberPlusOne = 1;
for (int rows = 0; rows < matrix.GetLength(0); rows++)
{
for (int columns = 0; columns < matrix.GetLength(1); columns++)
{
matrix[rows, columns] = numberPlusOne++; // telkens vullen met +1
}
}
}
void DisplayMatrix(int[,] matrix)
{
for (int rows = 0; rows < matrix.GetLength(0); rows++)
{
for (int columns = 0; columns < matrix.GetLength(1); columns++)
{
Console.Write($"{matrix[rows, columns]}");
}
}
}
The if statement is true.
It may not be obvious, but the array of strings passed to Main(string[] args) — args — are the arguments passed to the program on the command line, aptly called command line arguments. If you start a C# program named, say, myprog from a Console window with myprog 1 2 3, the operating system and .net runtime see to it that args will have (typically) four elements, namely "myprog", "1", "2" and "3". Perhaps the first one is missing and it's only "1", "2" and "3"; that seems to be the case when I try it on Windows 10 and .net 5.0.
You have probably never started your (or maybe any) program from the command line, hence your confusion.
In order to start a custom program which is not in the program search path from the Console, you need to know where it is because you either cd there or type the entire path name. The program may not be easy to find if you work with an IDE like Visual Studio.1
But Visual Studio allows you to pass arguments to the program via the project's properties dialog. Right-click the project, click Properties at the bottom, choose "Debug" on the left and enter two numbers in the "Application arguments" text box. Then hit F5 if you have a Debug build configuration active.
As an aside:
It is customary to return from Main with a non-zero value if the program encounters an error. That return value is used as the exit status of the program, which can be inspected by the caller. The wrong number of arguments is a very basic error condition that should be diagnosable: A script may choose not to continue when a critical step in a processing chain failed. It would be better to declare Main to return int. That way you can return non-zero when an error is encountered. Since you cannot change Main, this is perhaps a note to your teacher (who will likely answer that he doesn't want to complicate matters ;-) ).
It is customary to make error output on standard error, not on standard out. The reason is that a caller may parse the standard output (perhaps output from a chain of programs, not only yours!) and would be confused by unexpected text in the standard output. It would be better to write Console.Error.WriteLine("invalid number of arguments!");.
1 You can right-click the editor tab of a source file in Visual Studio and click "open containing folder"; somewhere below that project folder is an exe file, simply search *.exe in the explorer that opened. Right-click the entry with your exe and choose "open file location", then shift-right-click that folder and choose "open cmd window here", or the powershell equivalent.
Whew.
Now, if your program is named program.exe, type program 5 7 or whatever values you desire, and it should work.
Here are two different ways to display a matrix
1,2,3,4,5
6,7,8,9,10
11,12,13,14,15
16,17,18,19,20
21,22,23,24,25
26,27,28,29,30
31,32,33,34,35
| 1 2 3 4 5|
| 6 7 8 9 10|
| 11 12 13 14 15|
| 16 17 18 19 20|
| 21 22 23 24 25|
| 26 27 28 29 30|
| 31 32 33 34 35|
The first way is like a CSV file, with comma-separated values for each row. It is still human-readable but primarily targeted toward file operations.
The second way is arranged in a table/grid which far more human-readable, but less readable by computers.
The code to generate the above two styles is declared using extension methods, DisplayDelimited() and DisplayTable()
public static class DisplayExtensions
{
public static string DisplayDelimited<T>(this T[,] matrix, string columnSeparator = ",")
{
StringBuilder sb = new StringBuilder();
for (int i = 0; i < matrix.GetLength(0); i++)
{
for (int j = 0; j < matrix.GetLength(1); j++)
{
if (j > 0)
{
sb.Append(columnSeparator);
}
sb.Append(matrix[i, j]);
}
sb.AppendLine();
}
return sb.ToString();
}
public static string DisplayTable<T>(this T[,] matrix, int columnWidth = 8, string bracketSymbol = "|")
{
StringBuilder sb = new StringBuilder();
for (int i = 0; i < matrix.GetLength(0); i++)
{
sb.Append(bracketSymbol);
for (int j = 0; j < matrix.GetLength(1); j++)
{
if (j > 0)
{
sb.Append(" ");
}
sb.Append(matrix[i, j].ToString().PadLeft(columnWidth));
}
sb.AppendLine(bracketSymbol);
}
return sb.ToString();
}
}
class Program
{
static void Main(string[] args)
{
int value = 0;
int[,] matrix = new int[7, 5];
for (int i = 0; i < 7; i++)
{
for (int j = 0; j < 5; j++)
{
matrix[i, j] = ++value;
}
}
Console.WriteLine(matrix.DisplayDelimited());
Console.WriteLine(matrix.DisplayTable());
}
}
I want to break a long string by character and line length, without breaking words.
Within my string I use "|" as my seperator, and every line must never end with a seperator. I need to break on "|", without breaking words.
I tried the following, which looks at the maximum line length, and makes sure everything fits. Now I have to implement the seperation by "|" character without interupting the check for line length.
int partLength = 35;
string sentence = "Silver badges are awarded for longer term goals. Silver badges are uncommon.";
string[] words = sentence.Split(' ');
var parts = new Dictionary<int, string>();
string part = string.Empty;
int partCounter = 0;
foreach (var word in words)
{
if (part.Length + word.Length < partLength)
{
part += string.IsNullOrEmpty(part) ? word : " " + word;
}
else
{
parts.Add(partCounter, part);
part = word;
partCounter++;
}
}
parts.Add(partCounter, part);
foreach (var item in parts)
{
Console.WriteLine(item.Value);
}
I tried the following for breaking by character "|":
string sentence = "The dog had a bone | a ball | and other toys.";
char charToTrim = '|';
string[] words = sentence.Split();
foreach (string word in words)
Console.WriteLine(word.TrimEnd(charToTrim));
This will print all words on new line, which is not correct.
So in a long text, I need to look at the maximum line length, as well as the seperator "|". The words must match within the line, but a new line cannot end with "|".
So the following is correct:
Item 1 | Item 2 | Item 3 | Item 4
| Item 5 | Etc
But the following is not correct:
Item 1 | Item 2 | Item 3 | Item 4 |
Item 5 | Etc
You can't split the string using the | as you would lose the information about where they existing in the original string. Also you won't be able to do this with foreach as you need to look ahead when calculating the length of the next string. Taking your original code you can do this:
int partLength = 35;
string sentence = "Item 1 | Item 2 | Item 3 | Item 4 | Item 5 | Etc";
string[] words = sentence.Split(' ');
var parts = new Dictionary<int, string>();
string part = string.Empty;
int partCounter = 0;
for(int i = 0; i < words.Count(); i++)
{
var newLength = part.Length + words[i].Length;
if(words[i] == "|" && i + 1 < words.Count())
{
newLength += words[i + 1].Length;
}
if (newLength < partLength)
{
part += string.IsNullOrEmpty(part) ? words[i] : " " + words[i];
}
else
{
parts.Add(partCounter, part);
part = words[i];
partCounter++;
}
}
parts.Add(partCounter, part);
foreach (var item in parts)
{
Console.WriteLine(item.Value);
}
We still split on a space but we use a for loop to iterate through the strings. Before we check if the current word fits we need to check if it is a |. If it is then add the next word as well (if one exists). This should produce the output you are looking for.
Modifying your example (and following your initial approach) I was able to do it like this (the idea is to look one more word ahead in case we meet the separator):
int partLength = 15;
string sentence = "Item1 | Item2 | Item3 | Item4 | Item5 | Item6 | Item7 |";
string[] words = sentence.Split(' ');
var parts = new List<string>();
var partBuilder = new StringBuilder(partLength);
int partCounter = 0;
for (int i = 0; i < words.Length; i++)
{
var word = words[i];
var nextWord = (i < words.Length - 1)
? words[i + 1]
: null;
var lengthToCheck =
word == "|" && nextWord != null
? word.Length + nextWord.Length
: word.Length;
if (partBuilder.Length + lengthToCheck < partLength)
{
if (partBuilder.Length > 0)
partBuilder.Append(" ");
partBuilder.Append(word);
}
else
{
parts.Add(partBuilder.ToString());
partBuilder.Clear();
partBuilder.Append(word);
partCounter++;
}
}
parts.Add(partBuilder.ToString());
foreach (var item in parts)
{
Console.WriteLine(item);
}
The output is:
Item1 | Item2
| Item3 | Item4
| Item5 | Item6
| Item7 |
I also replaced concatenation of strings by StringBuilder which is considered the best practice when it comes to concatenating a lot of strings.
And I still have guts feeling that it's even easier to solve this by moving through the string char by char.
I have a program that is to calculate taxes for payroll. I need a for loop to write the last name, first name, dept, rate, hours, earnings, fica, fedtax, statetax and netpay. I'm not thrown any errors when I run the program and can't seem to find why my output only displays the last name. There are two .txt files, one is blank for output and the other is listed below.
This is the data content of my .txt file:
Adams Paul 3 9.75 40.00
Allen Cindy 2 11.45 48.00
Allen Sarah 4 10.30 40.00
Baker John 1 22.00 43.25
Baker Toni 1 12.65 40.00
Baldwin Cindy 2 7.90 25.50
Carson Robert 1 8.35 52.50
Freeman Sally 4 15.25 40.00
Garfield James 3 22.00 40.00
Grimes Kerri 3 16.50 35.00
Harris Joan 2 18.65 51.00
Harris John 2 9.00 47.50
Lawson LeAnn 4 17.85 40.00
Mason Debbie 4 22.00 41.50
Masters Kenneth 3 16.10 40.25
Patterson Roseanne 2 13.70 38.00
Peterson Paul 2 22.00 44.00
Randall Michael 3 8.00 41.00
Rogers Sherry 1 16.50 30.00
Shepard Steven 3 10.90 45.50
This is my code:
using System;
using System.IO;
using System.Text.RegularExpressions;
using LibUtil;
classPayRoll
{
const double FICA_RATE = 0.07;
const double FED_TAX_RATE = 0.22;
const double STATE_TAX_RATE = 0.05;
const string INPUT_FILE_NAME = "PayrollDat.Txt";
const string OUTPUT_FILE_NAME = "PayrollReport.Txt";
static uint numOfEmployees;
static string[] lastNameArray = new string[51], firstNameArray = new string[51];
static uint[] deptArray = new uint[51];
static double[] rateArray = new double[51], hoursArray = new double[51];
static double[] earningsArray = new double[51], ficaArray = new double[51];
static double[] fedTaxArray = new double[51], stateTaxArray = new double[51];
static double[] netPayArray = new double[51];
static StreamReader fileIn;
static StreamWriter fileOut;
static void Main()
{
OpenFiles();
InputData();
CalcDetailPayroll();
PrintReport();
CloseFiles();
}
static void OpenFiles()
{
if (File.Exists(INPUT_FILE_NAME))
{
fileIn = File.OpenText(INPUT_FILE_NAME);
Console.WriteLine("{0} was opened", INPUT_FILE_NAME);
}
else
{
Console.WriteLine("Error: {0} does not exist\n", INPUT_FILE_NAME);
ConsoleApp.Exit();
}
fileOut = File.CreateText(OUTPUT_FILE_NAME);
if (File.Exists(OUTPUT_FILE_NAME))
Console.WriteLine("{0} was created\n", OUTPUT_FILE_NAME);
else
{
Console.WriteLine("Error: {0} could not be created\n", OUTPUT_FILE_NAME);
ConsoleApp.Exit();
}
}
static void ParseLineIn(string lineIn, uint i)
{
string[] words = new string[5];
lineIn = lineIn.Trim();
while (Regex.IsMatch(lineIn, "[ ]{2}"))
lineIn = lineIn.Replace(" ", " ");
words = lineIn.Split(' ');
lastNameArray[i] = words[0];
i = 0;
while (i <= numOfEmployees)
{
lastNameArray[i] = words[0];
firstNameArray[i] = words[1];
deptArray[i] = uint.Parse(words[2]);
rateArray[i] = double.Parse(words[3]);
hoursArray[i] = double.Parse(words[4]);
i++;
}
//Add code to read in data into remaining arrays
}
static void InputData()
{
uint i;
string lineIn;
i = 0;
while ((lineIn = fileIn.ReadLine()) != null)
{
i++;
ParseLineIn(lineIn, i);
}
numOfEmployees = i;
}
static void CalcDetailPayroll()
{
uint i;
double basePay, ovtPay;
for (i = 1; i <= numOfEmployees; i++)
{
if (hoursArray[i] <= 40.0)
{
basePay = Math.Round(hoursArray[i] * rateArray[i]); //Calculate base pay
ovtPay = 0.00;
}
else
{
basePay = Math.Round(40 * rateArray[i]); //Calculate base pay
ovtPay = Math.Round(rateArray[i] * (hoursArray[i] - 40.0) * 1.5); //Calculate overtime pay
}
//Calculate earnings, fica, fedTax, stateTax, and netPay
earningsArray[i] = basePay + ovtPay;
ficaArray[i] = earningsArray[i] * FICA_RATE;
fedTaxArray[i] = earningsArray[i] * fedTaxArray[i];
stateTaxArray[i] = earningsArray[i] * STATE_TAX_RATE;
netPayArray[i] = earningsArray[i] - (ficaArray[i] + fedTaxArray[i] + stateTaxArray[i]);
}
}
static double Total(double[] doubleArray)
{
uint i;
double total = 0.0;
for (i = 1; i <= numOfEmployees; i++) ;
total += earningsArray[i];
return total;
}
static double Mean(double[] doubleArray)
{
uint i;
double sum = 0.0;
for (i = 1; i <= numOfEmployees; i++)
sum += doubleArray[i];
return sum / numOfEmployees;
}
static double Max(double[] doubleArray)
{
uint i;
double max;
max = doubleArray[1];
for (i = 2; i <= numOfEmployees; i++)
if (doubleArray[i] > max)
max = doubleArray[i];
return max;
}
static double Min(double[] doubleArray)
{
uint i;
double min;
double max;
min = doubleArray[1];
for (i = 2; i <= numOfEmployees; i++)
if (doubleArray[i] < min)
max = doubleArray[i];
return min;
}
static void PrintReport()
{
uint i;
fileOut.WriteLine(" Payroll Report ");
fileOut.WriteLine();
fileOut.WriteLine(" Last Name First Name Dept Rate Hours Earnings FICA Fed Tax State Tax Net Pay ");
fileOut.WriteLine("--------------- --------------- ---- ----- ----- --------- --------- --------- --------- ---------");
for (i = 1; i <= numOfEmployees; i++)
{
fileOut.WriteLine("{0,-9} {1,9} {2,9} {3,9} {4,9} {5,9} {6,9} {7,9} {8,9} {9,9}",
lastNameArray[i], firstNameArray[i], deptArray[i], rateArray[i],hoursArray[i],earningsArray[i],
ficaArray[i],fedTaxArray[i],stateTaxArray[i],netPayArray[i]);
}
//Create for loop to display last name, firstname, dept, rate, hours, earnings, fica, fedTax, stateTax, and netPay
fileOut.WriteLine(" --------- --------- --------- --------- ---------");
fileOut.WriteLine("{0,-49}{1,9:n} {2,9:n} {3,9:n} {4,9:n} {5,9:n}",
"Total", Total(earningsArray), Total(ficaArray),
Total(fedTaxArray), Total(stateTaxArray), Total(netPayArray));
fileOut.WriteLine("{0,-49}{1,9:n} {2,9:n} {3,9:n} {4,9:n} {5,9:n}",
"Mean", Mean(earningsArray), Mean(ficaArray),
Mean(fedTaxArray), Mean(stateTaxArray), Mean(netPayArray));
fileOut.WriteLine("{0,-49}{1,9:n} {2,9:n} {3,9:n} {4,9:n} {5,9:n}",
"Maximum", Max(earningsArray), Max(ficaArray),
Max(fedTaxArray), Max(stateTaxArray), Max(netPayArray));
fileOut.WriteLine("{0,-49}{1,9:n} {2,9:n} {3,9:n} {4,9:n} {5,9:n}",
"Minimum", Min(earningsArray), Min(ficaArray),
Min(fedTaxArray), Min(stateTaxArray), Min(netPayArray));
}
static void CloseFiles()
{
fileIn.Close(); fileOut.Close();
}
}
You should change the ParseLineIn method to use the index passed from the caller. Actually you are setting always the same index when you set the i to zero
static void ParseLineIn(string lineIn, uint i)
{
string[] words = new string[5];
lineIn = lineIn.Trim();
while (Regex.IsMatch(lineIn, "[ ]{2}"))
lineIn = lineIn.Replace(" ", " ");
words = lineIn.Split(' ');
lastNameArray[i] = words[0];
// i = 0;
// No loop needed, you are reading one line of data and setting
// the appropriate index in the arrays
// while (i <= numOfEmployees)
//{
lastNameArray[i] = words[0];
firstNameArray[i] = words[1];
deptArray[i] = uint.Parse(words[2]);
rateArray[i] = double.Parse(words[3]);
hoursArray[i] = double.Parse(words[4]);
// i++;
//}
}
Also notice that your Total method has an error in this line
for (i = 1; i <= numOfEmployees; i++) ;
remove the semicolon at the end of the for loop to allow the execution of the line the makes the sum.
Said all this, I really suggest you to discard this array approach and build a proper class that represent your data and collect the information in a List of such data. Actually your code allows only files with 50 lines and please remember that array in NET start at index zero.
my 2D array has sentences, their tokens and their tags. I want to remove all the other tags Except nouns and verbs. I want to remove the whole index which is not verb/noun. Right now my code is just placing a null on that index. but i want that index to be removed from the array. my code is:
HashSet<String> tagsToRemove = new HashSet<String>() { "'NN'", "'NNS'", "'VBD'", "'VBG'", "'VBZ'", "'VB'" };
for (int i = 0; i < array2D_of_tags.GetLength(0); ++i)
{
if (!tagsToRemove.Contains(array2D_of_tags[i, 2]))
array2D_of_tags[i, 2] = null;
//Console.WriteLine(array2D_of_tags[i, 2]);
}
this is the data in the array2D_of_tags:
A supplier supplies many parts. | 'A' | 'DT' |
A supplier supplies many parts. | 'supplier' | 'NN' |
A supplier supplies many parts. | 'supplies' | 'NNS' |
A supplier supplies many parts. | 'many' | 'JJ' |
A supplier supplies many parts. | 'parts' | 'NNS' |
A supplier supplies many parts. | '.' | '.' |
It's not possible to delete the index cause array are fixed in size.
If you want to accomplish this by keeping your data structure, you must create a new array with the desired data inside.
You can write something like this:
string[,] array2D_of_tags = new string[,]
{
{"A", "DT"}, {"supplier", "NN"}, {"supplies", "NNS"}, {"many", "JJ" }
};
HashSet <string> tagsToRemove = new HashSet<string> { "'NN'", "'NNS'", "'VBD'" };
int rowsToKeep = array2D_of_tags.GetLength(0) - tagsToRemove.Count;
string[,] newArr2d = new string[rowsToKeep, array2D_of_tags.GetLength(1)];
int currentRow = 0;
for (int i = 0; i < array2D_of_tags.GetLength(0); i++)
{
if (!tagsToRemove.Contains(array2D_of_tags[i, 2])) //I didn't understand this, i take it from your code
{
for (int j = 0; j < array2D_of_tags.GetLength(1); j++)
{
newArr2d[currentRow, j] = array2D_of_tags[i, j];
}
currentRow++;
}
}
So I'm using a C# code to separate lines of strings and then further separate them using a comma.
I'm using this two to separate:
dataString = hs_get.text.Split('\n');
stringPairs = new string[dataString.Length][];
for (int o = 0; o < dataString.Length - 1; o++)
{
Debug.Log (o);
stringPairs[o] = dataString[o].Split(',');
//Debug.Log (dataString[o][0] + " --- " + dataString[o][2]);
}
This is the PHP code that feeds this string:
php
// Send variables for the MySQL database class.
$database = mysql_connect('X', 'X', 'X') or die('Could not connect: ' . mysql_error());
mysql_select_db('openfire_scores') or die('Could not select database');
$query = "SELECT * FROM `scores` ORDER by `score` DESC LIMIT 5";
$result = mysql_query($query) or die('Query failed: ' . mysql_error());
$num_results = mysql_num_rows($result);
for($i = 0; $i < $num_results; $i++)
{
$row = mysql_fetch_array($result); // Automatically advances one row after fetching
echo $row['id'] . "," . $row['name'] . "," . $row['score'] . "\n";
}
>
And this is the table thats being used:
id | name | score |
1 | Player 1 | 5 |
2 | Player 2 | 5 |
3 | Player 3 | 7 |
But instead of separating the words between the comma's, it separates every single character INCLUDING the comma and puts that into the array.
What am I doing wrong?
Edit
I should mention I built off of this post: http://answers.unity3d.com/questions/16225/how-can-i-read-data-from-a-text-file-putting-a-lar.html
Edit 2
So today I had a breakthrough. This is the code I use now. I am still not sure why the previous code didn't work, but this one does.
dataString = hs_get.text.Split('\n');
stringPairs = new string[dataString.Length][];
for (int o = 0; o < dataString.Length; o++)
{
string[] trial = dataString[o].Split(',');
stringPairs[o] = trial;
}
Thanks for the all the help guys!
Your code appears to work but skips the last row, you should drop the -1 unless you intend to skip the last row.
Here is an example:
string text = "1,Player 1,5\n2,Player 2,5\n3,Player 3,7";
string [] dataString = text.Split('\n');
string [][] stringPairs = new string[dataString.Length][];
for (int o = 0; o < dataString.Length; o++)
{
//Debug.Log(o);
stringPairs[o] = dataString[o].Split(',');
//Debug.Log (dataString[o][0] + " --- " + dataString[o][2]);
}
the array looks as follows:
stringPair[0]
[0]1
[1]Player 1
[2]5
stringPair[1]
[0]2
[1]Player 2
[2]5
stringPair[2]
[0]3
[1]Player 3
[2]7
You don't have to mirror the way the PHP code does it.
You could write something like this:
private string[][] Work(string hs_get_text) {
var lines = hs_get_text.Split('\n');
int linesLength = lines.Length;
var pairs = new List<string[]>(linesLength);
foreach (var line in lines) {
pairs.Add(line.Split(','));
}
return pairs.ToArray();
}
The List class is very powerful. If you are in .Net, you should use it to save some headaches.
Perhaps I am missing something, but this is working fine for me, perhaps a better alternative. I tried recreating the sample from the unity answer.
const string hs_get_text = "apple,ball\ncar,dog\negg,fish\ngoat,hat";
var dataString = hs_get_text.Split('\n');
var list = new List<string[]>(dataString.Length - 1);
foreach (string s in dataString)
{
Debug.WriteLine(s);
list.Add(s.Split(','));
}
And if you needed the list of string to be an array, you can just call .ToArray() on the list.