I had a requirement to create a TextWriter to populate some data. I used the StringWriter as a TextWriter and the business logic works fine.
I have a technical requirement that cannot be changed because it may break all the clients. I need to an array of strings string[] from the TextWriter separated by line.
I tried with this but didn't work:
using System;
using System.IO;
using System.Text;
namespace TextWriterToArrayOfStringsDemo
{
internal static class Program
{
private static void Main()
{
var stringBuilder = new StringBuilder();
using (TextWriter writer = new StringWriter(stringBuilder))
{
writer.Write("A");
writer.WriteLine();
writer.Write("B");
}
string fullString = stringBuilder.ToString();
string replaced = fullString.Replace('\n', '\r');
string[] arrayOfString = replaced.Split('\r');
// Returns false but should return true
Console.WriteLine(arrayOfString.Length == 2);
}
}
}
Any idea or suggestion?
Try using Environment.NewLine to split rather than '\n':
var stringBuilder = new StringBuilder();
using (TextWriter writer = new StringWriter(stringBuilder))
{
writer.Write("A");
writer.WriteLine();
writer.Write("B");
}
string fullString = stringBuilder.ToString();
string[] newline = new string[] { Environment.NewLine };
string[] arrayOfString = fullString.Split(newline, StringSplitOptions.RemoveEmptyEntries);
// Returns false but should return true
Console.WriteLine(arrayOfString.Length == 2);
A quick fix would be to use a Regex split:
string[] arrayOfString =
System.Text.RegularExpressions.Regex.Split(stringBuilder.ToString(), "\r?\n")
Related
I am trying to write a program to remove open an XML file with Non-ASCII characters and replace those characters with spaces and save and close the file.
Thats basically it, just open the file remove all the non ascii characters and save/close the file.
Here is my code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.IO;
using System.Text.RegularExpressions;
namespace RemoveSpecial
{
class Program
{
static void Main(string[] args)
{
string pth_input = string.Empty;
string pth_output = string.Empty;
for (int i = 1; i < args.Length; i++)
{
//input one
string p_input = args[0];
pth_input = p_input;
pth_input = pth_input.Replace(#"\", #"\\");
//output
string p_output = args[2];
pth_output = p_output;
pth_output = pth_output.Replace(#"\", #"\\");
}
//s = Regex.Replace(s, #"[^\u0000-\u007F]+", string.Empty);
string lx;
using (StreamReader sr = new StreamReader(pth_input))
{
using (StreamWriter x = new StreamWriter(pth_output))
{
while ((lx = sr.ReadLine()) != null)
{
string text = sr.ReadToEnd();
Regex.Replace(text, #"[^\u0000-\u007F]+", "", RegexOptions.Compiled);
x.Write(text);
} sr.Close();
}
}
}
}
}
Thanks in advance guys.
According to documentation, the first string is an input parameter (and not passed by reference, so it could not change anyway). The result of the replacement is in the return value, like so:
var result = Regex.Replace(text, #"[^\u0000-\u007F]+", "", RegexOptions.Compiled);
x.Write(result);
Note that RegexOptions.Compiled might decrease performance here. It makes sense only if you reuse the same regular expression instance on multiple strings. You can still do that, if you create the RegEx instance outside of the loop:
var regex = new Regex(#"[^\u0000-\u007F]+", RegexOptions.Compiled);
using (var sr = new StreamReader(pth_input))
{
using (var x = new StreamWriter(pth_output))
{
while ((lx = sr.ReadLine()) != null)
{
var text = sr.ReadToEnd();
var result = regex.Replace(text, String.Empty);
x.Write(result);
}
}
}
Currently working on a project for a car park. I have a csv file which contains strings of information regarding car license plates. I have used regex already to return 90% of the license plates, however shorter personalised number plates aren;t returning correctly: ie "AA12" returns as "AA12BC" as it fits another regex.
Each string has two instances of the car license plate, is there a way to only return strings that prove correct for the regex and two instances of the number plate.
Code so far:
//start
using (TextReader reader = File.OpenText(#"C:\Users\user\documents\regdata.csv"))
{
List<string> lines = new List<string>();
string pattern = #"[A-Z]{3}[0-9]{3}";
string line;
while ((line = reader.ReadLine()) != null)
{
lines.Add(line);
}
List<string> regExs = new List<string>();
regExs.Add(#"[A-Z]{3}[0-9]{3}");
regExs.Add(#"[A-Z]{2}[0-9]{2}[A-Z]{3}");
regExs.Add(#"[A-Z]{1}[0-9]{3}[A-Z]{3}");
regExs.Add(#"[A-Z]{1}[0-9]{2}[A-Z]{3}");
regExs.Add(#"[A-Z]{1}[0-9]{1}[A-Z]{3}");
regExs.Add(#"[A-Z]{3}[0-9]{2,3}");
regExs.Add(#"[A-Z]{2}[0-9]{4}");
regExs.Add(#"[A-Z]{3}[0-9]{2}");
regExs.Add(#"[A-Z]{2}[0-9]{2}[A-Z]{3}");
using (StreamWriter writer = new StreamWriter(#"C: \Users\user\Desktop\usersNotes\plates.csv"))
{
foreach (var l in lines.Select(x => x.Split(',')[2]))
{
string result = "";
foreach (var r in regExs)
{
Regex myRegex = new Regex(r);
Match m = myRegex.Match(l);
if (m.Success)
{
result = m.Value;
break;
}
}
writer.WriteLine(l + "," + result);
}
Thanks
This should do it for you. I went ahead and coded (I think) the whole solution for you as I understand it. I made a Regex list rather than a string list; this way you don't have to build and tear down every Regex object with each loop.
Assumptions: (1) Plates never have " or , and (2) Plates don't show up more than twice.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.IO;
using System.Text;
using System.Windows.Forms;
using System.Text.RegularExpressions;
namespace DupeOnly {
public partial class Form1 : Form{
public Form1(){
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e){
string zRegData = File.ReadAllText(#"C:\Users\user\documents\regdata.csv");
HashSet<string> hsRegData = new HashSet<string>();
bool tfFirst = true;
string[] zAllPlateData = zRegData.Split(','); //License plates don't have comma's
List<Regex> rxList = new List<Regex>();
rxList.Add(new Regex(#"[A-Z]{3}[0-9]{3}"));
rxList.Add(new Regex(#"[A-Z]{2}[0-9]{2}[A-Z]{3}"));
rxList.Add(new Regex(#"[A-Z]{1}[0-9]{3}[A-Z]{3}"));
rxList.Add(new Regex(#"[A-Z]{1}[0-9]{2}[A-Z]{3}"));
rxList.Add(new Regex(#"[A-Z]{1}[0-9]{1}[A-Z]{3}"));
rxList.Add(new Regex(#"[A-Z]{3}[0-9]{2,3}"));
rxList.Add(new Regex(#"[A-Z]{2}[0-9]{4}"));
rxList.Add(new Regex(#"[A-Z]{3}[0-9]{2}"));
rxList.Add(new Regex(#"[A-Z]{2}[0-9]{2}[A-Z]{3}"));
Match m;
using (StreamWriter sw = new StreamWriter(#"C: \Users\user\Desktop\usersNotes\plates.csv")){
for(int Q = 0; Q < zAllPlateData.Length; Q++){
if(hsRegData.Add(zAllPlateData[Q]) == false){
//At this point we know it is a duplicate, must still match a check pattern
foreach(Regex rx in rxList){
m = rx.Match(zAllPlateData[Q]);
if(m.Success){
if(tfFirst){
tfFirst = false;
sw.Write(zAllPlateData[Q]); //First plate doesn't take a comma
}
else{
sw.Write("," + zAllPlateData[Q]); //Comma delimit subsequent plates
}
break;
}
}
}
}
}
}
}
}
So, I know my headline is a bit confusing, I will explain.
My code looks like this:
string filename = "C:\\C#\\maplist.txt"; // please put the text file path.
string filename2 = "C:\\C#\\zemaplist.txt";
string map;
StreamReader sr = new StreamReader(filename);
StreamWriter sw = new StreamWriter(filename2);
List<string> maps = new List<string> { };
while ((map = sr.ReadLine()) != null)
{
maps.Add(map);
}
sr.Close();
for (int i = 0; i < maps.Count; i++)
{
Console.WriteLine(maps[i]);
sw.WriteLine(maps[i]);
}
sw.Close();
and what i need to do is when the code read a new line, in my line there is
"Hey,Hey"
I want to split the , from each other so I can take both of them as other parameters, so that the first Hey will be added to maps and the other hey will be maps2,
How can I do that?
You can use Split() function to Split the given String based on delimiter.
Try This:
while ((map = sr.ReadLine()) != null)
{
maps.Add(map.Split(',')[0].Trim());
maps2.Add(map.Split(',')[1].Trim());
}
Simple Code:
using System.IO;
string filename = "C:\\C#\\maplist.txt"; // please put the text file path.
string filename2 = "C:\\C#\\zemaplist.txt";
string map;
StreamWriter sw = new StreamWriter(filename2);
List<string> maps = new List<string> { };
List<string> maps2 = new List<string> { };
String [] allLines = File.ReadAllLines(filename);
foreach(String line in allLines)
{
maps.Add(line.Split(',')[0].Trim());
maps2.Add(line.Split(',')[1].Trim());
}
for (int i = 0; i < maps.Count; i++)
{
Console.WriteLine(maps[i]);
sw.WriteLine(maps[i]);
}
sw.Close();
Solution 2:
String mapItem1="";
String mapItem2="";
if(maps.Count == maps2.Count)
{
for(int i=0;i<maps.Count;i++)
{
mapItem1=maps[i];
mapItem2=maps2[i];
}
}
while ((map = sr.ReadLine()) != null)
{
string[] split = map.Split(',');
//First Hey would be split[0], second Hey would be split[1]
maps.Add(split[0].Trim());
maps2.Add(split[1].Trim());
}
The Split method should help you out with that.
If you want to trim leading whitespace characters, you can use the .Trim() method on a string.
Use Split().
string heys = "Hey,Hey";
string[] splitArray = heys.Split(',');
Then you have:
splitArray[0] = "Hey";
splitArray[1] = "Hey";
Why even bother reading line by line? Read the entire file, replace the new line chars for a "," (to prevent last and first elements from different lines to be treated as one), and loop through a clean string.
string fileContent = Regex.Replace(File.ReadAllText("test.txt"), #"\r", ",");
List<string> mapList = new List<string>();
foreach (string map in Regex.Split(fileContent.Replace(#"\s+", ""), ","))
{
mapList.Add(map.Trim());
}
I'm trying to count the number of words from a text file, namely this, to start.
This is a test of the word count program. This is only a test. If your
program works successfully, you should calculate that there are 30
words in this file.
I am using StreamReader to put everything from the file into a string, and then use the .Split method to get the number of individual words, but I keep getting the wrong value when I compile and run the program.
using System;
using System.IO;
class WordCounter
{
static void Main()
{
string inFileName = null;
Console.WriteLine("Enter the name of the file to process:");
inFileName = Console.ReadLine();
StreamReader sr = new StreamReader(inFileName);
int counter = 0;
string delim = " ,.";
string[] fields = null;
string line = null;
while(!sr.EndOfStream)
{
line = sr.ReadLine();
}
fields = line.Split(delim.ToCharArray());
for(int i = 0; i < fields.Length; i++)
{
counter++;
}
sr.Close();
Console.WriteLine("The word count is {0}", counter);
}
}
Try to use regular expression, e.g.:
int count = Regex.Matches(input, #"\b\w+\b").Count;
this should work for you:
using System;
using System.IO;
class WordCounter
{
static void Main()
{
string inFileName = null;
Console.WriteLine("Enter the name of the file to process:");
inFileName = Console.ReadLine();
StreamReader sr = new StreamReader(inFileName);
int counter = 0;
string delim = " ,."; //maybe some more delimiters like ?! and so on
string[] fields = null;
string line = null;
while(!sr.EndOfStream)
{
line = sr.ReadLine();//each time you read a line you should split it into the words
line.Trim();
fields = line.Split(delim.ToCharArray(), StringSplitOptions.RemoveEmptyEntries);
counter+=fields.Length; //and just add how many of them there is
}
sr.Close();
Console.WriteLine("The word count is {0}", counter);
}
}
A couple hints.
What if you just have the sentence "hi" what would be your output?
Your counter calculation is: from 0 through fields.Length, increment counter. How are fields.Length and your counter related?
you're probably getting a one off error, try something like this
counter = 0;
while(!sr.EndOfStream)
{
line = sr.ReadLine();
fields = line.Split(delim.ToCharArray());
counter += field.length();
}
there is no need to iterate over the array to count the elements when you can get the number directly
using System.IO;
using System;
namespace solution
{
class Program
{
static void Main(string[] args)
{
var readFile = File.ReadAllText(#"C:\test\my.txt");
var str = readFile.Split(new char[] { ' ', '\n'}, StringSplitOptions.RemoveEmptyEntries);
System.Console.WriteLine("Number of words: " + str.Length);
}
}
}
//Easy method using Linq to Count number of words in a text file
/// www.techhowdy.com
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace FP_WK13
{
static class Util
{
public static IEnumerable<string> GetLines(string yourtextfile)
{
TextReader reader = new StreamReader(yourtextfile);
string result = string.Empty;
string line;
while ((line = reader.ReadLine()) != null)
{
yield return line;
}
reader.Close();
}
// Word Count
public static int GetWordCount(string str)
{
int words = 0;
string s = string.Empty;
var lines = GetLines(str);
foreach (var item in lines)
{
s = item.ToString();
words = words + s.Split(' ').Length;
}
return words;
}
}
}
I would really appreciate if somebody could help me/offer advice on this.
I have a file, probably about 50000 lines long, these files are generated on a weekly basis. each line is identical in terms of type of content.
original file:
address^name^notes
but i need to perform a switch. i need to be able to switch (on each and every line) the address with the name. so after the switch has been done, the names will be first, and then addresses and then notes, like so:
result file:
name^address^notes
50,000 isn't that much these days, so simply reading in the whole file and outputting the wanted format should work fine for you:
string[] lines = File.ReadAllLines(fileName);
string newLine = string.Empty;
foreach (string line in lines)
{
string[] items = line.Split(myItemDelimiter);
newLine = string.Format("{0},{1},{2}", items[1], items[0], items[2]);
// Append to new file here...
}
How about this?
StreamWriter sw = new StreamWriter("c:\\output.txt");
StreamReader sr = new StreamReader("c:\\input.txt");
string inputLine = "";
while ((inputLine = sr.ReadLine()) != null)
{
String[] values = null;
values = inputLine.Split('^');
sw.WriteLine("{0}^{1}^{2}", values[1], values[0], values[2]);
}
sr.Close();
sw.Close();
Go go gadget REGEX!
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ConsoleApplication1
{
class Program
{
static string Switcheroo(string input)
{
return System.Text.RegularExpressions.Regex.Replace
(input,
#"^([^^]+)\^([^^]+)\^(.+)$",
"$2^$1^$3",
System.Text.RegularExpressions.RegexOptions.Multiline);
}
static void Main(string[] args)
{
string input = "address 1^name 1^notes1\n" +
"another address^another name^more notes\n" +
"last address^last name^last set of notes";
string output = Switcheroo(input);
Console.WriteLine(output);
Console.ReadKey(true);
}
}
}