Creating a CSV File in C# - c#

I am trying to created a csv file where each entry is inputed by the user. Once one set of of values have been entered it should move on to the next. However I cannot seem to do the bit. Each time i run the program, it replaces the previous values.
using System;
using System.IO;
using System.Collections.Generic;
namespace FileAccess
{
class MainClass
{
public static void Main(string[] args)
{
string FName;
string LName;
string Dpt;
string Grade;
string NumberOfHours;
string file_name = "EmployeeDetails.txt";
System.IO.StreamWriter objWriter;
objWriter = new System.IO.StreamWriter(file_name);
String[] ArrayDetails = new string[5];
Console.Write("Enter Emp First Name: ");
FName=Console.ReadLine();
Console.Write("Enter Emp Last Name: ");
LName = Console.ReadLine();
Console.Write("Enter Emp Department: ");
Dpt = Console.ReadLine();
Console.Write("Enter Employee Grade: ");
Grade = Console.ReadLine();
Console.Write("Enter Number Of Hours Worked: ");
NumberOfHours = Console.ReadLine();
ArrayDetails[0] = FName;
ArrayDetails[1] = LName;
ArrayDetails[2] = Dpt;
ArrayDetails[3] = Grade;
ArrayDetails[4] = NumberOfHours;
// Create new list of strings
List<string> LDetails = new List<string>(); // Create new list of strings
LDetails.Add(FName); // Add string 1
LDetails.Add(LName); // 2
LDetails.Add(Dpt); // 3
LDetails.Add(Grade); // 4
LDetails.Add(NumberOfHours); // 5
//OutPut the data into the file
string LDetailsCSV = string.Join(",", LDetails.ToArray());
Console.WriteLine(LDetailsCSV);
objWriter.Write(LDetailsCSV);
objWriter.Close();
}
}
}
Some advise please.

The StreamWriter constructor will overwrite the file you are using if it exists. There is an overloaded constructor to which you can pass a boolean as a second argument to tell it to append:
System.IO.StreamWriter objWriter;
objWriter = new System.IO.StreamWriter(file_name, true);
In addition, the Write method you are using will not append a line break. If you use the WriteLine method, it will.
Console.WriteLine(LDetailsCSV);
objWriter.WriteLine(LDetailsCSV);
objWriter.Close();

You have to open the file in append mode, like this:
System.IO.StreamWriter objWriter;
objWriter = new File.AppendText(file_name);

In your case I think you are better off doing something like:
File.AppendAllText("EmployeeDetails.txt", string.Join(",",new [] {FName,LName,Dpt,Grade,NumberOfHours}));

Related

String Maniuplation in C#

