Recommended ways to read certain things in a text file - c#

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();
}
}
}

Related

how to get the last result after looping at C#

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

How to insert a string every n words?

I need help with text. I got a code which for example finds if the line has even number of words, then it finds every 2nd word in a text file. The problem is i don't know how to append a string to that every 2nd word and print it out.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Collections;
using System.IO;
namespace sd
{
class Program
{
const string CFd = "..\\..\\A.txt";
const string CFr = "..\\..\\Rezults.txt";
static void Main(string[] args)
{
Apdoroti(CFd, CFr);
Console.WriteLine();
}
static void Apdoroti(string fd, string fr)
{
string[] lines = File.ReadAllLines(fd, Encoding.GetEncoding(1257));
using (var far = File.CreateText(fr))
{
StringBuilder news = new StringBuilder();
VD(CFd,news);
far.WriteLine(news);
}
}
static void VD(string fv, StringBuilder news)
{
using (StreamReader reader = new StreamReader(fv,
Encoding.GetEncoding(1257)))
{
string[] lines = File.ReadAllLines(fv, Encoding.GetEncoding(1257));
int nrl;
int prad = 1;
foreach (string line in lines)
{
nrl = line.Trim().Split(' ').Count();
string[] parts = line.Split(' ');
if (nrl % 2 == 0)
{
Console.WriteLine(nrl);
for (int i = 0; i < nrl; i += 2)
{
int ind = line.IndexOf(parts[i]);
nauja.Append(parts[i]);
Console.WriteLine(" {0} ", news);
}
}
}
}
}
}
}
For example if i got a text like:
"Monster in the Jungle Once upon a time a wise lion lived in jungle.
He was always respected for his intelligence and kindness."
Then it should print out:
"Monster in abb the Jungle abb Once upon abb a time abb a wise abb lion lived abb in jungle.
He was always respected for his intelligence and kindness."
You can do it with a regex replace, like this regex:
#"\w+\s\w+\s"
It maches a Word, a Space, a Word and a Space.
Now replace it with:
"$&abb "
How to use:
using System.Text.RegularExpressions;
string text = "Monster in the Jungle Once upon a time a wise lion lived in jungle. He was always respected for his intelligence and kindness.";
Regex regex = new Regex(#"\w+\s\w+\s");
string output = regex.Replace(text, "$&abb ");
Now you will get the desired output.
Edit:
To Work with any number of Words, you can use:
#"(\w+\s){3}"
where the quantifier (here 3) can be set to whatever you want.
Edit2:
If you don't want to replace numbers:
#"([a-zA-Z]+\s){2}"
You can use linq, first parse the line on spaces to get a list of words (you are doing) and then for every odd element add the text required, finally convert the array back into a string.
string test = "Monster in the Jungle Once upon a time a wise lion lived in jungle. He was always respected for his intelligence and kindness.";
var words = test.Split(' ');
var wordArray = words.Select((w, i) =>
(i % 2 != 0) ? (w+ " asd ") : (w + " ")
).ToArray();
var res = string.Join("", wordArray);
Also this can be easily changed to insert after every n words by changing the mod function. Do remember that array index will start at 0 though.

c# string loop without specific number of loops

I have problem with looping code:
using System;
using System.Globalization;
namespace test
{
class Program
{
static void Main(string[] args)
{
string text = Console.ReadLine();
TextInfo ti = CultureInfo.CurrentCulture.TextInfo;
Console.WriteLine(ti.ToTitleCase(text).Replace(" ", string.Empty));
Console.ReadKey();
}
}
}
And maybe it's wrote like it shouldn't be because I can't find a way to fix it. To be specific I want this program to enter sentence in multiple lines of unknown number, it delete all white space and change every word first letter to upper case. So for example the enter data is:
I wanna ride bicycle,
but Rick say skateboard is better.
And output is:
IWannaRideBicycle,
ButRickSaySkateboardIsBetter.
The program can't have user interface so I think about while and making a list of strings but the problem for me will be still a way to loop it. I found a solution in C++ that they use "while ( getline (cin, text){}" but I think it's not useful in C#.
A while loop should do the trick. Console.ReadLine returns null if no more lines are available.
static void Main(string[] args)
{
List<string> converted = new List<string>();
while (true) // forever
{
string text = Console.ReadLine();
if (text == null)
{
break; // no more lines available - break out of loop.
}
// Convert to capitals
TextInfo ti = CultureInfo.CurrentCulture.TextInfo;
string convertedText = ti.ToTitleCase(text).Replace(" ", "");
converted.Add(convertedText);
}
// Now display the converted lines
foreach (string text in converted)
{
Console.WriteLine(text);
}
}
var text = Console.ReadLine();
while(!String.IsNullOrEmpty(text))
{
TextInfo ti = CultureInfo.CurrentCulture.TextInfo;
Console.WriteLine(ti.ToTitleCase(text).Replace(" ", string.Empty));
text = Console.ReadLine();
}
I think this may be a suitable solution. It will read input from the console until the user simply hits 'Enter' and sends you an empty string. I don't know that there is a more dynamic way to achieve what you're after.
It depends what your input is.
If its an IEnumerable<string> then simply use foreach:
var lines = ... //some IEnumerable<string>
foreach (var line in lines)
{
//do your thing
}
This will keep on looping as long as there is one more line to enumerate in lines. It can, in theory, keep on going forever.
If your input is a Stream then build a StreamReader around it and basically do the same (but with more plumbing):
using (var inputStream = ...// some stream)
using (var reader = new StreamReader(inputStream))
{
var line = reader.ReadLine();
while (line != null)
{
//do your thing
line = reader.ReadLine();
}
}
This again will loop as long as the input stream can produce a new line.

Is there a way to read a CSV file into an ArrayList and then print the values out on the console?

I am simply practicing in C#. I am mostly used to Java but I have been unable to figure out how to read a .CSV file , store it and the print out it's contents into the console. This is what I have so far. What am I doing wrong?
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
using Microsoft.VisualBasic.FileIO;
using System.Collections;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
String path = "C:\\Desktop\\csvTestFilePractice\\";
String file1 = "testFile1.csv";
ArrayList arryList1 = new ArrayList();
String[] dataArray1;
TextFieldParser CSVFile1 = new TextFieldParser(path + file1);
CSVFile1.SetDelimiters(",");
dataArray1 = CSVFile1.ReadFields();
int count = 0;
while (!CSVFile1.EndOfData)
{
dataArray1 = CSVFile1.ReadFields();
Console.WriteLine(dataArray1);
}
Console.Read();
}
}
}
Also this is the file I am testing with.
______Excel View
ID Name Phone State
1 Colt 864-367-8399 SC
2 Terry 864-367-8400 GA
3 Joe 864-367-8401 FL
4 Mark 864-367-8402 NC
5 Ashley 864-367-8403 CO
____Notepad View
ID,Name,Phone,State
1,Colt,864-367-8399,SC
2,Terry,864-367-8400,GA
3,Joe,864-367-8401,FL
4,Mark,864-367-8402,NC
5,Ashley,864-367-8403,CO
Thank you for any advice
You shouldn't be using ArrayList anyway as it is a non-generic collection type. You should be considering how to parse the CSV into a List to avoid having to box/unbox your objects.
Based on questions in the comments here is a short version of the program that uses the max length of each column to create the format string. It should work with almost any csv file. I'm sure it could be improved. All columns are left justified.
void Main()
{
List<string[]> lines = new List<string[]>();
TextFieldParser CSVFile1 = new TextFieldParser(#"g:\test\test.csv");
CSVFile1.SetDelimiters(",");
//Loop through the data and create a list. Each entry in the list
//is a string array. This method may be impractical for very large
//files.
while (!CSVFile1.EndOfData)
{
lines.Add(CSVFile1.ReadFields());
}
//Create a format string using the length of the longest string in each column
string formatString = createFormatString(lines);
//Loop through all the lines and write them to the console.
foreach (var csvLine in lines)
{
Console.WriteLine(formatString, csvLine);
}
}
//Create a format string based on the number of columns and the maximum
// size of each column
private string createFormatString(List<string[]> lines)
{
var sb = new StringBuilder();
//Use the first array to get the number of columns. They should all be the same
int numberOfColumns = lines[0].Length;
//Loop through the number of columns and find the max length and append to the format string
for (int i = 0; i < numberOfColumns; i++)
{
int maxColumnWidth = lines.Select(l => l[i].Length).Max();
sb.AppendFormat("{{{0}, -{1}}} ", i, maxColumnWidth);
}
return sb.ToString();
}

How to read different types of data from text file?

I need to read text data from file, where there are different types of data in every line.
So, I created a one big class named subject. My data looks something like this:
Subject name M1 M2 M3 M4
Subject1 5 7 8 3
Old Subject 1 2 5 9
The main question is, if it is possible to read all the data in line 1 for instance and assign it to proper fields, like SubjName = Subject1, M1 = 5, M2 = 7, M3 = 8 and so on, WITHOUT using substrings? (something like stream >> Subject.SubjName; stream >> Subject.M1 = 5 and so on in C++).
Here's the code that I have.
internal void Read()
{
TextReader tr = new StreamReader("Data.txt");
string line;
while ((line = tr.ReadLine()) != null) //read till end of line
{
tr.ReadLine(); //Skips the first line
}
Thanks in advance
EDIT: To clarify, I'd prefer that fields are delimited.
Something like the solution in this question might help, but obviously use a tab delimeter (\t)
CSV to object model mapping
from line in File.ReadAllLines(fileName).Skip(1)
let columns = line.Split(',')
select new
{
Plant = columns[0],
Material = int.Parse(columns[1]),
Density = float.Parse(columns[2]),
StorageLocation = int.Parse(columns[3])
}
It is not clear from your question how the records are stored in the file - whether fields are delimited or fixed length.
Regardless - you can use the TextFieldParser class, which:
Provides methods and properties for parsing structured text files.
It lives in the Microsoft.VisualBasic.FileIO namespace in the Microsoft.VisualBasic.dll assembly.
Split and Dictionary and your two methods of choice here. You read in your line, split it by empty spaces, then save it as a name/object pair in a dictionary.
Put the code below into a *.cs file, then build and run it as a demo:
using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Collections;
namespace stringsAsObjects
{
class stringObject
{
public static int Main(string[] args)
{
int counter = 0;
string line;
// Read the file and display it line by line.
System.IO.StreamReader file =
new System.IO.StreamReader("Data.txt");
string nameLine = file.ReadLine();
string valueLine = file.ReadLine();
file.Close();
string[] varNames = nameLine.Split(new char[] {' '}, StringSplitOptions.RemoveEmptyEntries);
string[] varValues = valueLine.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
Dictionary<string, object> map = new Dictionary<string, object>();
for(int i = 0; i<varNames.Length; i++)
{
try
{
map[varNames[i]] = varValues[i];
}
catch (Exception ex)
{
map[varNames[i]] = null;
}
}
foreach (object de in map)
{
System.Console.WriteLine(de);
}
Console.ReadKey();
return 0;
}
}
}

Categories