Faster than String.Replace() - c#

Is there any other method that is faster than doing like this?
private void EscapeStringSequence(ref string data)
{
data = data.Replace("\\", "\\\\"); // Backslash
data = data.Replace("\r", "\\r"); // Carriage return
data = data.Replace("\n", "\\n"); // New Line
data = data.Replace("\a", "\\a"); // Vertical tab
data = data.Replace("\b", "\\b"); // Backspace
data = data.Replace("\f", "\\f"); // Formfeed
data = data.Replace("\t", "\\t"); // Horizontal tab
data = data.Replace("\v", "\\v"); // Vertical tab
data = data.Replace("\"", "\\\""); // Double quotation mark
data = data.Replace("'", "\\'"); // Single quotation mark
}
-- Edited (Add explanation) --
Q1: Is there a reason why you need to speed it up? Is it causing a huge problem?
This part is used in this project: http://mysqlbackuprestore.codeplex.com/
I'm going to loop lots of various length of strings into this function repeatly. The whole process takes around 6-15 seconds to finished for millions of rows. There are other part get involve too. I'm trying to speed up every part.
Q2: How slow is it now?
OK, I'll capture the exact time used and post it here. I'll come back later. (will post the result tomorrow)
Update 29-06-2012
I have run test. This is the result:
Speed Test: String.Replace() - measured in miliseconds
Test 1: 26749.7531 ms
Test 2: 27063.438 ms
Test 3: 27753.8884 ms
Average: 27189.0265 ms
Speed: 100%
Speed Test: Foreach Char and Append - measured in miliseconds
Test 1: 8468.4547 ms
Test 2: 8348.8527 ms
Test 3: 8353.6476 ms
Average: 8390.3183 ms
Speed: 224% < faster
===================================
Update - Next Test (Another round)
===================================
------
Test Replace String Speed.
Test 1: 26535.6466
Test 2: 26379.6464
Test 3: 26379.6463
Average: 26431.6464333333
Speed: 100%
------
Test Foreach Char String Append.
Test 1: 8502.015
Test 2: 8517.6149
Test 3: 8595.6151
Average: 8538.415
Speed: 309.56%
------
Test Foreach Char String Append (Fix StringBuilder Length).
Test 1: 8314.8146
Test 2: 8330.4147
Test 3: 8346.0146
Average: 8330.41463333333
Speed: 317.29%
Conclusion:
Using Foreach Char Loop and Append is faster than String.Replace().
Thanks you very much guys.
--------
Below are the codes that I used to run the test: (edited)
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
Console.Write("Press any key to continue...");
Console.ReadKey();
Console.Write("\r\nProcess started.");
Test();
Console.WriteLine("Done.");
Console.Read();
}
public static Random random = new Random((int)DateTime.Now.Ticks);
public static string RandomString(int size)
{
StringBuilder sb = new StringBuilder();
char ch;
for (int i = 0; i < size; i++)
{
ch = Convert.ToChar(Convert.ToInt32(Math.Floor(26 * random.NextDouble() + 65)));
sb.Append(ch);
}
return sb.ToString();
}
public static void Test()
{
string text = "\\_\r\n\a\b\f\t\v\"'" + RandomString(2000) + "\\_\r\n\a\b\f\t\v\"'" + RandomString(2000);
List<TimeSpan> lstTimeUsed = new List<TimeSpan>();
int target = 100000;
for (int i = 0; i < 3; i++)
{
DateTime startTime = DateTime.Now;
for (int j = 0; j < target; j++)
{
if (j.ToString().EndsWith("000"))
{
Console.Clear();
Console.WriteLine("Test " + i.ToString());
Console.WriteLine(j.ToString() + " of " + target.ToString());
}
string data = text;
data = data.Replace("\\", "\\\\"); // Backslash
data = data.Replace("\r", "\\r"); // Carriage return
data = data.Replace("\n", "\\n"); // New Line
data = data.Replace("\a", "\\a"); // Vertical tab
data = data.Replace("\b", "\\b"); // Backspace
data = data.Replace("\f", "\\f"); // Formfeed
data = data.Replace("\t", "\\t"); // Horizontal tab
data = data.Replace("\v", "\\v"); // Vertical tab
data = data.Replace("\"", "\\\""); // Double quotation mark
data = data.Replace("'", "\\'"); // Single quotation mark
}
DateTime endTime = DateTime.Now;
TimeSpan ts = endTime - startTime;
lstTimeUsed.Add(ts);
}
double t1 = lstTimeUsed[0].TotalMilliseconds;
double t2 = lstTimeUsed[1].TotalMilliseconds;
double t3 = lstTimeUsed[2].TotalMilliseconds;
double tOri = (t1 + t2 + t3) / 3;
System.IO.TextWriter tw = new System.IO.StreamWriter("D:\\test.txt", true);
tw.WriteLine("------");
tw.WriteLine("Test Replace String Speed. Test Time: " + DateTime.Now.ToString());
tw.WriteLine("Test 1: " + t1.ToString());
tw.WriteLine("Test 2: " + t2.ToString());
tw.WriteLine("Test 3: " + t3.ToString());
tw.WriteLine("Average: " + tOri.ToString());
tw.WriteLine("Speed: 100%");
tw.Close();
lstTimeUsed = new List<TimeSpan>();
for (int i = 0; i < 3; i++)
{
DateTime startTime = DateTime.Now;
for (int j = 0; j < target; j++)
{
if (j.ToString().EndsWith("000"))
{
Console.Clear();
Console.WriteLine("Test " + i.ToString());
Console.WriteLine(j.ToString() + " of " + target.ToString());
}
string data = text;
var builder = new StringBuilder();
foreach (var ch in data)
{
switch (ch)
{
case '\\':
case '\r':
case '\n':
case '\a':
case '\b':
case '\f':
case '\t':
case '\v':
case '\"':
case '\'':
builder.Append('\\');
break;
default:
break;
}
builder.Append(ch);
}
}
DateTime endTime = DateTime.Now;
TimeSpan ts = endTime - startTime;
lstTimeUsed.Add(ts);
}
t1 = lstTimeUsed[0].TotalMilliseconds;
t2 = lstTimeUsed[1].TotalMilliseconds;
t3 = lstTimeUsed[2].TotalMilliseconds;
tw = new System.IO.StreamWriter("D:\\test.txt", true);
tw.WriteLine("------");
tw.WriteLine("Test Foreach Char String Append. Test Time: " + DateTime.Now.ToString());
tw.WriteLine("Test 1: " + t1.ToString());
tw.WriteLine("Test 2: " + t2.ToString());
tw.WriteLine("Test 3: " + t3.ToString());
tw.WriteLine("Average: " + ((t1 + t2 + t3) / 3).ToString());
tw.WriteLine("Speed: " + ((tOri) / ((t1 + t2 + t3) / 3) * 100).ToString("0.00") + "%");
tw.Close();
lstTimeUsed = new List<TimeSpan>();
for (int i = 0; i < 3; i++)
{
DateTime startTime = DateTime.Now;
for (int j = 0; j < target; j++)
{
if (j.ToString().EndsWith("000"))
{
Console.Clear();
Console.WriteLine("Test " + i.ToString());
Console.WriteLine(j.ToString() + " of " + target.ToString());
}
string data = text;
var builder = new StringBuilder(data.Length + 20);
foreach (var ch in data)
{
switch (ch)
{
case '\\':
case '\r':
case '\n':
case '\a':
case '\b':
case '\f':
case '\t':
case '\v':
case '\"':
case '\'':
builder.Append('\\');
break;
default:
break;
}
builder.Append(ch);
}
}
DateTime endTime = DateTime.Now;
TimeSpan ts = endTime - startTime;
lstTimeUsed.Add(ts);
}
t1 = lstTimeUsed[0].TotalMilliseconds;
t2 = lstTimeUsed[1].TotalMilliseconds;
t3 = lstTimeUsed[2].TotalMilliseconds;
tw = new System.IO.StreamWriter("D:\\test.txt", true);
tw.WriteLine("------");
tw.WriteLine("Test Foreach Char String Append (Fix StringBuilder Length). Test Time: " + DateTime.Now.ToString());
tw.WriteLine("Test 1: " + t1.ToString());
tw.WriteLine("Test 2: " + t2.ToString());
tw.WriteLine("Test 3: " + t3.ToString());
tw.WriteLine("Average: " + ((t1 + t2 + t3) / 3).ToString());
tw.WriteLine("Speed: " + ((tOri) / ((t1 + t2 + t3) / 3) * 100).ToString("0.00") + "%");
tw.Close();
}
}
}

