Avoid writing of equal existing line to text document - c#

I’m new with C# need your help
In this code, I write a some word or phrase to text document with cycle loop. My question is how to avoid writing of equal line, which is already exist in text document and find it in text document, show on output?
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace program_1
{
class Program
{
static void Main(string[] args)
{
int i = 0;
for (;;)
{
Console.Write("Write phrase: ");
var row = Console.ReadLine();
Console.WriteLine(i++ + ". " + (row));
TextWriter tsw = new StreamWriter("lines.txt", true);
tsw.WriteLine(row);
tsw.Close();
}
Console.Read();
}
}
}

If you want to avoid writing duplicate lines in your file, you need a different approach. First, you need to have all of your lines in memory, then check if the user inputs a line already in memory, then write everything at the end of the program
class Program
{
static void Main(string[] args)
{
int i = 0;
List<string> wordsTyped = new List<string>();
// If the file already exists then you can load its content
// in memory to start your checks against the current content
// of the file....
if(File.Exists("lines.txt"))
wordsTyped.AddRange(File.ReadAllLines("lines.txt"));
for (;;)
{
Console.Write("Write phrase: (type 'exit' to end)");
string row = Console.ReadLine();
// Provide a way to exit from this infinite loop
if(row == "exit")
break;
Console.WriteLine(i++ + ". " + (row));
// Use IndexOf to find if there is a match for your row
// and in which position in the List<string>
int position = wordsTyped.IndexOf(row);
if (position != -1)
Console.WriteLine($"Already inserted. Found match at line {position+1} , type again");
else
{
wordsTyped.Add(row);
// It of uttermost importance to enclose the StreamWriter
// in a using statement to be sure to close and dispose it
// after the write, otherwise you could lock yourself out
using(StreamWriter sw = File.AppendText("lines.txt"))
sw.WriteLine(row);
}
}
// File.WriteAllLines("lines.txt", wordsTyped.ToArray());
Console.Read();
}
}

Related

Program that writes numbers until I write a string to stop it

I am required to write a program that prints out numbers until I write in the console window a simple string "stop". The numbers are supposed to go on infinitely until the condition is met.
I tried:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApp3
{
internal class Program
{
static void Main(string[] args)
{
for (int i = 0; i < 1000000000;)
{
Console.WriteLine(i);
string a = Console.ReadLine();
if (a == "stop")
{
break;
}
i++;
}
}
}
}
But, there is a delay waiting for my input every time, it's not constant.
You are asking for a non blocking console read. THats not simple.
One way is to peek to see if a key is available to read
int number = 0;
while (true)
{
Console.WriteLine(number);
number++;
if (Console.KeyAvailable)
{
var s = Console.ReadLine();
if (s == "stop")
break;
}
}

Reading in integers from text files and storing them in lists

I have a small text file, containing a few integers on separate lines.
I wrote the following program (just a function called ReadFromFile) in order to read in the integers and assign them to some variables.
I wonder if I could improve it, and how? I tried reading in integers, but realized I would get errors with StreamReader, so I carried on using strings.
Is there anyway I could improve this program?
All it does is read in the following numbers, assign the first two to two variables, and put the rest in a list.
3
4
8
8
8
8
8
8
So, I will have: var1 = 3 , var2 = 4 , myList = [8,8,8,8,8,8]
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
namespace Practice
{
class Program
{
static void Main(string[] args)
{
// Read the specifications from the file.
ReadFromFile();
// Prevent the console window from closing.
Console.ReadLine();
}
/// The function that reads the input specifications from a file.
public static void ReadFromFile()
{
string localPath = #"C:\Desktop\input.txt";
StreamReader sr = new StreamReader(localPath);
// Read all the lines from the file into a list,
// where each list element is one line.
// Each line in the file.
string line = null;
// All lines of the file.
List<string> lines = new List<string>();
while ( ( line = sr.ReadLine() ) != null )
{
lines.Add(line);
Console.WriteLine(line);
}
// Display the extracted parameters.
Console.WriteLine( lines[0] + " var1");
Console.WriteLine( lines[1] + " var2");
// Put the rest in a separate list.
List<int> myList = new List<int>();
for (int i = 2; i < lines.Count; i++)
{
Console.WriteLine("item {0} = {1}", i-1, lines[i] );
myList.Add( Int32.Parse( lines[i] ) );
}
sr.Close();
}
}
}
var vals = File.ReadAllLines(path).Select(int.Parse).ToList();
You might need a Skip(...) if you have header lines; for example to match your for(int i = 2; ...):
var vals = File.ReadAllLines(path).Skip(2).Select(int.Parse).ToList();
You could write it as follow :
public static void ReadFromFile(string localPath) // paremetrizing the path for more flexibility
{
StreamReader sr = new StreamReader(localPath);
// extrating the lines from the file
List<int> lines = Regex.Split(sr.ReadToEnd(), "\r\n").Select(int.Parse).ToList();
// we can close the reader as we don't need it anymore
sr.Close();
Console.WriteLine( lines[0] + " var1");
Console.WriteLine( lines[1] + " var2");
// removing the first 2 elements
lines = lines.Skip(2).ToList();
for (int i = 0; i < lines.Count; i++)
{
Console.WriteLine("item {0} = {1}", i-1, lines[i] );
}
}

