I'm trying to read an csv file with the format:
name, location
Joseph, "street xpto, London"
When I read CSV, I split the file to ",", but when the line has "street xpto, London" (other commas) it doesn't work.
Is there some solution to that? I need to do split ignoring commas when find an " ".
var reader = new StreamReader(File.OpenRead(#"C:\example_File.csv"));
while (!reader.EndOfStream)
{
var line = reader.ReadLine();
String[] values = line.Split(',');
for (int i = 0; i < values.Length; i++)
{
}
}
Don't reinvent the wheel. There are extremely good libraries that will help you do all this. The one I like is CsvHelper available through nuget
Install-Package CsvHelper
or from the project home page.
Text field parser handles this already
using System;
using Microsoft.VisualBasic.FileIO;
class Program
{
static void Main()
{
using (TextFieldParser parser = new TextFieldParser("C:\\csv.txt"))
{
parser.Delimiters = new string[] { "," };
while (true)
{
string[] parts = parser.ReadFields();
if (parts == null)
{
break;
}
Console.WriteLine("{0} field(s)", parts.Length);
}
}
}
}
Related
This question already has answers here:
Reading CSV files using C#
(12 answers)
Closed 3 years ago.
The code below reads a CSV file and looks for a line containing the serial number which is the first column of the file. Then copies that line to another file. The code works fine.
I need to read the text in the second and third fields of the row (there are 12 fields) and assign them to string variables (for other uses).
Can you help me, Please.
I am a novice.
List<string> found = new List<string>();
string line;
using(StreamReader file = new StreamReader(input_filename))
{
while((line=file.ReadLine())!=null)
{
if(line.Contains("XA2345")) // Serial Number
{
found.Add(line);
using(StreamWriter w = File.AppendText(output_filename))
{
// Console.WriteLine(line);
w.WriteLine(line);
w.Flush();
}
}
}
}
I'd start with some best practices for parsing CSV files with the post Parsing CSV files in C#, with header.
I've also noticed you've got that "found" variable. Are you trying to avoid duplicate lines in your output file but the code is incomplete? I've written the following code under that assumption.
Here are the using statements:
using Microsoft.VisualBasic.FileIO;
using System.Collections.Generic;
using System.IO;
using System.Linq;
Here's the main code:
List<string> foundLines = new List<string>();
using (TextFieldParser parser = new TextFieldParser(inputFilename))
{
// Set up the parser for CSV files
parser.TextFieldType = FieldType.Delimited;
parser.SetDelimiters(",");
using (StreamWriter writer = new StreamWriter(outputFilename, false))
{
while (!parser.EndOfData)
{
string[] values = parser.ReadFields();
string serialNumber = values[0];
if (string.Equals(serialNumber, "XA2345"))
{
string line = string.Join(",", values.Select(Escape));
if (foundLines.Contains(line))
continue; // Skip writing this line more than once
else
foundLines.Add(line); // Remember this line for later
writer.WriteLine(line);
// Do what you need to with the individual column values
string secondValue = values[1];
string thirdValue = values[2];
// ... Etc. ...
}
}
}
}
And here's a CSV helping method for escaping values as needed at Good CSV writer for C#:
static private string Escape(string s)
{
const string QUOTE = "\"";
const string ESCAPED_QUOTE = "\"\"";
char[] CHARACTERS_THAT_MUST_BE_QUOTED = { ',', '"', '\n' };
if (s.Contains(QUOTE))
s = s.Replace(QUOTE, ESCAPED_QUOTE);
if (s.IndexOfAny(CHARACTERS_THAT_MUST_BE_QUOTED) > -1)
s = QUOTE + s + QUOTE;
return s;
}
How to append text (from txt file e.g englishWord.txt) to the end of all lines (from another txt file e.g PolishWord.Txt) ?
i have one txt file with many english word and translated polish word in another txt file. I would like the result to be such as it:
englishWord.txt:
familiar
involve
ability
expand
polishWord.txt:
znajomy
angażować
umiejętność
rozszerzać
Program make the result.txt like this:
familiar - znajomy
involve - angazować
ability - umiejętność
expand - rozszerzac
Thanks for your attention. I’m looking forward to your reply.
Sorry for my bad English.
This is what i tried:
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApp8
{
class Program
{
static void Main(string[] args)
{
string englishWord = File.ReadAllText("c:/temp/english.txt");
string polishWord = File.ReadAllText("c:/temp/polish.txt");
foreach (var lineE in englishWord)
{
string lineEnglish = lineE;
}
foreach (var lineP in polishWord)
{
string linePolish = lineP;
}
string result = lineEnglish + " - " + linePolish;
result = File.WriteAllText"c:/temp/result.txt";
}
}
}
An easy way to do this would be to first read the line from both files, split those lines by spaces into two arrays, then iterate through those arrays at the same time. I.E.:
System.IO.StreamReader english = new System.IO.StreamReader("englishWord.txt");
System.IO.StreamReader polish = new System.IO.StreamReader("polishWord.txt");
String englishLine = english.ReadLine();
String polishLine = polish.ReadLine();
String englishWords[] = englishLine.split(' ');
String polishWords[] = polishLine.split(' ');
for (int i = 0; i < englishWords.Length; i++) {
/* Output englishWords[i] and polishWords[i] to result.txt here */
}
Hope this helps!
Try this:
using (var english = new StreamReader("englishWord.txt"))
using (var polish = new StreamReader("polishWord.txt"))
using (var result = new StreamWriter("result.txt"))
{
while (!english.EndOfStream && !polish.EndOfStream)
{
result.Write(english.ReadLine());
result.Write(" - ");
result.Write(polish.ReadLine());
result.WriteLine();
}
}
This produces results exactly like in the specification. However, if you're trying to build something like a dictionary I'd suggest other formats like writing to Excel file or a csv file.
//load files
var englishFile = File.OpenText("englishWord.txt").ReadToEnd();
var polishFile = File.OpenText("polishWord.txt").ReadToEnd();
//convert to string arrays
var englishArray = englishFile.Split(' ');
var polishArray = polishFile.Split(' ');
//build output string
String outputString = "";
//take the lenght of the shorter array in case they're not the same length
int maxLength = Math.Min(englishArray.Length, polishArray.Length);
for (int i=0; i<maxLength; i++)
{
outputString += englishArray[i] + " - " + polishArray[i] + " ";
}
//write output to file
File.WriteAllText("results.txt", outputString);
I have a csv file that I need to read in the first line and save it to a List. Only problem is there are commas in some of the text and it is splitting in the middle of a field when I need it not to. Unfortunately I cannot change the data inside so whats there needs to stay. I currently also write the data to csv so I was thinking maybe instead of using a comma I can use a different character. Does anyone know if this is possible? I have been researching but am not coming up with a proper answer. Here is my code below:
using System;
using System.CodeDom;
using System.IO;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
namespace TestJSON
{
class Program
{
static void Main()
{
var data = JsonConvert.DeserializeObject<dynamic>(File.ReadAllText(
#"C:\Users\nphillips\workspace\2016R23\UITestAutomation\SeedDataGenerator\src\staticresources\seeddata.resource"));
string fileName = "";
var bundles = data.RecordSetBundles;
foreach (var bundle in bundles)
{
var records = bundle.Records;
foreach (var record in records)
{
var test = record.attributes;
foreach (var testagain in test)
{
// Getting the object Name Ex. Location, Item, etc.
var jprop = testagain as JProperty;
if (jprop != null)
{
fileName = jprop.First.ToString().Split('_')[2]+ ".csv";
}
break;
}
string header = "";
string value = "";
foreach (var child in record)
{
var theChild = child as JProperty;
if (theChild != null && !theChild.Name.Equals("attributes"))
{
header += child.Name + ",";
value += child.Value.ToString() + ",";
}
}
value += "+" + Environment.NewLine;
if (!File.Exists(fileName))
{
header += "+" + Environment.NewLine;
File.WriteAllText(fileName, header);
}
else
{
// Need to read in here
var readCSV = new StreamReader(fileName);
var splits = readCSV.ReadLine();
}
File.AppendAllText(fileName, value);
}
}
}
}
}
You need to know how the file is delimited. I would guess that this file is tab delimited, so split on that instead.
Assuming your line is called myCSVLine... I.E
string seperator = "\t";
string[] splitLine = myCSVLine.Split(seperator.ToCharArray());
splitLine would now have all of your strings, including ones with commas
I'm trying to cycle through a .txt to build a test function for another application I'm building.
I've got a list of UK based lat/long values that are formatted like this:
Latitude: 57°39′55″N 57.665198
Longitude: 6°57′27″W -6.95739395
Distance: 184.8338 mi Bearing: 329.815°
with the intended result of this small application being just the lat/long values:
57.665198
-6.95739395
So far I've got a StreamReader working with a myString.StartsWith("Latitude") {} but I'm stuck.
How do I detect a splitstring of 2 spaces " " inside of a string and delete everything before that? My code so far is this:
static void Main(string[] args)
{
string text = "";
using (var streamReader = new StreamReader(#"c:\mb\latlong.txt", Encoding.UTF8))
{
text = streamReader.ReadToEnd();
if (text.Trim().StartsWith("Latitude: "))
{
text.Split()
} else if (text.StartsWith("Distance: "))
{
} else if (text.StartsWith(""))
{
}
streamReader.ReadLine();
}
Console.ReadKey();
}
Thanks in advance
You can try using regular expressions
var result = File
.ReadLines(#"C:\MyFile.txt")
.SelectMany(line => Regex
.Matches(line, #"(?<=\s)-?[0-9]+(\.[0-9]+)*$")
.OfType<Match>()
.Select(match => match.Value));
Test
// 57.665198
// -6.95739395
Console.Write(String.Join(Environment.NewLine, result));
Use string.IndexOf(" ") to find the position of the two spaces in the string. Then you can use string.Substring(position) to get the string after that point.
In your code:
if (text.Trim().StartsWith("Latitude: "))
{
var positionOfTwoSpaces = text.IndexOf(" ");
var latString = text.Substring(positionOfTwoSpaces);
var latValue = float.Parse(latString);
}
You can try the regular expression solution. (You might need to fix up the space counts in the regex definitions)
static void Main(string[] args)
{
string text = "";
Regex lat = new Regex("Latitude: .+? (.+)");
Regex lon = new Regex("Longitude .+? (.+)");
using (var streamReader = new StreamReader(#"c:\mb\latlong.txt", Encoding.UTF8))
{
string line;
while ((line = streamReader.ReadLine() != null)
{
if (lat.IsMatch(line))
lat.Match(line).Groups[1].Value // latitude
else if(lon.IsMatch(line))
lon.Match(line).Groups[1].Value // longitude
}
}
Console.ReadKey();
}
A simple solution would be
string[] fileLines = IO.File.ReadAllLines("input file path");
List<string> resultLines = new List<string>();
foreach (string line in fileLines) {
string[] parts = line.Split(" "); //Double space
if (parts.Count() > 1) {
string lastPart = parts.LastOrDefault();
if (!string.IsNullOrEmpty(lastPart)) {
resultLines.Add(lastPart);
}
}
}
IO.File.WriteAllLines("output file path", resultLines.ToArray());
As I already suggested in my comment. You can look for the last occurrence of the space and substring from there.
using System;
using System.IO;
using System.Text;
public class Test
{
public static void Main()
{
String line = String.Empty;
while(!String.IsNullOrEmpty((line = streamReader.ReadLine())))
{
if(line.StartsWith("Latitude:"))
{
line = line.Substring(line.LastIndexOf(' ') + 1);
Console.WriteLine(line);
}
}
Console.ReadKey();
}
}
Working example.
I didn't provide all the code because this is just copy paste for the longitude case. I think you can do this by your own. :)
What I want to do is actually have my program open up and set a string array so that i can use it for if commands (its used to block people) and I want to store another string in there so that it can be saved and still be used if the program restart. Can someone show me how to do this? Please and thank you :]
You could use the following:
string[] lines = File.ReadAllLines(#"Path here").ToArray();
This splits each line up into the array.
As for saving to file, google "saving to file in c#", you will get plenty of results and tutorials.
This is definitely better then the solution I posted first:
File.WriteAllLines(fileName, yourStringArray);
yourStringArray = File.ReadAllLines(fileName);
File.WriteAllLines
File.ReadAllLines
Below my first answer. Correct, but crap!
Something like this should work for you. Don't blame me for inaccuracy, I am not wide awake yet! ;)
{
string fileName = #"d:\temp\blacklist.txt";
char seperator = ';';
public Form1()
{
InitializeComponent();
string[] users = { "Dave", "John", "Shawn" };
//Save(users);
users = Load();
}
public string[] Load()
{
string line;
using (StreamReader sr = new StreamReader(this.fileName))
{
line = sr.ReadToEnd();
}
return line.Split(seperator);
}
public void Save(string[] users)
{
using (StreamWriter sw = new StreamWriter(this.fileName))
{
string line = string.Empty;
foreach (string user in users)
{
line += string.Format("{0}{1}", user, seperator);
}
sw.WriteLine(line);
sw.Flush();
}
}
}