var builder = new StringBuilder(data.Length + 20);
foreach (var ch in data)
{
switch (ch)
{
case '\\':
case '\r':
...
builder.Append('\\');
break;
}
builder.Append(ch);
}
return builder.ToString();

Try using a series of StringBuilder calls.

Related

C# - Building an Array from Text File

I am attempting to build an array of batting averages from a .txt file, but most of the resources I am finding online to assist in how to work this out either work with text in the following format:
1 2 3 4 5
2 3 4 5 6
etc.
... or in the following format:
1, 2
3, 4
etc.
Unfortunately, my text file is in the following format, and changing the format is not an option. Each odd line number denotes a player, with the following even line number being their average at bat in that instance (just information for context):
1
2
3
4
Using this file, I want to assign the odd numbers to the index of the array, and then populate the even numbers as values, calculating them as I go. I believe that I can parse out how to accomplish the calculations, I just cannot ascertain how to grab the data nor associate the odd numbers with array indexes.
Code as follows. File is to be specified by user:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
static string FileName()
{
string doc = Console.ReadLine();
return doc;
}
static void Main(string[] args)
{
try
{
Console.Write("Where is the data file for batting averages located? ");
string doc = FileName();
StreamReader reader = new StreamReader(doc);
string avg = reader.ReadToEnd();
reader.Close();
}
catch (System.IO.FileNotFoundException)
{
Console.WriteLine("The file can not be found.");
}
catch (System.FormatException)
{
Console.WriteLine("Invalid file.");
}
catch (System.ArgumentException)
{
Console.WriteLine("Enter a valid file name.");
}
catch (System.Exception exc)
{
Console.WriteLine(exc.Message);
}
}
Any assistance would be welcome. Please keep in mind I am a student and still learning the earliest parts of C#, so any truly advanced techniques are probably going to be lost on me.
You can read the Text file Line by line (or use System.IO.File.ReadAllLines - to get a string[] - Link). Now Odd/Even indices can be read and processed per your wish.
Tip: Your text file format is basic and error prone.
You can do something like this:
var lines = File.ReadAllLines(FileName());
for (int i = 0; i < lines.Length; i += 2)
{
Console.WriteLine($"Player Name: {lines[i]}");
Console.WriteLine($"Player Average: {lines[i + 1]}");
}
After working late into the night yesterday, I came up with code that resolved my issue:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
class Program
{
static void Main(string[] args)
{
Console.Write("Where is the data file for batting averages located? ");
string doc = Console.ReadLine();
int[] avg = new int[9];
int val1=0, val2=0, val3=0, val4=0, val5=0, val6=0, val7=0, val8=0, val9=0;
int cnt1=0, cnt2=0, cnt3=0, cnt4=0, cnt5=0, cnt6=0, cnt7=0, cnt8=0, cnt9=0;
try
{
StreamReader reader = new StreamReader(doc);
var lines = File.ReadAllLines(doc);
int[] index = Array.ConvertAll(lines, int.Parse);
//Console.WriteLine(lines); //displays contents of text file
reader.Close();
for (int i = 0; i < index.Length; i += 2)
{
switch (index[i])
{
case 1:
cnt1++;
val1 = val1 + index[i + 1];
break;
case 2:
cnt2++;
val2 = val2 + index[i + 1];
break;
case 3:
cnt3++;
val3 = val3 + index[i + 1];
break;
case 4:
cnt4++;
val4 = val4 + index[i + 1];
break;
case 5:
cnt5++;
val5 = val5 + index[i + 1];
break;
case 6:
cnt6++;
val6 = val6 + index[i + 1];
break;
case 7:
cnt7++;
val7 = val7 + index[i + 1];
break;
case 8:
cnt8++;
val8 = val8 + index[i + 1];
break;
case 9:
cnt9++;
val9 = val9 + index[i + 1];
break;
default:
break;
}
}
int total = cnt1 + cnt2 + cnt3 + cnt4 + cnt5 + cnt6 + cnt7 + cnt8 + cnt9;
decimal avg1 = Convert.ToDecimal(val1) / Convert.ToDecimal(cnt1);
decimal avg2 = Convert.ToDecimal(val2) / Convert.ToDecimal(cnt2);
decimal avg3 = Convert.ToDecimal(val3) / Convert.ToDecimal(cnt3);
decimal avg4 = Convert.ToDecimal(val4) / Convert.ToDecimal(cnt4);
decimal avg5 = Convert.ToDecimal(val5) / Convert.ToDecimal(cnt5);
decimal avg6 = Convert.ToDecimal(val6) / Convert.ToDecimal(cnt6);
decimal avg7 = Convert.ToDecimal(val7) / Convert.ToDecimal(cnt7);
decimal avg8 = Convert.ToDecimal(val8) / Convert.ToDecimal(cnt8);
decimal avg9 = Convert.ToDecimal(val9) / Convert.ToDecimal(cnt9);
Console.WriteLine("{0} pairs of data read.", total);
Console.WriteLine("The batting average for:");
Console.WriteLine(" position 1 is {0}", Math.Round(avg1, 4));
Console.WriteLine(" position 2 is {0}", Math.Round(avg2, 4));
Console.WriteLine(" position 3 is {0}", Math.Round(avg3, 4));
Console.WriteLine(" position 4 is {0}", Math.Round(avg4, 4));
Console.WriteLine(" position 5 is {0}", Math.Round(avg5, 4));
Console.WriteLine(" position 6 is {0}", Math.Round(avg6, 4));
Console.WriteLine(" position 7 is {0}", Math.Round(avg7, 4));
Console.WriteLine(" position 8 is {0}", Math.Round(avg8, 4));
Console.WriteLine(" position 9 is {0}", Math.Round(avg9, 4));
}
catch (System.IO.FileNotFoundException) //file not present
{
Console.WriteLine("The file {0} was not found.", doc);
}
catch (System.IndexOutOfRangeException)
{
Console.WriteLine("Incomplete data pairs. Please re-check your data entries and retry.");
}
catch (System.FormatException) //bad data
{
Console.WriteLine("Invalid file.");
}
catch (System.ArgumentException) //null entry
{
Console.WriteLine("Make sure you enter a valid file name.");
}
catch (System.Exception exc) //any other exceptions
{
Console.WriteLine(exc.Message);
}
}
}
}
I know parts of it are a bit clunky, but as long as it works, I can learn more about condensing the information as I attend more classes. Thank you both for your assistance.