I have a program that finds words within a text file and print them out. But this is a school assignment, and I need to use a certain degree of object oriented programming, like using different classes and interfaces.
So, the issue I have is that I have two public classes, that when called and adopted in the main class, with the main method, prints out the two string values I want.
The code looks like this
public class GetFilePath
{
public string FilePath;
public GetFilePath(string fn)
{
/// string path = "testfile.txt";
FilePath = fn;
}
public void SetFilename(string NewFilePath)
{
FilePath = NewFilePath;
}
}
public class GetSearchWord
{
public string WordSearch;
public GetSearchWord(string st)
{
WordSearch = st;
}
public void SetSearchTerm(string NewSearchTerm)
{
WordSearch = NewSearchTerm;
}
}
These are implemented into the main function as follows
Console.Write("please enter a file to search for: ");
// Call the constructor that has no parameters.
GetFilePath Filepath1 = new GetFilePath("");
Console.WriteLine(Filepath1.FilePath);
Filepath1.SetFilename("testfile.txt");
Console.WriteLine(Filepath1.FilePath);
// Call the constructor that has one parameter.
Console.Write("please enter a word to search for in the file: ");
GetSearchWord SearchedWord1 = new GetSearchWord("");
Console.WriteLine(SearchedWord1.WordSearch);
SearchedWord1.SetSearchTerm("true");
Console.WriteLine(SearchedWord1.WordSearch);
But I need to connect Filepath1.FilePath and SearchedWord1.WordSearch to the following strings
string FilePath = "";
string WordSearch = "";
As you can see those are null at the moment.
which are the key strings in my search function that actually searches up the lines with the words!
The FilePath and WordSearched strings are used as following
using (StreamReader fs = File.OpenText(FilePath))
{
int count = 0; //counts the number of times wordResponse is found.
int lineNumber = 0;
while (!fs.EndOfStream)
{
string line = fs.ReadLine();
lineNumber++;
int position = line.IndexOf(WordSearch);
if (position != -1)
{
count++;
Console.WriteLine("Match#{0} line {1}: {2}", count, lineNumber, line);
}
}
if (count == 0)
{
Console.WriteLine("your word was not found!");
}
else
{
Console.WriteLine("Your word was found " + count + " times!");
}
Console.WriteLine("Press enter to quit.");
Console.ReadKey();
}
what I have tried doing is setting
string WordSearch = SearchedWord1.WordSearch;
as an example of what I am trying to achive since, SearchedWord1.WordSearch is currently set to "true" which is the keyword I want to search my file for.
if I understood your question correctly then the following code should solve your problem(update your main code with the following):
Console.Write("please enter a file to search for: ");
// Call the constructor that has no parameters.
var filePathInput = Console.ReadLine();
GetFilePath Filepath1 = new GetFilePath(filePathInput);
Console.WriteLine(Filepath1.FilePath);
Filepath1.SetFilename("testfile.txt");
Console.WriteLine(Filepath1.FilePath);
// Call the constructor that has one parameter.
Console.Write("please enter a word to search for in the file: ");
var searchWordInput = Console.ReadLine();
GetSearchWord SearchedWord1 = new GetSearchWord(searchWordInput);
Console.WriteLine(SearchedWord1.WordSearch);
SearchedWord1.SetSearchTerm("true");
Console.WriteLine(SearchedWord1.WordSearch);
the change is that this code is getting the input from the user...

Creating a list of no duplicate string entries in a text file at C#