String Array to text document and read it

I'm having issues with with making a program.
I need to make it so it checks whether a text file exists or not, if it exists it displays the contents, if not it prompts the user to enter 5 names, these names are stored into an array are then sent to the text document. I've already tried to do it but I'm getting an error.
Note:
I need to do the names in an array.
Code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Threading;
using System.Text.RegularExpressions;
namespace Array
{
class Program
{
public static string line;
public const string file = #"D:\information.txt";
public static string names = #"D:\names.txt";
public static StreamReader myFile = new StreamReader(names);
public static string[] namesArray = new string[4];
public static bool checkFileExists(string names)
{
bool b = false;
if (File.Exists(names))
{
b = true;
}
return b;
}
static void reset() //void used to reset the program
{
Console.ForegroundColor = ConsoleColor.Red;
Console.Write("\nIf there is an error, press Enter to restart");
Console.ForegroundColor = ConsoleColor.White; //changes the text colour of the next line of code to white, better visuals
Console.ReadLine(); //the readkey used to read for any keys being pressed for restarting
Console.Clear(); //clears the console and resets it back to normal
}
static void toFile()
{
Console.ForegroundColor = ConsoleColor.White;
string[] namesArray = new string[5];
Random RandString = new Random();
StreamWriter info = new StreamWriter(file);
for (int x = 0; x < namesArray.Length; x++)
{
Console.Write("Enter a name of class member: {0}", namesArray[x]);
namesArray[x] = Console.ReadLine();
}
for (int x = 0; x < namesArray.Length; x++)
{
info.WriteLine("{0}", namesArray[x]);
}
info.Close();
}
static void Main(string[] args)
{
Console.Title = "Class names to array";
try
{
if (checkFileExists(names))
{
Console.WriteLine("file exists, the contents of the file is: ");
while (myFile1.EndOfStream == false)
{
line = myFile1.ReadLine();
Console.WriteLine(line);
}
Console.ReadLine();
}
else
{
toFile();
}
}
catch (Exception e)
{
Console.WriteLine("Exception: " + e.Message);
}
}
}
The error I'm getting is 'The type initializer for 'Array.Program' threw an exception' and it just closes down.
I've also been told by a friend that my code is really messy, I'm not sure what I need to do to make it better but any help is appreciated.
As #cdhowie said, you will find the details in InnerException. I did notice that your code was a little bit strung out, and admittedly messy, so I decided to write a little sample that does what you want it to in way fewer lines. Many times when doing simple file operations, you can avoid using StreamReader or StreamWriter and instead just use the File class.
Here is the code sample:
using System;
using System.IO;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
string file = #"D:\information.txt";
if (File.Exists(file))
foreach(var s in File.ReadAllLines(file))
Console.WriteLine(s);
else
{
string[] src = new string[5];
Console.WriteLine("Please enter 5 names:");
for (int i = 0; i < 5; i++)
src[i] = Console.ReadLine();
File.Create(file).Close();
File.WriteAllLines(file, src)
}
}
}
}
Check the details of the "inner exception" in a debugger. You should see that the problem is this line:
public static StreamReader myFile = new StreamReader(names);
This is the only line that could be causing this problem, and likely occurs because the filename contained by the names field doesn't exist, or you don't have access to it (permissions or sharing violation, for example). Correct the problem indicated by the inner exception to make the exception stop happening.
Note that if you did this assignment in the Main() method that the real error would not be masked by the TypeInitializationException, which is thrown whenever a static constructor throws an exception.

Importing files with streamReader.ReadBlock (buffer)