OpenQA.Selenium.ElementNotInteractableException : Cannot click on element

public PriceChangeRequestStatus SelectPcrFrom(String[] fromdate)
{
wrapper.Click(imgPcrFrom);
String year, day, month;
day = fromdate[0];
month = fromdate[1];
year = fromdate[2];
//for (int index = 0; index <= 1; index++)
wrapper.Click(lnkPcrFrom);
wrapper.Click(lnkPcrFrom);
Thread.Sleep(4000);
driver.FindElement(By.XPath("//div[contains(text(),'" + year + "')]")).Click();
Thread.Sleep(4000);
driver.FindElement(By.XPath("//div[contains(text(),'" + findMonth(month).Substring(0, 3) + "')]")).Click();
Thread.Sleep(2000);
driver.FindElement(By.XPath("//div[contains(#title,'" + findMonth(month) + " " + day + ", " + year + "')]")).Click();
Thread.Sleep(2000);
return this;
}
public PriceChangeRequestStatus SelectPcrTo(String[] todate)
{
wrapper.Click(imgPcrTo);
wrapper.Click(lnkPcrTo);
wrapper.Click(lnkPcrTo);
String year, day, month;
day = todate[0];
month = todate[1];
year = todate[2];
Thread.Sleep(4000);
// By Sunayana
//IJavaScriptExecutor js = (IJavaScriptExecutor)driver;
//js.ExecuteScript("document.getElementsByClassName('ajax__calendar_year')");
// End
//// IReadOnlyList<IWebElement> yearClick = wrapper.GetElements("xpath:=.//div[#class='ajax__calendar_year']");
//IList<IWebElement> yearClick = driver.FindElements(By.XPath(".//div[#class='ajax__calendar_year']"));
//Console.WriteLine(yearClick.Count);
//for (int index = 1; index-1 <= yearClick.Count; index++)
//{
// int i=0;
// Console.WriteLine(index);
// i=index;
// if (yearClick[i].GetAttribute("innerHTML").Equals(year))
// {
// yearClick[i].Click();
// Console.WriteLine("I am here");
// }
// else {
// Console.WriteLine("Sorry");
// }
//}
Thread.Sleep(4000);
//var wait = new WebDriverWait(driver, TimeSpan.FromSeconds(10));
//try
//{
// wait.Until(ExpectedConditions.ElementToBeClickable(By.XPath("//div[contains(text(),'" + year + "')]"))).Click();
//}
//catch (WebDriverTimeoutException)
//{
// Console.WriteLine("Logout button was not visible!");
//}
IWebElement clickyear = driver.FindElement(By.XPath("//div[contains(text(),'" +year+ "')]"));
clickyear.Click();
//Actions action = new Actions(driver);
//action.MoveToElement(clickyear).Click().Build().Perform();
Thread.Sleep(4000);
driver.FindElement(By.XPath("//div[contains(text(),'" + findMonth(month).Substring(0, 3) + "')]")).Click();
Thread.Sleep(2000);
driver.FindElement(By.XPath("//div[contains(#title,'" + findMonth(month) + " " + day + ", " + year + "')]")).Click();
Thread.Sleep(2000);
return this;
}
public String findMonth(String month)
{
String CorrectMonth = "";
switch (month) {
case "01":
CorrectMonth = "January";
break;
case "02":
CorrectMonth = "February";
break;
case "03":
CorrectMonth = "March";
break;
case "04":
CorrectMonth = "April";
break;
case "05":
CorrectMonth = "May";
break;
case "06":
CorrectMonth = "June";
break;
case "07":
CorrectMonth = "July";
break;
case "08":
CorrectMonth = "August";
break;
case "09":
CorrectMonth = "September";
break;
case "10":
CorrectMonth = "October";
break;
case "11":
CorrectMonth = "November";
break;
case "12":
CorrectMonth = "December";
break;
}
return CorrectMonth;
}
Edited the code and tried running the script. The logic written for SELECTPCRFROM is working fine but the same logic is not working for SELECTPCRTO. tried many others solutions but still SELECTPCRTO is nor working as expected Please help me on this. The executed code is displaying error message provided in the title
Most of the datepickers gets identified by xpath but when you try perform an operation on them then they would give you an error. Instead try going the javascript way.
Java -
document.evaluate(PATH, document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue;
Similary you can use it in C#
Refer the answer here - link

c# ncalc - line 1:1 missing EOF at 'x'

Im playing around with a genetic algorithm for solving eqvations.
So I've found this lib called NCAL which seems to be a nice way to go.
So I've tried to generate som random strings that will become NCALC Expressions like this:
private Expression getRandomExpression(int i)
{
string expression = ""; ;
double nr = random.NextDouble() * random.Next(100);
int sign = 1;
if (random.Next(2) > 0)
{
sign = -1;
}
Console.WriteLine("sign: " + sign + " i: " + i);
switch (i)
{
case 1:
expression = (sign.ToString() + "*" + nr.ToString() + "x");
break;
case 2:
expression = (sign.ToString() + nr.ToString() + "/x");
break;
case 3:
expression = (sign.ToString() + "x/" + nr.ToString());
break;
case 4:
expression = (sign.ToString() + "Pow(x," + nr.ToString()+")");
break;
default:
expression = (sign.ToString() + "*" + nr.ToString());
break;
}
return new Expression(expression);
}
And then I want to loop over these elements and check the sum against my goalfunction, like this:
public double calculateFitness(double[] goalFunction)
{
double fitness = 0.0;
for (int i = 1; i < goalFunction.Length; i++)
{
foreach (var element in genome)
{
try
{
element.Parameters["x"] = i;
var value = (double)element.Evaluate();
fitness += Math.Abs(goalFunction.ElementAt(i) - value);
}catch(Exception ex)
{
throw ex;
}
}
}
return fitness;
}
Seems easy but I keep getting this exception saying "line 1:1 missing EOF at 'x'". Any suggestions on how to solve this? Or easier ways to go. :)
I want to be able to find a equation representing the goalfunction.
br

