Cycle through text file to capture string - c#

I'm looking for a solution to this issue that I'm having a hard time with: I'm trying to read text from a .txt file with this code. The line Monsters[i, j] = string(col.Split(' ')); is giving me trouble, telling me that string is an invalid expression. The file is a list of characters and their attributes separated by spaces. Thanks in advance!
String input = File.ReadAllText(#"CharacterAttributes.txt");
int a = 0, b = 0;
string[,] Monsters = new string[24,11];
foreach (var row in input.Split('\n'))
{
b = 0;
foreach (var col in row.Trim().Split(' '))
{
Monsters[a, b] = string(col.Split(' '));
b++;
}
b++;
}

From what it appears to me:
You've already separated each character by row: var row in input.Split('\n')
You've already separated each attribute for the character by space: var col in row.Trim().Split(' ')
So, when we get to Monsters[a,b] = string(col.Split(' ')) (which btw, string() is invalid syntax), I see no reason to split any further, and what you're actually trying to do is store the value of col to your Monsters[a,b], assuming a is each character, and b is the attribute for said character.
Monsters[a,b] = col; may well be what you are looking for.

Related

Insert a value in a specific line by index

private void Parse_Click(object sender, EventArgs e)
{
for (int i = 0; i < keywordRanks.Lines.Length; i++)
{
int p = keywordRanks.Lines.Length;
MessageBox.Show(p.ToString());
string splitString = keywordRanks.Lines[i];
string[] s = splitString.Split(':');
for (int j = 0; j < keywords.Lines.Length; j++)
{
string searchString = keywords.Lines[j];
if (s[0].Equals(searchString))
{
richTextBox1.Lines[j] = searchString + ':' + s[1];
}
}
}
}
I have an issue with inserting string in a particular line. I have 2 multi line TextBoxes and one RichTextBox.
My application will search for the strings from textbox1 to textbox2 line by line and need to insert those matched values in a RichTextBox control but in the exact index position where it found in textbox2.
If the value found in 5th line of textbox2 then that found line need to be inserted in the RichTextBox 5th line.
Some how my code is not working. I tried a lot but no luck. The code I need something like below but its not working and an IndexOutOfBound exception is raised.
richTextBox1.Lines[j] = searchString + ':' + s[1];
Your RichTextBox must contain all the needed lines before you can set the value using the line index.
If the Control contains no text or line breaks (\n), no lines are defined and any attempt to set a specific Line[Index] value will generate an IndexOutOfRangeException exception.
Here, I'm using a pre-built array, sized as the number of possible matches (the Lines.Length of the keywords TextBox). All matches found are stored here in the original position. The array is then assigned to the RichTextBox.Lines property.
Note: directly using and pre-setting the RichTextBox.Lines won't have effect: the text will remain empty.
string[] MatchesFound = new string[keywords.Lines.Length];
foreach (string currentSourceLine in keywordRanks.Lines)
{
string[] SourceLineValue = currentSourceLine.Split(':');
var match = keywords.Lines.ToList().FindIndex(s => s.Equals(SourceLineValue[0]));
if (match > -1)
MatchesFound[match] = currentSourceLine;
}
richTextBox1.Lines = MatchesFound;
Source Matches Result
(keywordRanks) (keywords) (RichTextBox)
-------------------------------------------
aand:1 aand aand:1
cnd:5 this one
cnds:9 cnds cnds:9
fan:2 another one
gst:0 cnd cnd:5
fan fan:2

Error trying to read csv file

Good Day,
i am having trouble reading csv files on my asp.net project.
it always returns the error index out of range cannot find column 6
before i go on explaining what i did here is the code:
string savepath;
HttpPostedFile postedFile = context.Request.Files["Filedata"];
savepath = context.Server.MapPath("files");
string filename = postedFile.FileName;
todelete = savepath + #"\" + filename;
string forex = savepath + #"\" + filename;
postedFile.SaveAs(savepath + #"\" + filename);
DataTable tblcsv = new DataTable();
tblcsv.Columns.Add("latitude");
tblcsv.Columns.Add("longitude");
tblcsv.Columns.Add("mps");
tblcsv.Columns.Add("activity_type");
tblcsv.Columns.Add("date_occured");
tblcsv.Columns.Add("details");
string ReadCSV = File.ReadAllText(forex);
foreach (string csvRow in ReadCSV.Split('\n'))
{
if (!string.IsNullOrEmpty(csvRow))
{
//Adding each row into datatable
tblcsv.Rows.Add();
int count = 0;
foreach (string FileRec in csvRow.Split('-'))
{
tblcsv.Rows[tblcsv.Rows.Count - 1][count] = FileRec;
count++;
}
}
}
i tried using comma separated columns but the string that comes with it contains comma so i tried the - symbol just to make sure that there are no excess commas on the text file but the same error is popping up.
am i doing something wrong?
thank you in advance
Your excel file might have more columns than 6 for one or more rows. For this reason the splitting in inner foreach finds more columns but the tblcsv does not have more columns than 6 to assign the extra column value.
Try something like this:
foreach (string FileRec in csvRow.Split('-'))
{
if(count > 5)
return;
tblcsv.Rows[tblcsv.Rows.Count - 1][count] = FileRec;
count++;
}
However it would be better if you check for additional columns before processing and handle the issue.
StringBuilder errors = new StringBuilder(); //// this will hold the record for those array which have length greater than the 6
foreach (string csvRow in ReadCSV.Split('\n'))
{
if (!string.IsNullOrEmpty(csvRow))
{
//Adding each row into datatable
DataRow dr = tblcsv.NewRow(); and then
int count = 0;
foreach (string FileRec in csvRow.Split('-'))
{
try
{
dr[count] = FileRec;
tblcsv.Rows.Add(dr);
}
catch (IndexOutOfRangeException i)
{
error.AppendLine(csvRow;)
break;
}
count++;
}
}
}
Now in this case we will have the knowledge of the csv row which is causing the errors, and rest will be processed successfully. Validate the row in errors whether its desired input, if not then correct value in csv file.
You can't treat the file as a CSV if the delimiter appears inside a field. In this case you can use a regular expression to extract the first five fields up to the dash, then read the rest of the line as the sixth field. With a regex you can match the entire string and even avoid splitting lines.
Regular expressions are also a lot faster than splits and consume less memory because they don't create temporary strings. That's why they are used extensively to parse log files. The ability to capture fields by name doesn't hurt either
The following sample parses the entire file and captures each field in a named group. The last field captures everything to the end of the line:
var pattern="^(?<latitude>.*?)-(?<longitude>.*?)-(?<mps>.*?)-(?<activity_type>.*?)-" +
"(?<date_occured>.*?)-(?<detail>.*)$";
var regex=new Regex(pattern,RegexOptions.Multiline);
var matches=regex.Matches(forex);
foreach (Match match in matches)
{
DataRow dr = tblcsv.NewRow();
row["latitude"]=match.Groups["latitude"].Value);
row["longitude"]=match.Groups["longitude"].Value);
...
tblcsv.Rows.Add(dr);
}
The (?<latitude>.*?)- pattern captures everything up to the first dash into a group named latitude. The .*? pattern means the matching isn't greedy ie it won't try to capture everything to the end of the line but will stop when the first - is encountered.
The column names match the field names, which means you can add all fields with a loop:
foreach (Match match in matches)
{
var row = tblCsv.NewRow();
foreach (Group group in match.Groups)
{
foreach (DataColumn col in tblCsv.Columns)
{
row[col.ColumnName]=match.Groups[col.ColumnName].Value;
}
}
tblCsv.Rows.Add(row);
}
tblCsv.Rows.Add(row);