Needed to import a large number of text files and find some research material, particularly for my problem, I decided to post the solution here. I believe it will help someone else.
My files are registries of 3,000,000 up. Tried to read line by line, with StreamReader.ReadLine(), but it was impractical. Moreover, the files are too large to loads them in memory.
The solution was to load files in memory in blocks (buffers) using the streamReader.ReadBlock().
The difficulty I had was that the ReadBlock() reads byte-by-byte, occurring in a row or get another half. Then the next buffer the first line was incomplete. To correct, I load a string (resto) and concatenate with the 1st line (primeiraLinha) of the next buffer.
Another important detail in using the Split, in most examples the 1st verification of variables are followed Trim() to eliminate spaces. In this case I do not use because it joined the 1st and 2nd line buffer.
using System;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApplication2
{
class Program
{
static void Main()
{
const string arquivo = "Arquivo1.txt";
using (var streamReader = new StreamReader(arquivo))
{
int deslocamento = 1000;
int pStart = 0; // buffer starting position
int pEnd = deslocamento; // buffer end position
string resto = "";
for (int i = pStart; i < int.MaxValue; i += pStart)
{
string primeiraLinha;
char[] buffer = new char[pEnd-pStart];
streamReader.ReadBlock(buffer, 0, buffer.Length);
var bufferString = new String(buffer);
string[] bufferSplit = null;
bufferSplit = bufferString.Split(new char[] { '\n' });
foreach (var bs in bufferSplit )
{
if (bs != "")
{
if (resto != "")
{
primeiraLinha = resto + bs;
Console.WriteLine(primeiraLinha);
resto = "";
}
else
{
if (bs.Contains('\r'))
{
Console.WriteLine(bs);
}
else
{
resto = bs;
}
}
}
}
Console.ReadLine();
// Moves pointers
pStart = pEnd;
pEnd += deslocamento;
if (bufferString == null)
break;
}
}
}
}
}
I had a great help from my friend training, Gabriel Gustaf, the resolution of this problem.
If anyone has any suggestions to further improve the performance, or to make any comments, feel free.
C# have a designed class to work with large files: MemoryMappedFile. It's simple and I think could help you.

C# first element of string is missing

I wrote a program, what is compute the difference of two string or compute a hamming distance.
I run in debug mode. And I saw, the at the string first the first element of string is missing. But the string second is good!
When I tested the first's length and second's length is equal.
Forexample:
I typed this: 00011
And in debug mode it's value only: 0011
. Or I typed this: "this", in debug the real value is only "his"
Somebody can explain me, why missing the first element of string?
The code:
while (Console.Read() != 'X')
{
string first = Console.ReadLine();
string second = Console.ReadLine();
int distance = 0;
for (int i = 0; i < first.Length; i++)
{
if (first[i]!= second[i])
{
++distance;
}
}
Console.WriteLine("Hamming distance is {0}.", distance);
}
I tried modify the iteration, forexample the loop was ++i, or the first[i-1] but these aren't solve my problem.
Console.Read() reads the first character from the buffer. This character will not be included in the ReadLine().
I would personally find a better way to end your program such as if first=="quit" or by some other syntaxic means.
You consume the first char with Console.Read() so it will not appear in first:
string first = Console.ReadLine();
while ((first != null) && (first[0] != 'X'))
{
string second = Console.ReadLine();
int distance = 0;
for (int i = 0; i < first.Length; i++)
{
if (first[i]!= second[i])
{
++distance;
}
}
Console.WriteLine("Hamming distance is {0}.", distance);
first = Console.ReadLine();
}
I have the same problem in vb.net and found out that it was causing by "console.readkey()". console should only read one at time.See you have multiple read function at same time.
like Readkey() at main() and readline() on Background.thread...
using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
namespace_File_Handling
{
class Program
{
static void Main(string[] args)
{
string path = #"E:\File.txt";
StreamReader r1 = new StreamReader(path);
string m = r1.ReadToEnd();
Console.WriteLine(m);
Console.ReadKey();
r1.Close();
StreamWriter wr = File.AppendText(path);
string na = Convert.ToString(Console.ReadLine());
wr.WriteLine(na);
wr.Close();
Console.WriteLine(na);
Console.ReadKey();
StreamReader rd = new StreamReader(path);
string val = rd.ReadToEnd();
Console.WriteLine(val);
rd.Close();
Console.ReadKey();
}
}
}

Categories