Convert a complicated txt file into a csv file using c#

I have absolutely no idea what to do with this but here is a snippet of the file that I'm trying to convert:
"September
3Beef
Lamb Chops
4Fish
Not Fish
5Mac and Cheese
PB & J"
The csv file is supposed to print the date what comes after in quotes, so the above should look like:
Tuesday September Third 2013 "Beef" "Lamb Chops"
Wednesday September Fourth 2013 "Fish" "Not Fish"
Thursday September Fifth 2013 "Mac and Cheese" "PB&J"
Here is what I have so far:
StreamReader reader = new StreamReader(#"..\..\Lunches.txt");
while (!reader.EndOfStream)
{
string currentLine = reader.ReadLine();
}
StreamWriter writer = new StreamWriter(#"..\..\Lunches.csv");
// date.ToString("ddddd yyyyy mm MMMMMM");
string delimiter = ",";
Here is the code
private void Form1_Load(object sender, EventArgs e)
{
string sayka = "August\n\n" +
"31Beef\n" +
"Lamb Chops\n" +
"24Fish\n" +
"Not Fish\n" +
"15Mac and Cheese\n" +
"PB & J\n";
MessageBox.Show(makeCSV(sayka));
}
string getMonthName(int val)
{
switch (val)
{
case 1: return "JANUARY";
case 2: return "FEBRUARY";
case 3: return "MARCH";
case 4: return "APRIL";
case 5: return "MAY";
case 6: return "JUNE";
case 7: return "JULY";
case 8: return "AUGUST";
case 9: return "SEPTEMBER";
case 10: return "OCTOBER";
case 11: return "NOVEMBER";
case 12: return "DECEMBER";
default: return null;
}
}
string getDayName(int val)
{
switch (val)
{
case 1: return "First";
case 2: return "Second";
case 3: return "Third";
case 4: return "Fourth";
case 5: return "Fifth";
case 6: return "Sixth";
case 7: return "Seventh";
case 8: return "Eighth";
case 9: return "Nineth";
case 10: return "Tenth";
case 11: return "Eleventh";
case 12: return "Twelth";
case 13: return "Thirteenth";
case 14: return "Fouteenth";
case 15: return "Fifteenth";
case 16: return "Sixteenth";
case 17: return "Seventeenth";
case 18: return "Eighteenth";
case 19: return "Nineteenth";
case 20: return "Twentieth";
default: return "";
}
}
string getDayName2(int val)
{
if (val == 30) return "Thirtieth";
else if (val > 30) return "Thirty " + getDayName(val % 30);
else if (val > 20) return "Twenty " + getDayName(val % 20);
else return getDayName(val);
}
string makeCSV(string val)
{
string res = "";
string[] ss = val.Split('\n');
int curMonth = 0;
for (int i = 0; i < ss.Length; i++)
{
if (ss[i].Trim() != "")
{
bool isInt = false;
try
{
int intA = Convert.ToInt32(ss[i][0].ToString());
isInt = true;
}
catch { }
if (isInt)
{
bool isDoubleInt = false;
try
{
int intB = Convert.ToInt32(ss[i][1].ToString());
isDoubleInt = true;
}
catch { }
int date = 0;
if (isDoubleInt) date = Convert.ToInt32(ss[i].Remove(2));
else date = Convert.ToInt32(ss[i][0].ToString());
DateTime dt = new DateTime(DateTime.Now.Year, curMonth, date);
string itemName = "";
if (isDoubleInt) itemName = ss[i].Substring(2);
else itemName = ss[i].Substring(1);
string itemName2 = ss[i + 1];
res += dt.DayOfWeek + " " + getMonthName(dt.Month) + " " + getDayName2(dt.Day) + " \"" + itemName + "\"" + " \"" + itemName2 + "\"\n";
}
else
{
for (int j = 1; j < 13; j++)
if (ss[i].ToUpper().StartsWith(getMonthName(j)))
{
curMonth = j;
break;
}
}
}
}
return res;
}
}
From the filestream either use StreamReader.readToEnd(), get the string and use the function, Or if the file is big then use it line by line..
Rate if this helps..
This is going to be a bit complicated. I left out some things for you to do.
String[] months = { "January", "February", "March", ....};
Date processDate = new Date();
while (!reader.EndOfStream)
{
string currentLine = reader.ReadLine();
// skip this line if blank
if (String.IsNullOrEmpty(currentLine)) continue;
if (months.Contains(currentLine)) {
// we have a new starting month.
// reset the process date
Int32 month = DateTime.ParseExact(currentLine.Trim(), "MMMM", CultureInfo.CurrentCulture).Month;
date = Convert.ToDate(month.ToString() + "/01/2013");
continue;
}
// here's where the real fun begins:
// you have to pull out the first two characters and test if one or both are digits.
// This will give you the day. Put that into your date variable.
Int32 day = 0;
char[] arr = currentLine.ToCharArray(0, currentLine.Length);
if (Char.IsDigit(arr[1])) {
// first two characters are numbers
day = Convert.ToInt32(currentLine.Substring(0,2));
currentLine = currentLine.Remove(0,2);
} else {
// only the first character is a number
day = Convert.ToInt32(currentLine.Substring(0,1));
currentLine = currentLine.Remove(0,1);
}
// set the new date
date = new DateTime(date.Year, date.Month, day, 0, 0, 0);
// If we can assume that ALL lines are broken into two parts then we can do the following:
String secondLine = reader.ReadLine();
currentLine = String.Format("{0} {1}", currentLine, secondLine);
// At this point you have the month, day, and the entire line.
// write it to your lunch stream or store in a StringBuilder
}

Writing a string to a file causes an exception in C#

I'm getting a "FormatException: Input string was not in a correct format" error that I don't understand.
I'm using the following lines to write a string to a text file:
using (StreamWriter sw = new StreamWriter(myfilename, false, System.Text.Encoding.GetEncoding(enc)))
{
sw.Write(mystring, Environment.NewLine);
}
(the encoding part is because I do have an option in my application to set it to utf-8 or iso-8859-1... but I think that's irrelevant).
All of my strings write out just fine except this one string that is different from the others because it actually has a snippet of javascript code in it. I'm sure that one of the special characters there might be causing the problem but how do I know?
The one thing I tried was to insert the following line just before the sw.Write statement above:
System.Console.WriteLine(mystring);
and it wrote out to the console just fine - no error.
Help?
Thanks! (and Happy New Year!)
-Adeena
The overload you are using takes the format as the first parameter, and objects to inject after that.
You can do either of the following:
sw.Write(mystring + Environment.NewLine);
or
sw.Write("{0}{1}", mystring, Environment.NewLine);
In response to the comments from DK, I tested to what extend string concatenation is slower. I made this setup with three options;
concatenating the string
calling sw.Write twice
calling sw.WriteLine
On my machine, the second option is about 88% faster than average. At 10000000 iterations they use 3517, 2420 and 3385 milliseconds.
It should only be significant if this is code that is called many times in your program.
using System;
using System.IO;
using System.Text;
class Program
{
static void Main(string[] args)
{
const string myString = "kdhlkhldhcĂžehdhkjehdkhekdhk";
int iterations=getIntFromParams(args, 0, 10);
int method = getIntFromParams(args, 1, 0);
var fileName=Path.GetTempFileName();
using (StreamWriter sw = new StreamWriter(fileName, false, Encoding.Default))
{
switch (method)
{
case 0:
Console.WriteLine("Starting method with concatenation. Iterations: " + iterations);
var start0 = DateTimeOffset.Now;
for (int i = 0; i < iterations; i++)
{
sw.Write(myString + Environment.NewLine);
}
var time0 = DateTimeOffset.Now - start0;
Console.WriteLine("End at " + time0.TotalMilliseconds + " ms.");
break;
case 1:
Console.WriteLine("Starting method without concatenation. Iterations: " + iterations);
var start1 = DateTimeOffset.Now;
for (int i = 0; i < iterations; i++)
{
sw.Write(myString);
sw.Write(Environment.NewLine);
}
var time1 = DateTimeOffset.Now - start1;
Console.WriteLine("End at " + time1.TotalMilliseconds + " ms.");
break;
case 2:
Console.WriteLine("Starting method without concatenation, using WriteLine. Iterations: " + iterations);
var start2 = DateTimeOffset.Now;
for (int i = 0; i < iterations; i++)
{
sw.WriteLine(myString);
}
var time2 = DateTimeOffset.Now - start2;
Console.WriteLine("End at " + time2.TotalMilliseconds + " ms.");
break;
}
}
}
private static int getIntFromParams(string[] args, int index, int #default)
{
int value;
try
{
if (!int.TryParse(args[index], out value))
{
value = #default;
}
}
catch(IndexOutOfRangeException)
{
value = #default;
}
return value;
}
}

Categories