Hello i'm new at C# and programming so i get stuck for hours to get the last result from my looping result
here my code :
using System;
public class Program
{
public static void Main()
{
string merek = string.Empty;
// i wanted to get the last value which is 13 R DLX DG M/T
string str = "DAIHATSU.ALL NEW XENIA.13 R DLX DG M/T";
// Taking a string
char[] spearator = { '.', '.' };
// using the method
String[] strlist = str.Split(spearator);
foreach(String s in strlist)
{
Console.WriteLine(s);
}
}
}
this the point
the result is
DAIHATSU
ALL NEW XENIA
13 R DLX DG M/T
// i wanted to get the last value which is 13 R DLX DG M/T
string str = "DAIHATSU.ALL NEW XENIA.13 R DLX DG M/T";
i'm really appreciate for any help thank you.
You don't need a for loop. You can simply print the last part using the following:
Console.WriteLine(strlist[strlist.Length - 1]);
You can use IEnumerable<T>.Last():
var last = strlist.Last();
Remember to include Linq:
using System.Linq;
Based on your title question, you are looking for the last value after looping.
You can access it directly from your string array.
strlist[strlist.Length - 1];
If there is any valid reason to go through the array, another alternative would be this
string latest = "";
foreach(String s in strlist)
{
Console.WriteLine(s);
latest = s;
}
// After the loop, the latest variable will have the value you are looking for.
To avoid using another Linq cal, you could try using the "IsLast" property from the SmartEnumerable Extension from Jon Skeet's old but reliable MiscUtil. Here's a link to a port into modern .net
https://github.com/jaredthirsk/JTForks.MiscUtil/blob/master/JTForks.MiscUtil/Collections/SmartEnumerable.cs
Related
Im making a hangman game, at the start of the game the word that the player must guess is printed as stars. I have just started making it again after attempting to write it once and just having messy code that i couldn't bug fix. So I decided it best to write it again. The only problem is, when i try to get my array to print out by using array.ToString(); it just returns System.char[]. See below.
code:
class Program
{
static void Main(string[] args)
{
string PlayerOneWord;
string PlayerTwoGuess;
int lives = 5;
Console.WriteLine("Welcome to hangman!\n PLayer one, Please enter the word which player Two needs to guess!");
PlayerOneWord = Console.ReadLine().ToLower();
var stars = new char[PlayerOneWord.Length];
for (int i = 0; i < stars.Length ; i++)
{
stars[i] = '*';
}
string StarString = stars.ToString();
Console.Write("Word to Guess: {0}" , StarString);
Console.ReadLine();
}
}
output:
The output should say Word to guess: Hello.
Please will someone explain why this is happening as its not the first time I have run into this problem.
Calling ToString on a simple array only returns "T[]" regardless what the type T is. It doesn't have any special handling for char[].
To convert a char[] to string you can use:
string s = new string(charArray);
But for your concrete problem there is an even simpler solution:
string stars = new string('*', PlayerOneWord.Length);
The constructor public String(char c, int count) repeats c count times.
The variable stars is an array of chars. This is the reason you get this error. As it is stated in MSDN
Returns a string that represents the current object.
In order you get a string from the characters in this array, you could use this:
Console.Write("Word to Guess: {0}" , new String(stars));
The correct way to do this would be:
string StarString = new string(stars);
ToString() calls the standard implementation of the Array-class's ToString-method which is the same for all Arrays and similarily to object only returns the fully qualified class name.
Try this code:
static string ConvertCharArr2Str(char[] chs)
{
var s = "";
foreach (var c in chs)
{
s += c;
}
return s;
}
I am trying to figure out the best way to read data from a file. I figured out a way but as a jr. I know it's not the best way to go about things. Here is what my text file looks like:
--------Text File text.txt---------
username: nothingeag
accesscode: 123456
value: 74
email: test#testing.com
--------End of File----------------
And here is what I came up with:
using System;
using System.IO;
using System.Linq;
namespace FileSystem
{
class Program
{
static void Main(string[] args)
{
var username = "";
var accesscodeStr = "";
var accesscode = 0;
var valueStr = "";
var value = 0;
var email = "";
var path = #"C:\Users\jthompson\text.txt";
//Read Lines
username = File.ReadLines(path).Skip(0).Take(1).First();
accesscodeStr = File.ReadLines(path).Skip(1).Take(1).First();
valueStr = File.ReadLines(path).Skip(2).Take(1).First();
email = File.ReadLines(path).Skip(3).Take(1).First();
//Trim retrieved data
username = username.Substring(10);
accesscodeStr = accesscodeStr.Substring(12);
valueStr = valueStr.Substring(7);
email = email.Substring(7);
//Parse the INT values
accesscode = Int32.Parse(accesscodeStr);
value = Int32.Parse(valueStr);
//Display the Data
Console.WriteLine(accesscode);
Console.WriteLine(email);
Console.WriteLine(username);
Console.WriteLine(value);
}
}
}
This outputs exactly what I need:
123456
test#testing.com
nothingeag
74
What is the best way to go about reading specific items like this in a text file?
Well, you are making many mistakes:
You are enumerating throught the file MANY times. Read it, store it, than you can make operations on the stored data.
Don't use hardcoded substrings, use string.Split instead.
There is nothing that assures you that those data is what you are anticipating. The number could well be a string, than your program would crash.
Here is a simple implementation of the upper ideas:
string[] fileInput = File.ReadAllLines(path);
string usernameString = fileInput[0].Split(": ")[1];
string accessCodeString = fileInput[1].Split(": ")[1];
string valueString = fileInput[2].Split(": ")[1];
string emailString = fileInput[3].Split(": ")[1];
int accessCode;
if (!int.TryParse(accessCodeString, out accessCode))
{
//Do something when accesscode is not int.
}
int value;
if (!int.TryParse(accessCodeString, out value))
{
//Do something when value is not int.
}
Console.WriteLine(accesscode);
Console.WriteLine(emailString);
Console.WriteLine(usernameString);
Console.WriteLine(value);
This is not a perfect solution, but it is in the right direction.
If your input file structure is static that means it wont change the order; you can use the below instead of your //ReadLines code.
var allLines = File.ReadAllLines(path);
var dataSet = allLines.Select(line => line.Trim().Split(' ')[1]).ToArray();
// Add conditional checks regarding the length of the dataset and any thing else.
var userName = dataSet[0];
var accesscode = Convert.ToInt32(dataSet[1]);
var value = Convert.ToInt32(dataSet[2]);
var email = dataSet[3];
// Then your console.writeline statements here.
If you are unsure of the order, you can use dictionary to store the both parts of line split one for key and other for value. And then print them.
I know this looks a bit goofy, but the Microsoft.VisualBasic assemblies have some great resources for reading text files. This was really quick and dirty. I'm just using ':' as a delimiter as others have suggested.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.VisualBasic;
namespace SandBox
{
class Program
{
static void Main(string[] args)
{
List<string> outputStrings = new List<string>();
string path = #"C:\Users\oa971d\Desktop\textSample.txt";
using (Microsoft.VisualBasic.FileIO.TextFieldParser parser =
new Microsoft.VisualBasic.FileIO.TextFieldParser(path))
{
parser.TextFieldType = Microsoft.VisualBasic.FileIO.FieldType.Delimited;
parser.SetDelimiters(":"); //.csv
//parser.SetDelimiters("\t"); //tab delimited .txt
while(!parser.EndOfData)
{
string[] fields = parser.ReadFields();
if(fields.Length>1)
outputStrings.Add(fields[1]);
}
}
foreach(string s in outputStrings)
{ Console.WriteLine(s); }
Console.ReadLine();
}
}
}
So I am coding a converter program that convers a old version of code to the new version you just put the old text in a text box and it converts Txt to Xml and im trying to get each items beetween two characters and below is the string im trying to split. I have put just the name of the param in the " " to protect my users credentials. So i want to get every part of code beetween the ","
["Id","Username","Cash","Password"],["Id","Username","Cash","Password"]
And then add each string to a list so it would be like
Item 1
["Id","Username","Cash","Password"]
Item 2
["Id","Username","Cash","Password"]
I would split it using "," but then it would mess up because there is a "," beetween the params of the string so i tried using "],"
string input = textBox1.Text;
string[] parts1 = input.Split(new string[] { "]," }, StringSplitOptions.None);
foreach (string str in parts1)
{
//Params is a list...
Params.Add(str);
}
MessageBox.Show(string.Join("\n\n", Params));
But it sort of take the ] of the end of each one. And it messes up in other ways
This looks like a great opportunity for Regular Expressions.
My approach would be to get the row parts first, then get the column parts. I'm sure there are about 30 ways to do this, but this is my (simplistic) approach.
using System;
using System.Text.RegularExpressions;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
var rowPattern = new Regex(#"(?<row>\[[^]]+\])", RegexOptions.Multiline | RegexOptions.ExplicitCapture);
var columnPattern = new Regex(#"(?<column>\"".+?\"")", RegexOptions.Multiline | RegexOptions.ExplicitCapture);
var data = "[\"Id\",\"Username\",\"Cash\",\"Password\"],[\"Id\",\"Username\",\"Cash\",\"Password\"]";
var rows = rowPattern.Matches(data);
var rowCounter = 0;
foreach (var row in rows)
{
Console.WriteLine("Row #{0}", ++rowCounter);
var columns = columnPattern.Matches(row.ToString());
foreach (var column in columns)
Console.WriteLine("\t{0}", column);
}
Console.ReadLine();
}
}
}
Hope this helps!!
You can use Regex.Split() together with positive lookbehind and lookahead to do this:
var parts = Regex.Split(input, "(?<=]),(?=\\[)");
Basically this says “split on , with ] right before it and [ right after it”.
Assuming that the character '|' does not occur in your original data, you can try:
input.Replace("],[", "]|[").Split(new char[]{'|'});
If the pipe character does occur, use another (non-occurring) character.
I have a string that looks like this
2,"E2002084700801601390870F"
3,"E2002084700801601390870F"
1,"E2002084700801601390870F"
4,"E2002084700801601390870F"
3,"E2002084700801601390870F"
This is one whole string, you can imagine it being on one row.
And I want to split this in the way they stand right now like this
2,"E2002084700801601390870F"
I cannot change the way it is formatted. So my best bet is to split at every second quotation mark. But I haven't found any good ways to do this. I've tried this https://stackoverflow.com/a/17892392/2914876 But I only get an error about invalid arguements.
Another issue is that this project is running .NET 2.0 so most LINQ functions aren't available.
Thank you.
Try this
var regEx = new Regex(#"\d+\,"".*?""");
var lines = regex.Matches(txt).OfType<Match>().Select(m => m.Value).ToArray();
Use foreach instead of LINQ Select on .Net 2
Regex regEx = new Regex(#"\d+\,"".*?""");
foreach(Match m in regex.Matches(txt))
{
var curLine = m.Value;
}
I see three possibilities, none of them are particularly exciting.
As #dvnrrs suggests, if there's no comma where you have line-breaks, you should be in great shape. Replace ," with something novel. Replace the remaining "s with what you need. Replace the "something novel" with ," to restore them. This is probably the most solid--it solves the problem without much room for bugs.
Iterate through the string looking for the index of the next " from the previous index, and maintain a state machine to decide whether to manipulate it or not.
Split the string on "s and rejoin them in whatever way works the best for your application.
I realize regular expressions will handle this but here's a pure 2.0 way to handle as well. It's much more readable and maintainable in my humble opinion.
using System;
using System.Collections.Generic;
namespace ConsoleApplication1
{
internal class Program
{
private static void Main(string[] args)
{
const string data = #"2,""E2002084700801601390870F""3,""E2002084700801601390870F""1,""E2002084700801601390870F""4,""E2002084700801601390870F""3,""E2002084700801601390870F""";
var parsedData = ParseData(data);
foreach (var parsedDatum in parsedData)
{
Console.WriteLine(parsedDatum);
}
Console.ReadLine();
}
private static IEnumerable<string> ParseData(string data)
{
var results = new List<string>();
var split = data.Split(new [] {'"'}, StringSplitOptions.RemoveEmptyEntries);
if (split.Length % 2 != 0)
{
throw new Exception("Data Formatting Error");
}
for (var index = 0; index < split.Length / 2; index += 2)
{
results.Add(string.Format(#"""{0}""{1}""", split[index], split[index + 1]));
}
return results;
}
}
}
I am attempting to use regex matching to get a list of optional params out of an mvc route and dynamically inject values into the holders where variables have been used. See code below. Unfortunatly the sample doesn't find both values but repeats the first. Can anyone offer any help?
using System;
using System.Text.RegularExpressions;
namespace regexTest
{
class Program
{
static void Main(string[] args)
{
var inputstr = "http://localhost:12345/Controller/Action/{route:value1}/{route:value2}";
var routeRegex = new Regex(#"(?<RouteVals>{route:[\w]+})");
var routeMatches = routeRegex.Match(inputstr);
for (var i = 0; i < routeMatches.Groups.Count; i++)
{
Console.WriteLine(routeMatches.Groups[i].Value);
}
Console.ReadLine();
}
}
}
This outputs
{route:value1}
{route:value1}
where I was hopeing to get
{route:value1}
{route:value2}
I know nothing about C# but it may help if you put the quantifier after the closing parenthese, no?
Update: That post may help you.
Just make a global match :
var inputstr = "http://localhost:12345/Controller/Action/{route:value1}/{route:value2}";
StringCollection resultList = new StringCollection();
Regex regexObj = new Regex(#"\{route:\w+\}");
Match matchResult = regexObj.Match(inputstr);
while (matchResult.Success) {
resultList.Add(matchResult.Value);
matchResult = matchResult.NextMatch();
}
Your results will be stored in resultList.
foreach (Match match in routeMatches){
for(var i=1;i<match.Groups.Count;++i)
Console.WriteLine(match.Groups[i].Value);
}