I am trying to write into a csv file row by row using C# language. Here is my function
string first = reader[0].ToString();
string second=image.ToString();
string csv = string.Format("{0},{1}\n", first, second);
File.WriteAllText(filePath, csv);
The whole function runs inside a loop, and every row should be written to the csv file. In my case, next row overwrites the existing row and in the end, I am getting an only single record in the csv file which is the last one. How can I write all the rows in the csv file?
UPDATE
Back in my naïve days, I suggested doing this manually (it was a simple solution to a simple question), however due to this becoming more and more popular, I'd recommend using the library CsvHelper that does all the safety checks, etc.
CSV is way more complicated than what the question/answer suggests.
Original Answer
As you already have a loop, consider doing it like this:
//before your loop
var csv = new StringBuilder();
//in your loop
var first = reader[0].ToString();
var second = image.ToString();
//Suggestion made by KyleMit
var newLine = string.Format("{0},{1}", first, second);
csv.AppendLine(newLine);
//after your loop
File.WriteAllText(filePath, csv.ToString());
Or something to this effect.
My reasoning is: you won't be need to write to the file for every item, you will only be opening the stream once and then writing to it.
You can replace
File.WriteAllText(filePath, csv.ToString());
with
File.AppendAllText(filePath, csv.ToString());
if you want to keep previous versions of csv in the same file
C# 6
If you are using c# 6.0 then you can do the following
var newLine = $"{first},{second}"
EDIT
Here is a link to a question that explains what Environment.NewLine does.
I would highly recommend you to go the more tedious route. Especially if your file size is large.
using(var w = new StreamWriter(path))
{
for( /* your loop */)
{
var first = yourFnToGetFirst();
var second = yourFnToGetSecond();
var line = string.Format("{0},{1}", first, second);
w.WriteLine(line);
w.Flush();
}
}
File.AppendAllText() opens a new file, writes the content and then closes the file. Opening files is a much resource-heavy operation, than writing data into open stream. Opening\closing a file inside a loop will cause performance drop.
The approach suggested by Johan solves that problem by storing all the output in memory and then writing it once. However (in case of big files) you program will consume a large amount of RAM and even crash with OutOfMemoryException
Another advantage of my solution is that you can implement pausing\resuming by saving current position in input data.
upd. Placed using in the right place
Writing csv files by hand can be difficult because your data might contain commas and newlines. I suggest you use an existing library instead.
This question mentions a few options.
Are there any CSV readers/writer libraries in C#?
I use a two parse solution as it's very easy to maintain
// Prepare the values
var allLines = (from trade in proposedTrades
select new object[]
{
trade.TradeType.ToString(),
trade.AccountReference,
trade.SecurityCodeType.ToString(),
trade.SecurityCode,
trade.ClientReference,
trade.TradeCurrency,
trade.AmountDenomination.ToString(),
trade.Amount,
trade.Units,
trade.Percentage,
trade.SettlementCurrency,
trade.FOP,
trade.ClientSettlementAccount,
string.Format("\"{0}\"", trade.Notes),
}).ToList();
// Build the file content
var csv = new StringBuilder();
allLines.ForEach(line =>
{
csv.AppendLine(string.Join(",", line));
});
File.WriteAllText(filePath, csv.ToString());
Instead of calling every time AppendAllText() you could think about opening the file once and then write the whole content once:
var file = #"C:\myOutput.csv";
using (var stream = File.CreateText(file))
{
for (int i = 0; i < reader.Count(); i++)
{
string first = reader[i].ToString();
string second = image.ToString();
string csvRow = string.Format("{0},{1}", first, second);
stream.WriteLine(csvRow);
}
}
You can use AppendAllText instead:
File.AppendAllText(filePath, csv);
As the documentation of WriteAllText says:
If the target file already exists, it is overwritten
Also, note that your current code is not using proper new lines, for example in Notepad you'll see it all as one long line. Change the code to this to have proper new lines:
string csv = string.Format("{0},{1}{2}", first, image, Environment.NewLine);
Instead of reinventing the wheel a library could be used. CsvHelper is great for creating and reading csv files. It's read and write operations are stream based and therefore also support operations with a big amount of data.
You can write your csv like the following.
using(var textWriter = new StreamWriter(#"C:\mypath\myfile.csv"))
{
var writer = new CsvWriter(textWriter, CultureInfo.InvariantCulture);
writer.Configuration.Delimiter = ",";
foreach (var item in list)
{
writer.WriteField( "a" );
writer.WriteField( 2 );
writer.WriteField( true );
writer.NextRecord();
}
}
As the library is using reflection it will take any type and parse it directly.
public class CsvRow
{
public string Column1 { get; set; }
public bool Column2 { get; set; }
public CsvRow(string column1, bool column2)
{
Column1 = column1;
Column2 = column2;
}
}
IEnumerable<CsvRow> rows = new [] {
new CsvRow("value1", true),
new CsvRow("value2", false)
};
using(var textWriter = new StreamWriter(#"C:\mypath\myfile.csv")
{
var writer = new CsvWriter(textWriter, CultureInfo.InvariantCulture);
writer.Configuration.Delimiter = ",";
writer.WriteRecords(rows);
}
value1,true
value2,false
If you want to read more about the librarys configurations and possibilities you can do so here.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Data;
using System.Configuration;
using System.Data.SqlClient;
public partial class CS : System.Web.UI.Page
{
protected void ExportCSV(object sender, EventArgs e)
{
string constr = ConfigurationManager.ConnectionStrings["constr"].ConnectionString;
using (SqlConnection con = new SqlConnection(constr))
{
using (SqlCommand cmd = new SqlCommand("SELECT * FROM Customers"))
{
using (SqlDataAdapter sda = new SqlDataAdapter())
{
cmd.Connection = con;
sda.SelectCommand = cmd;
using (DataTable dt = new DataTable())
{
sda.Fill(dt);
//Build the CSV file data as a Comma separated string.
string csv = string.Empty;
foreach (DataColumn column in dt.Columns)
{
//Add the Header row for CSV file.
csv += column.ColumnName + ',';
}
//Add new line.
csv += "\r\n";
foreach (DataRow row in dt.Rows)
{
foreach (DataColumn column in dt.Columns)
{
//Add the Data rows.
csv += row[column.ColumnName].ToString().Replace(",", ";") + ',';
}
//Add new line.
csv += "\r\n";
}
//Download the CSV file.
Response.Clear();
Response.Buffer = true;
Response.AddHeader("content-disposition", "attachment;filename=SqlExport.csv");
Response.Charset = "";
Response.ContentType = "application/text";
Response.Output.Write(csv);
Response.Flush();
Response.End();
}
}
}
}
}
}
Handling Commas
For handling commas inside of values when using string.Format(...), the following has worked for me:
var newLine = string.Format("\"{0}\",\"{1}\",\"{2}\"",
first,
second,
third
);
csv.AppendLine(newLine);
So to combine it with Johan's answer, it'd look like this:
//before your loop
var csv = new StringBuilder();
//in your loop
var first = reader[0].ToString();
var second = image.ToString();
//Suggestion made by KyleMit
var newLine = string.Format("\"{0}\",\"{1}\"", first, second);
csv.AppendLine(newLine);
//after your loop
File.WriteAllText(filePath, csv.ToString());
Returning CSV File
If you simply wanted to return the file instead of writing it to a location, this is an example of how I accomplished it:
From a Stored Procedure
public FileContentResults DownloadCSV()
{
// I have a stored procedure that queries the information I need
SqlConnection thisConnection = new SqlConnection("Data Source=sv12sql;User ID=UI_Readonly;Password=SuperSecure;Initial Catalog=DB_Name;Integrated Security=false");
SqlCommand queryCommand = new SqlCommand("spc_GetInfoINeed", thisConnection);
queryCommand.CommandType = CommandType.StoredProcedure;
StringBuilder sbRtn = new StringBuilder();
// If you want headers for your file
var header = string.Format("\"{0}\",\"{1}\",\"{2}\"",
"Name",
"Address",
"Phone Number"
);
sbRtn.AppendLine(header);
// Open Database Connection
thisConnection.Open();
using (SqlDataReader rdr = queryCommand.ExecuteReader())
{
while (rdr.Read())
{
// rdr["COLUMN NAME"].ToString();
var queryResults = string.Format("\"{0}\",\"{1}\",\"{2}\"",
rdr["Name"].ToString(),
rdr["Address"}.ToString(),
rdr["Phone Number"].ToString()
);
sbRtn.AppendLine(queryResults);
}
}
thisConnection.Close();
return File(new System.Text.UTF8Encoding().GetBytes(sbRtn.ToString()), "text/csv", "FileName.csv");
}
From a List
/* To help illustrate */
public static List<Person> list = new List<Person>();
/* To help illustrate */
public class Person
{
public string name;
public string address;
public string phoneNumber;
}
/* The important part */
public FileContentResults DownloadCSV()
{
StringBuilder sbRtn = new StringBuilder();
// If you want headers for your file
var header = string.Format("\"{0}\",\"{1}\",\"{2}\"",
"Name",
"Address",
"Phone Number"
);
sbRtn.AppendLine(header);
foreach (var item in list)
{
var listResults = string.Format("\"{0}\",\"{1}\",\"{2}\"",
item.name,
item.address,
item.phoneNumber
);
sbRtn.AppendLine(listResults);
}
}
return File(new System.Text.UTF8Encoding().GetBytes(sbRtn.ToString()), "text/csv", "FileName.csv");
}
Hopefully this is helpful.
This is a simple tutorial on creating csv files using C# that you will be able to edit and expand on to fit your own needs.
First you’ll need to create a new Visual Studio C# console application, there are steps to follow to do this.
The example code will create a csv file called MyTest.csv in the location you specify. The contents of the file should be 3 named columns with text in the first 3 rows.
https://tidbytez.com/2018/02/06/how-to-create-a-csv-file-with-c/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
namespace CreateCsv
{
class Program
{
static void Main()
{
// Set the path and filename variable "path", filename being MyTest.csv in this example.
// Change SomeGuy for your username.
string path = #"C:\Users\SomeGuy\Desktop\MyTest.csv";
// Set the variable "delimiter" to ", ".
string delimiter = ", ";
// This text is added only once to the file.
if (!File.Exists(path))
{
// Create a file to write to.
string createText = "Column 1 Name" + delimiter + "Column 2 Name" + delimiter + "Column 3 Name" + delimiter + Environment.NewLine;
File.WriteAllText(path, createText);
}
// This text is always added, making the file longer over time
// if it is not deleted.
string appendText = "This is text for Column 1" + delimiter + "This is text for Column 2" + delimiter + "This is text for Column 3" + delimiter + Environment.NewLine;
File.AppendAllText(path, appendText);
// Open the file to read from.
string readText = File.ReadAllText(path);
Console.WriteLine(readText);
}
}
}
public static class Extensions
{
public static void WriteCSVLine(this StreamWriter writer, IEnumerable<string> fields)
{
const string q = #"""";
writer.WriteLine(string.Join(",",
fields.Select(
v => (v.Contains(',') || v.Contains('"') || v.Contains('\n') || v.Contains('\r')) ? $"{q}{v.Replace(q, q + q)}{q}" : v
)));
}
public static void WriteCSVLine(this StreamWriter writer, params string[] fields) => WriteCSVLine(writer, (IEnumerable<string>)fields);
}
This should allow you to write a csv file quite simply. Usage:
StreamWriter writer = new ("myfile.csv");
writer.WriteCSVLine("A", "B"); // A,B
Here is another open source library to create CSV file easily, Cinchoo ETL
List<dynamic> objs = new List<dynamic>();
dynamic rec1 = new ExpandoObject();
rec1.Id = 10;
rec1.Name = #"Mark";
rec1.JoinedDate = new DateTime(2001, 2, 2);
rec1.IsActive = true;
rec1.Salary = new ChoCurrency(100000);
objs.Add(rec1);
dynamic rec2 = new ExpandoObject();
rec2.Id = 200;
rec2.Name = "Tom";
rec2.JoinedDate = new DateTime(1990, 10, 23);
rec2.IsActive = false;
rec2.Salary = new ChoCurrency(150000);
objs.Add(rec2);
using (var parser = new ChoCSVWriter("emp.csv").WithFirstLineHeader())
{
parser.Write(objs);
}
For more information, please read the CodeProject article on usage.
One simple way to get rid of the overwriting issue is to use File.AppendText to append line at the end of the file as
void Main()
{
using (System.IO.StreamWriter sw = System.IO.File.AppendText("file.txt"))
{
string first = reader[0].ToString();
string second=image.ToString();
string csv = string.Format("{0},{1}\n", first, second);
sw.WriteLine(csv);
}
}
enter code here
string string_value= string.Empty;
for (int i = 0; i < ur_grid.Rows.Count; i++)
{
for (int j = 0; j < ur_grid.Rows[i].Cells.Count; j++)
{
if (!string.IsNullOrEmpty(ur_grid.Rows[i].Cells[j].Text.ToString()))
{
if (j > 0)
string_value= string_value+ "," + ur_grid.Rows[i].Cells[j].Text.ToString();
else
{
if (string.IsNullOrEmpty(string_value))
string_value= ur_grid.Rows[i].Cells[j].Text.ToString();
else
string_value= string_value+ Environment.NewLine + ur_grid.Rows[i].Cells[j].Text.ToString();
}
}
}
}
string where_to_save_file = #"d:\location\Files\sample.csv";
File.WriteAllText(where_to_save_file, string_value);
string server_path = "/site/Files/sample.csv";
Response.ContentType = ContentType;
Response.AppendHeader("Content-Disposition", "attachment; filename=" + Path.GetFileName(server_path));
Response.WriteFile(server_path);
Response.End();
You might just have to add a line feed "\n\r".
private void button33_Click_1(object sender, EventArgs e)
{
DialogResult result = openFileDialog1.ShowDialog();
if (result == DialogResult.OK)
{
DialogResult result2 = folderBrowserDialog1.ShowDialog();
if (result2 == DialogResult.OK)
{
ZipFile.ExtractToDirectory(openFileDialog1.FileName,
folderBrowserDialog1.SelectedPath);
MessageBox.Show("ZIP file extracted successfully!");
}
}
OpenFileDialog openFileDialog = new OpenFileDialog();
openFileDialog.Multiselect = true;
openFileDialog.Filter = "Text files (*.txt)|*.txt|All files
(*.*)|*.*";
openFileDialog.InitialDirectory =
Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
if (openFileDialog.ShowDialog(this) == DialogResult.OK)
{
XNamespace xns = "http://www.opengis.net/kml/2.2";
XDocument xdInput = XDocument.Load(openFileDialog.FileName);
XElement xeDocument = xdInput.Root.Element(xns + "Document");
XElement xePlaceMark = xeDocument.Element(xns + "Placemark");
XElement xeCoord = xePlaceMark.Descendants(xns +
"coordinates").First();
string[] lines = xeCoord.Value.Trim().Split(new string[] { ",0 "
}, StringSplitOptions.RemoveEmptyEntries);
File.AppendAllLines(#"C:\New folder\longlat.txt", lines);
}
in this code it extract the xml filesand save the vales from
<coordinates>
80.41501791166907,15.31966921785412,80.66681262872422,15.30770770315245,81.04469571795477,15.27884283211159,0
</coordinates>
these tags and save it in longlat text file. like this it saves for other coordinates from other document ,and my final output got looks like
80.41501791166907,15.31966921785412
80.66681262872422,15.30770770315245
81.04469571795477,15.27884283211159,0
81.03730709247927,15.27205299521836
80.99634866995486,14.75503556947802,0
the first 3 is 1 set and next 2 is second set etc...
what i need to do count the no of lines in first set and write on top of first set ,again count the the second set of lines write on top of second set ,and then it should continue for entire set of coordinates tag extracted.
o/p i need to obtain is in this manner
3 0
80.41501791166907,15.31966921785412
80.66681262872422,15.30770770315245
81.04469571795477,15.27884283211159
2 0
81.03730709247927,15.27205299521836
80.99634866995486,14.75503556947802
etc....
3- number of line along with space and 0 . Can you guys help me out.
You might need two Splits, one with ",0" and followed one with ",".
var lines = xeCoord.Value.Trim()
.Split(new string[] {",0"}, StringSplitOptions.RemoveEmptyEntries)
.Select(x=>
{
int i=0;
var splits = x.Split(new string[] {","},StringSplitOptions.RemoveEmptyEntries)
.GroupBy(g=> i++/2) //Group for consecutive values to form a coordinate.
.Select(s=>string.Join(",",s)) // Join them
.ToList();
splits.Insert(0,splits.Count().ToString()); // Insert the count at the beginning
return splits;
})
.SelectMany(x=>x); // flatten the structure
// now write these lines to file.
File.AppendAllLines(#"C:\New folder\longlat.txt", lines);
Check this Demo
Try this
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Xml;
using System.Xml.Linq;
namespace ConsoleApplication1
{
class Program
{
const string FILENAME = #"c:\temp\test.csv";
static void Main(string[] args)
{
StreamWriter writer = new StreamWriter(FILENAME);
string input = "<coordinates>80.41501791166907,15.31966921785412,80.66681262872422,15.30770770315245,81.04469571795477,15.27884283211159,0 </coordinates>";
XDocument doc = XDocument.Parse(input);
string[] groups = ((string)doc.Element("coordinates")).Trim().Split(new string[] {",0"}, StringSplitOptions.RemoveEmptyEntries);
Boolean first = true;
foreach (string group in groups)
{
if (first)
{
first = false;
}
else
{
writer.WriteLine();
}
string[] coordinates = group.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
writer.WriteLine("{0} {1}", coordinates.Length / 2, 0);
writer.WriteLine();
for (int i = 0; i < coordinates.Count() - 1; i += 2)
{
writer.WriteLine("{0},{1}", coordinates[i], coordinates[i + 1]);
}
}
writer.Flush();
writer.Close();
}
}
}
I have a text file contains several lines with words, for example like this
cards
door
lounge
dog
window
I want to add a new word into that list with the condition that it does not already exist in the list. For example I want to add wind or car
I use File.ReadAllText(#"C:\Temp.txt").Contains(word)
But the problem is window contains wind and cards contain car
Is there any way to compare it uniquely?
If you have not a huge file, you can read it to memory and process it like any array:
var lines = File.ReadAllLines(#"C:\Temp.txt");
if(lines.Any(x=>x == word)
{
//There is a word in the file
}
else
{
//Thee is no word in the file
}
Use File.ReadLine() and check for with String.equals(), dont look for substrings. Something Like this:
while(!reader.EndOfFile0
{
if(String.Compare(reader.ReadLine(),inputString, true) == 0)
{
//do your stuf here
}
}
You should do through Regex match so that you are matching an exact work, and I have made this below as case insensitive.
using ConsoleApplication3;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text.RegularExpressions;
public static class Program
{
private static void Main(string[] args)
{
// Read the file and display it line by line.
System.IO.StreamReader file =
new System.IO.StreamReader("c:\\temp\\test.txt");
var line = string.Empty;
string fileData = file.ReadToEnd();
file.Close();
fileData = "newword".InsertSkip(fileData);
StreamWriter fileWrite = new StreamWriter(#"C:\temp\test.txt", false);
fileWrite.Write(fileData);
fileWrite.Flush();
fileWrite.Close();
}
public static string InsertSkip(this string word, string data)
{
var regMatch = #"\b(" + word + #")\b";
Match result = Regex.Match(data, regMatch, RegexOptions.Singleline | RegexOptions.IgnoreCase);
if (result == null || result.Length == 0)
{
data += Environment.NewLine + word;
}
return data;
}
}
Although I am reading an entire file and writing an entire file back. You can improve the performance by only writing one word rather a whole file again.
you can do something like
string newWord = "your new word";
string textFile = System.IO.File.ReadAllText("text file full path");
if (!textFile.Contains(newWord))
{
textFile = textFile + newWord;
System.IO.File.WriteAllText("text file full path",textFile);
}
Original Text in the txtinput will look in this format
Firstportion Seconportion
Firstportion Seconportion
Firstportion Seconportion
Firstportion Seconportion
My Goal is to first split each lines into two variable and add them to an array or list or whatever works [number of lines are variable so array will not work]
var1[] = firstportion, var2=seconportion //so far looks like working for the 1st entry
put those to variable array/list [Not working with the loops i currently have]
the process the first portions seperately and second portion seperatly with conditional if and regural expression and displaythem all back in the 2nd txtbox
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.IO;
using System.Collections;
using System.Text.RegularExpressions;
namespace Projectx
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
string rawInput = txtInput.Text;
//string[] rawInput = txtInput.Text.Split('\n');
int x = 1;
int y = 1;
foreach (string line in txtInput.Lines)
{
string firstPortion= "";
string secondPortion = "";
string[] splitInput = Regex.Split(rawInput, ("\\s+"));
firstPortion= splitInput[0];
secondPortion = splitInput[1];
//##### This works so far ans splits each line into two variables seperated by 1 white space but not sure if it works for 2nd line and seems can't assign these new splited values into two seperate array or list with the same loop or seperate loop
//List<int> list = new List<int>; //(arr)
List<string> myList1 = new List<string>();
List<string> myList2 = new List<string>();
myList1.Add(firtPortion);
myList2.Add(secondPortion);
txtOutPut.Text = "modified " + myList1[x] + " " + myList2[y]+"\r\n";
int i = 1;
i++;
x++;
y++;
}
}
}
}
The List should be declared outside the loop
Why do you use rawInput? Instead you have to use line to do the Split
You dont need the local variables(x,y) instead you could use LastOrDefault()
List<string> myList1 = new List<string>();
List<string> myList2 = new List<string>();
string rawInput = txtInput.Text;
foreach (string line in txtInput.Lines)
{
string firstPortion = "";
string secondPortion = "";
string[] splitInput = Regex.Split(line, ("\\s+"));
firstPortion = splitInput[0];
secondPortion = splitInput[1];
myList1.Add(firstPortion);
myList2.Add(secondPortion);
txtOutPut.Text = "modified " + myList1.LastOrDefault() + " " + myList2.LastOrDefault() + "\r\n";
}
Try declaring your :
List<string> myList1 = new List<string>();
List<string> myList2 = new List<string>();
outside the foreach loop.
There seems to be two big problems.
You're creating a new pair of lists in each iteration rather than adding new items to the same list.
You're splitting the rawInput variable in each iteration rather than the current line.
There are also a number of smaller ones mostly having to do with extraneous or unused variables.
Try something like this:
List<string> myList1 = new List<string>();
List<string> myList2 = new List<string>();
int x = 0;
foreach (string line in txtInput.Lines)
{
string[] splitInput = Regex.Split(line, ("\\s+"));
myList1.Add(splitInput[0]);
myList2.Add(splitInput[1]);
txtOutPut.Text += "modified " + myList1[x] + " " + myList2[x] + Environment.NewLine;
x++;
}
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;
}
}
}