I'm a beginner at C# programming.
I wanted to create a text file to the desktop in C# Console, which is wanted to add my input new string value to the created text file's new line.
This is my work:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
namespace noteonce
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("New Word: ");
string newWord = Console.ReadLine();
string wlist = Environment.GetFolderPath(Environment.SpecialFolder.Desktop) + #"\list.txt";
TextWriter inject = new StreamWriter(wlist, true);
inject.WriteLine(newWord);
inject.Close();
Console.WriteLine("New word has been added! ");Console.ReadKey();
}
}
}
I created the file through the console, but I want each of my entered string to be unique, I did some look up on google but I'm so confused. I want the console to tell me that whether the new input already exists or not, If it is, to warn me as "It already exists! Input another word : ", If it does not exist, just to add it to the list. I need your assistance.
Thank you all for your attention. By the help of Mr.Ankitkumar Bhatt, This is my recent work :
static void Main(string[] args)
{
string wlist = Environment.GetFolderPath(Environment.SpecialFolder.Desktop)+#"\list.txt";
FileStream create = File.Open(wlist, FileMode.Create);
create.Close();
for (int i = 0; i < 100; i++)
{
Console.WriteLine("New Word"+#" ("+(100-i)+") :");
string newWord = Console.ReadLine();
string FileContents = File.ReadAllText(Environment.GetFolderPath(Environment.SpecialFolder.Desktop) + #"\list.txt");
TextWriter inject = new StreamWriter(Environment.GetFolderPath(Environment.SpecialFolder.Desktop) + #"\list.txt", true);
if (!FileContents.Contains(newWord))
{
inject.WriteLine(newWord);
inject.Close();
}
else
{
Console.WriteLine("It already exists!");
Console.ReadKey();
inject.Close();
}
}
}
But I want to point that, I want the program to recognize all of items in the list, by my last method, it quite works, but when I close, and open the program again, It doesn't give me the warning that New Word is already exist, doesn't add it to the file neither. How can I do the rest ?
In case of "no duplicate" please, have a look at HashSet<String>; you may find TextWriter and TextReader being too complex - try File.ReadLines(), File.AppendAllLines instead:
static void Main(string[] args) {
// better practice is paths combining
string path = Path.Combine(Environment.SpecialFolder.Desktop, "list.txt");
// unique (no duplicates) strings so far
HashSet<String> hash = new HashSet<string>(
File.ReadLines(path), // file to read from
StringComparer.OrdinalIgnoreCase); // let's ignore words' case ("World", "world")
Console.WriteLine("New Word: ");
string newWord = Console.ReadLine().Trim(); // let's trim spaces: "world " -> "world"
if (!string.IsNullOrEmpty(newWord)) // let's not add an empty string
if (!hash.Contains(newWord)) {
// add new word to the end of file
File.AppendAllLines(path, new string[] {newWord});
Console.WriteLine("New word has been added!");
}
else
Console.WriteLine("It already exists! Input another word");
else
Console.WriteLine("We don't add empty lines.");
Console.ReadKey();
}
In case you want to add several words, one after one (put an empty line to exit):
static void Main(string[] args) {
// better practice is paths combining
string path = Path.Combine(Environment.SpecialFolder.Desktop, "list.txt");
// unique (no duplicates) strings so far
HashSet<String> hash = new HashSet<string>(
File.ReadLines(path), // file to read from
StringComparer.OrdinalIgnoreCase); // let's ignore words' case ("World", "world")
while (true) {
Console.WriteLine("New Word: ");
string newWord = Console.ReadLine().Trim(); // let's trim spaces: "world " -> "world"
if (string.IsNullOrEmpty(newWord))
break;
if (hash.Add(newWord)) {
File.AppendAllLines(path, new string[] {newWord});
Console.WriteLine("New word has been added!");
}
else
Console.WriteLine("It already exists! Input another word.");
}
Console.ReadKey();
}
before injecting word check the word exists or not like below
string FileContents = File.ReadAllText(Environment.GetFolderPath(Environment.SpecialFolder.Desktop) + #"\list.txt");
if (!FileContents.Contains(newWord))
{
// Add to file //
}
this can be accomplished in multiple ways. I will present a solution that most closely will work with your code. There is definitely a more elegant way to accomplish this, but this is a quick and dirty way to accomplish that.
one way is to have a foreach check from your text file so:
var isWordPresent = false;
var textLines = File.ReadAllLines(wlist);
foreach (var line in textLines) {
if (line.contains(newWord) {
isWordPresent = true;
}
}
if (isWordPresent == false) {
inject.WriteLine(newWord);
inject.Close();
isWordPresent = false; //added this portion incase you run this code in a while loop
//so you can reuse it. You would need to have the boolean reset to false
}
1) Read the file and write its content to a string[] (Array of string):
var lines = File.ReadAllLines(wlist , Encoding.UTF8);
2) Read your input and check for duplicates:
var input = Console.ReadLine();
if (lines.Contains(input)) {
//Warning message
} else {
//Success message
}

Editing files with with lists in C#?

I'm trying to teach myself how to edit files in C# and have encountered a problem. I am trying to allow the user to open a file that contains a sentence that says:
"How are you today, <name>?"
I have a class that will read the file and add the sentence to a List. Here is the code that I wrote for that:
class FileReader
{
public string reader(string sentence)
{
string f = sentence;
List<string> lines = new List<string>();
using (StreamReader r = new StreamReader(f))
{
string line;
while ((line = r.ReadLine()) != null)
{
lines.Add(line);
}
return lines.ToString();
}
}
}
Once this is returned as a string, I have another class that will read the list, and then will ask the user for a name. It will then replace <name> with the name the user input. Here is the code I've tried writing to handle this:
class Asker
{
public string asker(string sentence)
{
List<string> lines = new List<string>();
Console.Write("Enter Name: ");
string name = Console.ReadLine();
string text = File.ReadAllText(sentence);
text = text.Replace("<name>", name);
lines.Add(text);
File.WriteAllText(sentence, text);
return lines.ToString();
}
}
By the end of this class, the Asker class should return a list containing the new sentence where name now replaces <name> in the original sentence. In main, I get an error code every time I try to run it. Here is main:
static void Main(string[] args)
{
Console.Write("Enter the name of the story file: ");
string filename = Console.ReadLine();
FileReader read = new FileReader();
string uneditedSentence = read.reader(filename);
Asker ask = new Asker();
string newSentence = ask.asker(uneditedSentence);
Console.WriteLine(newSentence);
}
When I run this program I get a message that it stopped working and just crashes.
Few Edits are required in your code:
1) When you are returning lines.toString()>> it would return System.Collections.Generic.List`1[System.String] and not the text in the file. So you should lines and not lines.String().
so the return type of your function would be List.
Or if you want to return the string then code would be:
class FileReader
{
public string reader(string sentence)
{
string f = sentence;
string lines = "";
using (StreamReader r = new StreamReader(f))
{
string line;
while ((line = r.ReadLine()) != null)
{
lines +=line+ Environment.NewLine;
}
return lines;
}
}
}
2) In your asker class: asker function argument is the content of file and not the filename:
string text = File.ReadAllText(sentence)
so the above code will not work.
A better way: you dont need file reader class:
class Program
{
static void Main(string[] args)
{
Console.Write("Enter the name of the story file: ");
string filename = Console.ReadLine();
Asker ask = new Asker();
string newSentence = ask.asker(filename);
Console.WriteLine(newSentence);
string name = Console.ReadLine();
}
}
class Asker
{
public string asker(string sentence)
{
Console.Write("Enter Name: ");
string name = Console.ReadLine();
string text = File.ReadAllText(sentence);
text = text.Replace("<name>", name);
File.WriteAllText(sentence, text);
return text;
}
}
Your reader method accepts filename as the only argument and returns the contents of the file.
It means that in this line of code uneditedSentence is the contents of file filename:
string uneditedSentence = read.reader(filename);
Then, you pass this uneditedSentence to your asker:
string newSentence = ask.asker(uneditedSentence);
At the same time, your asker method has the following lines:
string text = File.ReadAllText(sentence);
File.WriteAllText(sentence, text);
which expects filepath while you provide contents of it.
It provides a error, because you provide an incorrect file path. The reason of this is very simple - naming. You name your variables inproperly and get confused.
Refer to MSDN documentation on ReadAllText and WriteAllText.
Also, it will not show proper results, because you apply ToString() to the List<string> expecting that it will be converted to the single string. However, it will simply result in something like System.Collections.Generic.List'1[System.String].
Here is how you should have done this:
class FileReader // Actually, it is a useless class, get rid of it
{
public string Read(string filename)
{
return File.ReadAllText(filename);
}
}

Searching for a Specific Word in a Text File and Displaying the line its on

I am having trouble attempting to find words in a text file in C#.
I want to find the word that is input into the console then display the entire line that the word was found on in the console.
In my text file I have:
Stephen Haren,December,9,4055551235
Laura Clausing,January,23,4054447788
William Connor,December,13,123456789
Kara Marie,October,23,1593574862
Audrey Carrit,January,16,1684527548
Sebastian Baker,October,23,9184569876
So if I input "December" I want it to display "Stephen Haren,December,9,4055551235" and "William Connor,December,13,123456789" .
I thought about using substrings but I figured there had to be a simpler way.
My Code After Given Answer:
using System;
using System.IO;
class ReadFriendRecords
{
public static void Main()
{
//the path of the file
FileStream inFile = new FileStream(#"H:\C#\Chapter.14\FriendInfo.txt", FileMode.Open, FileAccess.Read);
StreamReader reader = new StreamReader(inFile);
string record;
string input;
Console.Write("Enter Friend's Birth Month >> ");
input = Console.ReadLine();
try
{
//the program reads the record and displays it on the screen
record = reader.ReadLine();
while (record != null)
{
if (record.Contains(input))
{
Console.WriteLine(record);
}
record = reader.ReadLine();
}
}
finally
{
//after the record is done being read, the progam closes
reader.Close();
inFile.Close();
}
Console.ReadLine();
}
}
Iterate through all the lines (StreamReader, File.ReadAllLines, etc.) and check if
line.Contains("December") (replace "December" with the user input).
Edit:
I would go with the StreamReader in case you have large files. And use the IndexOf-Example from #Matias Cicero instead of contains for case insensitive.
Console.Write("Keyword: ");
var keyword = Console.ReadLine() ?? "";
using (var sr = new StreamReader("")) {
while (!sr.EndOfStream) {
var line = sr.ReadLine();
if (String.IsNullOrEmpty(line)) continue;
if (line.IndexOf(keyword, StringComparison.CurrentCultureIgnoreCase) >= 0) {
Console.WriteLine(line);
}
}
}
As mantioned by #Rinecamo, try this code:
string toSearch = Console.ReadLine().Trim();
In this codeline, you'll be able to read user input and store it in a line, then iterate for each line:
foreach (string line in System.IO.File.ReadAllLines(FILEPATH))
{
if(line.Contains(toSearch))
Console.WriteLine(line);
}
Replace FILEPATH with the absolute or relative path, e.g. ".\file2Read.txt".
How about something like this:
//We read all the lines from the file
IEnumerable<string> lines = File.ReadAllLines("your_file.txt");
//We read the input from the user
Console.Write("Enter the word to search: ");
string input = Console.ReadLine().Trim();
//We identify the matches. If the input is empty, then we return no matches at all
IEnumerable<string> matches = !String.IsNullOrEmpty(input)
? lines.Where(line => line.IndexOf(input, StringComparison.OrdinalIgnoreCase) >= 0)
: Enumerable.Empty<string>();
//If there are matches, we output them. If there are not, we show an informative message
Console.WriteLine(matches.Any()
? String.Format("Matches:\n> {0}", String.Join("\n> ", matches))
: "There were no matches");
This approach is simple and easy to read, it uses LINQ and String.IndexOf instead of String.Contains so we can do a case insensitive search.
For finding text in a file you can use this algorithim use this code in
static void Main(string[] args)
{
}
try this one
StreamReader oReader;
if (File.Exists(#"C:\TextFile.txt"))
{
Console.WriteLine("Enter a word to search");
string cSearforSomething = Console.ReadLine().Trim();
oReader = new StreamReader(#"C:\TextFile.txt");
string cColl = oReader.ReadToEnd();
string cCriteria = #"\b"+cSearforSomething+#"\b";
System.Text.RegularExpressions.Regex oRegex = new
System.Text.RegularExpressions.Regex(cCriteria,RegexOptions.IgnoreCase);
int count = oRegex.Matches(cColl).Count;
Console.WriteLine(count.ToString());
}
Console.ReadLine();

Create a stream reader in c# console to read only one student at a time instead of all of them using a .txt file

class Program
{
static string strFile = "Student Database.txt";
static void Main(string[] args)
{
string strInput = null; // user input string
start:
System.IO.DirectoryInfo dir = new DirectoryInfo("student_results.txt");
// Request user input as to actions to be carried out
Console.WriteLine("\nWhat do you want to do?\n" +
" 1.View Student(s)\n 2.Add a New Student\n 3.Exit program");
// Save user input to make decision on program operation
strInput = Console.ReadLine();
// Switch statement checking the saved user input to decide the action
// to be carried out
switch (strInput)
{
case "1": // choice for view file
Console.Clear();
string file = AppDomain.CurrentDomain.BaseDirectory +
#"student_results.txt";
StreamReader sr = new StreamReader(file);
string wholeFile = sr.ReadToEnd();
Console.Write(wholeFile + "");
sr.Close();
goto start;
...
}
...
}
...
}
I want this part of my code to just read the students indivially and relay them back to me, instead of how it is doing so at the moment were it just calls all of them back to me when I press '1) view Student' it pretty much says "please enter the students name or ID number of which student you would like to view".
I've currently have got the ID number running off a random number generator.
Thank you for your time guys.
Welcome to SO, first of all goto is not a good choice in C# in 99% of cases, and you'd better use loops. For your code I would save each student in a single line and at the time of reading students I would read them line by line untill I found the student.
class Program
{
static string strFile = "Student Database.txt";
static void Main(string[] args)
{
string strInput = ""; // user input string
while (strInput != "3")
{
System.IO.DirectoryInfo dir = new System.IO.DirectoryInfo("student_results.txt");
Console.WriteLine("\nWhat do you want to do?\n 1.View Student(s)\n 2.Add a New Student\n 3.Exit program"); // request user input as to actions to be carried out
strInput = Console.ReadLine(); //save user input to make decision on program operation
switch (strInput)
{
case "1":
Console.Clear();
Console.WriteLine("Enter Student ID: \n");
string file = AppDomain.CurrentDomain.BaseDirectory + #"student_results.txt";
StreamReader sr = new StreamReader(file);
string StudentID = Console.ReadLine();
string line = "";
bool found = false;
while((line = sr.ReadLine()) != null)
{
if (line.Split(',')[0] == StudentID)
{
found = true;
Console.WriteLine(line);
break;
}
}
sr.Close();
if (!found)
{
Console.WriteLine("Not Found");
}
Console.WriteLine("Press a key to continue...");
Console.ReadLine();
break;
case "2":
Console.WriteLine("Enter Student ID : ");
string SID = Console.ReadLine();
Console.WriteLine("Enter Student Name : ");
string SName = Console.ReadLine();
Console.WriteLine("Enter Student Average : ");
string average = Console.ReadLine();
string wLine = SID + "," +SName+":"+average;
file = AppDomain.CurrentDomain.BaseDirectory + #"student_results.txt";
StreamWriter sw = File.Exists(file) ? File.AppendText(file) : new StreamWriter(file);
sw.WriteLine(wLine);
sw.Close();
Console.WriteLine("Student saved on file, press a key to continue ...");
Console.ReadLine();
Console.Clear();
break;
case "3":
return;
default:
Console.Clear();
Console.WriteLine("Invalid Command!\n");
break;
}
}
}
}
this code might not be complete, I wanted to give you the idea, I hope it helps.
Presuming you are not dealing with a huge file of students, and on the basis that you want to make multiple queries, i would not read the text file line by line each time.
Instead create a student class, read the file once on init, and create a list< student > from the data. Then you can query it with LinQ
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
namespace ReadStudents
{
class Program
{
static string _filename = "students.txt";
static void Main(string[] args)
{
List<Student> students = new List<Student>();
// Load students.
StreamReader reader = new StreamReader(_filename);
while (!reader.EndOfStream)
students.Add( new Student( reader.ReadLine()));
reader.Close();
string action;
bool showAgain = true;
do
{
Console.WriteLine("");
Console.WriteLine("1. See all students.");
Console.WriteLine("2. See student by ID.");
Console.WriteLine("3. Add new student.");
Console.WriteLine("0. Exit.");
Console.WriteLine("");
action = Console.ReadLine();
switch (action)
{
case "1":
foreach (Student item in students)
item.Show();
break;
case "2":
Console.Write("ID = ");
int id = int.Parse( Console.ReadLine() ); // TODO: is valid int?
foreach (Student item in students)
if (item.Id == id)
item.Show();
break;
case "3":
Console.WriteLine("ID-Name");
Student newStudent = new Student(Console.ReadLine());
students.Add(newStudent);
StreamWriter writer = new StreamWriter(_filename, true);
writer.WriteLine(newStudent);
writer.Close();
break;
case "0":
Console.WriteLine("Bye!");
showAgain = false;
break;
default:
Console.WriteLine("Wrong action!");
break;
}
}
while (showAgain);
}
}
class Student
{
public int Id;
public string Name;
public Student(string line)
{
string[] fields = line.Split('-');
Id = int.Parse(fields[0]);
Name = fields[1];
}
public void Show()
{
Console.WriteLine(Id + ". " + Name);
}
}
}
I assume your data are in "ID-Name" format for example:
1-Alexander
2-Brian
3-Christian
I load file line-by-line and pass to Student class which converts in constructor text data to more friendly form. Next, application shows interface until user write "0".

Categories

Resources