Validating header names for an SQL column list

I am currently trying to make a user friendly input for people to input SQL headers for a CSV that is created using a temporary table, however I am having issues with validating and changing the names to SQL friendly column headers.
An example input would be as follows:
Name, Ag-e, Gender, Birth Place, Rac+e
Please keep in mind that the input could be ANY word, these are simply an example.
My ideal final output would for the SQL column headers
name age gender birth_place race
however I am having issues checking for invalid characters (which I haven't actually got around to yet.) but my primary issue I am currently having is checking for spaces between words that SHOULD have a space and other spaces at the start of words.
My current output is coming out as(please note that the invalid characters are for testing later.):
Name Ag-e Gender Birth Place Rac+e
Please note that there are double spaces between every one apart from Birth Place which has a single space as it should.
The code I am currently using to achieve this (or not achieve as you can clearly see) is:
columnNamesList = new List<string>(columnNames.Split(splitChar));
columnNamesList[0] = columnNamesList[0].Trim();
columnNamesList[columnNamesList.Count - 1] = columnNamesList[columnNamesList.Count - 1].TrimEnd();
List<string> removalList = new List<string>();
foreach (string i in columnNamesList)
{
if (string.IsNullOrEmpty(i))
{
removalList.Add(i);
}
}
if (removalList.Count < 0)
{
foreach (string i in removalList)
{
columnNamesList.Remove(i);
}
}
for (int i = 0; i < columnNamesList.Count; i++)
{
string s = string.Empty;
string str = columnNamesList[i];
if (Regex.IsMatch(str, #"\w\s\w+", RegexOptions.IgnoreCase))
{
foreach (char c in str)
{
if (Char.IsLetterOrDigit(c) || c == ' ' || c == ',')
s += c;
s = s.Replace(' ', '_');
columnNamesList[i] = s;
}
}
}
string[] columnArray = columnNamesList.ToArray<string>();
columnNames = String.Join(" ", columnArray);
I thought you said that the input is like the first string, comma separated.
Does this not work? All you have to do is remove the unwanted characters (against a blacklist)
var input = "Name, Ag-e, Gender, Birth Place, Rac+e";
var splitInput = input.Split(',')
.Select(i =>
i.Trim()
.ToLower()
.Replace(' ','_'));
var output = string.Join(" ", splitInput.ToArray());

Splitting a string seems not to work

I have problems with reading a file (textasset) line by line and getting the results!
Here is the file I am trying to read:
AUTHOR
COMMENT
INFO 1 X ARG 0001 0.581 2.180 1.470
INFO 2 X ARG 0001 1.400 0.974 1.724
INFO 3 X ARG 0001 2.553 0.934 0.751
INFO 4 X ARG 0001 3.650 0.494 1.053
INFO 5 X ARG 0001 1.188 3.073 1.532
INFO 6 X ARG 0001 2.312 1.415 -0.466
INFO 7 X ARG 0001 -0.232 2.249 2.180
END
Here is the code I am using:
//read file
string[] line = file.text.Split("\n"[0]);
for(int i = 0 ; i < line.Length ; i++)
{
if(line[i].Contains("INFO"))
{
//To replace all spaces with single underscore "_" (it works fine)
string l = Regex.Replace(line[i]," {2,}","_");
//In this Debug.Log i get correct results
//For example "INFO_1_X_ARG_0001_0.581_2.180_1.470"
Debug.Log(l);
string[] subline = Regex.Split(l,"_");
//Only for first "INFO" line i get correct results (INFO,1,X,ARG,0001,0.581,2.180,1.470)
//For all other "INFO" lines i get incomplete results (first,fourth and fifth element are not put into substrings
//like they are dissapeard!
foreach(string s in subline){Debug.Log(s);}
}
}
Explanation:
I first split text into lines (works fine),then i read only lines that contain INFO
I loop all lines that contain INFO and replace all spaces with underscore _ (this works fine)
I split lines that contain INFO into substrings based on underscore _
When I print out the lines only first line with INFO seems to have all substrings
every next line is not splitted correctly (first part INFO is omitted as well as third string)
It seems very unreliable. Is this the way to go with these things? Any help is appreciated! This should be simple, what i am doing wrong?
EDIT:
Something is wrong with this code (it should be simple, but it does not work)
Here is the updated code (i just made a List<string> list = new List<string>() and copied all substrings. I use unity3D so that list contents show in the inspector. I was shocked when i so all properly extracted substrings but simple
foreach(string s in list)
Debug.Log(s);
was indeed missing some values. so I was trying different things and this code:
for(int x = 0; x < list.Count ; x++)
{
Debug.Log("List: " + x.ToString() + " " + list[x].ToString());
}
shows contents of the list properly, but this code (note that i just removed x.ToString()) is missing some elements in the list. It does not want to read them!
for(int x = 0; x < list.Count ; x++)
Debug.Log("List: " + list[x].ToString());
So i am not sure what is going on here?!
There are some problems
1>The contains method you are using is case sensitive i.e INFO != info
You should use
line[i].ToLower().Contains("info")
2>Is the text always separated by space.it may also be separated by tabs.you are better off with
Regex.Replace(line[i]," {2,}|\t+","_");
//this would replace 1 to many tabs or 2 or more space
The following seems to be working for me:
using (var fs = new FileStream(filePath, FileMode.Open))
using (var reader = new StreamReader(fs))
{
string line;
while ((line = reader.ReadLine()) != null)
{
if (line.StartsWith("INFO"))
{
line = Regex.Replace(line, "[ ]+", "_");
var subline = line.Split('_');
foreach (var str in subline)
{
Console.Write("{0} ",str);
}
Console.WriteLine();
}
}
}
You may want to try something like this:
for (int i = 0; i < line.Length; i++)
{
if (line[i].Contains("INFO"))
{
string l = Regex.Replace(line[i], #"\p{Zs}{2,}|\t+", "_");
string[] sublines = l.Split('_');
// If you want to see the debug....
sublines.ForEach(s => Debug.Log(s));
}
}
The \p{Zs} will match all Unicode separator/space characters (e.g. space, non-breaking spaces, etc.). The following reference may be of some help to you: Character Classes in Regular Expressions.
Try string.split("\t"[0]") You have probable tabulators between columns.

How can I convert multiple numbers in a textbox to int, in C#?

For a programming assignment, I have to make a simple dice game in Visual C#. A part of this game is displaying a list of the values, and seeing whether the total of the values is over a certain number.
I currently have a textbox that displays the individual values separated by a newline, and am currently using iPlayer1Total += int.Parse(player1TxtBox.Text);, but this only seems to do the first line of the textbox.
It seems that you are using multiline textbox. First split your string on "\n\r" and then:
string[] strArray =player1TxtBox.Text.Split("\n\r".ToCharArray());
then
int iPlayer1Total = 0;
foreach (string str in strArray)
{
int temp =0;
int.TryParse(str, out temp);
iPlayer1Total += temp;
}
Edit: a better option to split would be:
var strArray = player1TxtBox.Text.Split("\r\n".ToCharArray(),StringSplitOptions.RemoveEmptyEntries);
Split the string into an array along the newline.
String.split should get you there.
Then parse each value and voila
You should split your text into string array. MSDN
string[] list = player1TxtBox.Text.Split(new string[] { "\r\n" }, StringSplitOptions.RemoveEmptyEntries);
and then use
foreach(string num in list)
iPlayer1Total += int.Parse(num);
The MSDN library is your friend. Check out the entry on the TextBox and you will find what you're looking for:
http://msdn.microsoft.com/en-us/library/system.windows.forms.textbox.aspx
Hint: Note the Lines property.
Use
string[] str = textbox.Text.Split(#"\n\r");
int a=0;
for(int i=0; i< str.Length; i++)
a += int.TryParse(a);
Is it safe to assume, since it is dice, that each value will only be a single character.
string t = "125 yhsd 7,8+2";
List<int> diceValues=new List<int>();
foreach (char c in t)
{
int o=0;
int.TryParse(c.ToString(),out o);
if (o > 0 && o < 7)
diceValues.Add(o);
}
output should be
diceValues
1
2
5
2
I didn't test this or compile it so there might be errors

Categories

Resources