Ordering writeline outputs from text file using C# in console - c#

I wonder if you could help me at all. Essentially my program has to scan through a text file and then print the lines. Each line that is printed must be alphabetized also, if possible. I could do with being able to point at any file through cmd rather than automatically pointing it at a specific file and in a specific location.
I have this so far as I wanted to get things working in a basic form.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
namespace Program
{
class Program
{
static void Main(string[] args)
{
String line;
try
{
//We Have to pass the file path and packages.txt filename to the StreamReader constructor
StreamReader sr = new StreamReader("D:\\Users\\James\\Desktop\\packages.txt");
//Instruction to read the first line of text
line = sr.ReadLine();
//Further Instruction is to to read until you reach end of file
while (line != null)
{
//Instruction to write the line to console window
Console.WriteLine(line);
//The read the next line
line = sr.ReadLine();
}
//Finally close the file
sr.Close();
Console.ReadLine();
}
catch (Exception e)
{
Console.WriteLine("Exception: " + e.Message);
}
finally
{
Console.WriteLine("Executing finally block.");
}
}
}
}
I hope you guys can help me, I am very rusty!
My thoughts were to convert the string into an char array? then modify and sort using array.sort method.
OK guys. On your advice I have made a few changes. I get an exception thrown at me now as we are trying to get it to accept an argument in order for us to point it at any text file, not a specific one.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
namespace Program
{
class Program
{
static void Main (params string[] args)
{
string PathToFile = args[1];
string TargetPackages = args[2];
try
{
string[] textLines = File.ReadAllLines(PathToFile);
List<string> results = new List<string>();
foreach (string line in textLines)
{
if (line.Contains(TargetPackages))
{
results.Add(line);
}
Console.WriteLine(results);
}
}
catch (Exception e)
{
Console.WriteLine("Exception: " + e.Message);
}
finally
{
Console.WriteLine("Executing finally block.");
}
}
}
}

If you just want to sort by the first word and output, you need to read all the lines into memory (I hope your file isn't too large), sort the lines, and then write them back out.
There are many ways to do all that. The File class has some helper functions that make reading and writing text files line-by-line very simple, and LINQ's OrderBy method makes quick work of sorting things.
File.WriteAllLines(
outputFileName,
File.ReadLines(inputFileName).OrderBy(line => line));
See File.WriteAllLines and File.ReadLines for information on how they work.
If you want to load each line, sort the first word, and then re-output the line:
File.WriteAllLines(
outputFileName,
File.ReadLines(inputFileName)
.Select(line =>
{
var splits = line.Split(new [] {' '}};
var firstWord = new string(splits[0].OrderBy(c => c));
var newLine = firstWord + line.Substring(firstWord.Length);
return newLine;
}));
Note that this loads and processes one line at a time, so you don't have to hold the entire file in memory.

You should be better off by reading all lines at once and then looking at each line separately, like this:
List<string> allLines = System.IO.File.ReadLines(pathToFile).ToList();
allLines = allLines.OrderBy(line => line).ToList(); //this orders alphabetically all your lines
foreach (string line in allLines)
{
Console.WriteLine(line);
}
This will print all the lines in the file ordered alphabetically.
You can also parametrize the path by using the args parameter you receive when opening the application:
CMD> pathToYourExe.exe path1 path2 path3
You can mock this by using the DEBUG arguments in the project's Debug menu

Related

C# Use comment when compiling and running code from path at runtime

Recently I try to compile and run C# code stored somewhere else. My goal is to import a .txt file, compile it and run it. I followed this article on Simeon's blog about compiling and running C# code within the program, and everything work well.
Then I try making something a bit more complex by importing the C# code from my computer, so I created a .txt file with the following lines that is store for instance at "C:\program.txt" :
(the text file)
using System;
namespace Test
{
public class DynaCore
{
static public int Main(string str)
{
Console.WriteLine("Cool it work !");
return str.Length;
}
}
}
I do some coding based on the same article and that is my code :
(the C# program)
using System;
using System.Collections.Generic;
using System.Text;
using System.CodeDom.Compiler;
using System.IO;
using Microsoft.CSharp;
using System.Reflection;
namespace DynaCode
{
class Program
{
static void Main(string[] args)
{
string[] lines = System.IO.File.ReadAllLines(#"C:\program.txt");
string bigLine = string.Empty;
foreach(string s in lines)
{
bigLine += s;
}
string[] finalLine = new string[1] { bigLine };
CompileAndRun(finalLine);
Console.ReadKey();
}
static void CompileAndRun(string[] code)
{
CompilerParameters CompilerParams = new CompilerParameters();
string outputDirectory = Directory.GetCurrentDirectory();
CompilerParams.GenerateInMemory = true;
CompilerParams.TreatWarningsAsErrors = false;
CompilerParams.GenerateExecutable = false;
CompilerParams.CompilerOptions = "/optimize";
string[] references = { "System.dll" };
CompilerParams.ReferencedAssemblies.AddRange(references);
CSharpCodeProvider provider = new CSharpCodeProvider();
CompilerResults compile = provider.CompileAssemblyFromSource(CompilerParams, code);
if (compile.Errors.HasErrors)
{
string text = "Compile error: ";
foreach (CompilerError ce in compile.Errors)
{
text += "rn" + ce.ToString();
}
throw new Exception(text);
}
Module module = compile.CompiledAssembly.GetModules()[0];
Type mt = null;
MethodInfo methInfo = null;
if (module != null)
{
mt = module.GetType("Test.DynaCore");
}
if (mt != null)
{
methInfo = mt.GetMethod("Main");
}
if (methInfo != null)
{
Console.WriteLine(methInfo.Invoke(null, new object[] { "here in dyna code. Yes it work !!" }));
}
}
}
}
This work well, and I got the following output as expected :
Cool it work !
33
Note that I put all the code of the .txt file in one big line that I do myseft, because as Simeon said :
CompileAssemblyFromSource consumes is a single string for each block (file) worth of C# code, not for each line.
Even now this sentence still a bit obscure for me.
( I tried CompileAndRun(new string[1] { lines.ToString() }); before but there was an error when compiling the .txt file, that's why I do the big line myself. )
And here is my problem : I ask myself : "What if I add a comment in my .txt file ?", so I edit it and that how it look : (the text file)
using System;
namespace Test
{
//This is a super simple test
public class DynaCore
{
static public int Main(string str)
{
Console.WriteLine("Cool it work !");
return str.Length;
}
}
}
And of course I got an error (CS1513) because I convert the .txt file in one big string, so everything after the // is ignored. So how can I use comment using // inside my .txt file and got the program work ?
I also try CompileAndRun(lines);, but after launching the program it crash when compiling the .txt file because of the exception.
I do some search about it and I didn't find anythings about comment. I guess there is somethings wrong about passing only one big line in the CompileAndRun method, but passing several lines don't work as I say upper.
(Another note : Comment using /* insert comment */ works.)
Each element given to CompileAssemblyFromSource is supposed to be a file, not a single line of code. So read the whole file into a single string and give it to the method and it'll work just fine.
static void Main(string[] args)
{
var code = System.IO.File.ReadAllText(#"C:\program.txt");
CompileAndRun(code);
Console.ReadKey();
}
static void CompileAndRun(string code)
{
CompilerParameters CompilerParams = new CompilerParameters();
string outputDirectory = Directory.GetCurrentDirectory();
CompilerParams.GenerateInMemory = true;
CompilerParams.TreatWarningsAsErrors = false;
CompilerParams.GenerateExecutable = false;
CompilerParams.CompilerOptions = "/optimize";
string[] references = { "System.dll" };
CompilerParams.ReferencedAssemblies.AddRange(references);
CSharpCodeProvider provider = new CSharpCodeProvider();
CompilerResults compile = provider.CompileAssemblyFromSource(CompilerParams, code);
// ...
}

Deleting an specified string by user in an array?

What i want to do here was getting an string input from the user and if that string input is in the array i want to delete it from the file (all the items in the array is actual files in my computer that got scanned at the start of the program and become one array) is there a way to do that without foreach?
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Diagnostics;
using System.IO;
using System.Threading;
string typed = null;
string loc = AppDomain.CurrentDomain.BaseDirectory;
if (!Directory.Exists(loc + #"\shortcuts"))
{
Directory.CreateDirectory(loc + #"\shortcuts");
}
string[] directory = Directory.GetFiles(loc + #"\shortcuts");
foreach (var filed in directory)
{
File.Move(filed, filed.ToLowerInvariant());
}
string[] file = Directory.GetFiles(loc + #"\shortcuts").Select(System.IO.Path.GetFileNameWithoutExtension).ToArray();
foreach (string dir in directory)
{
}
if (typed == "exit") System.Environment.Exit(0);
//other ifs here
else if (typed == "rem")
{
//Console.WriteLine("\nNot available at the moment\n");
////add this command
Console.WriteLine("\nWhich program entry do you wish to erase?\n");
typed = Console.ReadLine().ToLower();
if (file.Any(typed.Contains))
{
File.Delete(file.Contains(typed)); //this is the broken part and i don't know how i can get the stings from there
Console.WriteLine("hi");
}
else Console.WriteLine("\n" + typed + " is not in your registered programs list.\n");
}
Expected result was getting rid of the typed program in the folder and actual results was just an error code.
You are storing only the file name in the array, not its complete path or extension. You need to change this, and allow it to store FileName with extension.
string[] file = Directory.GetFiles(loc + #"\shortcuts").Select(System.IO.Path.GetFileName).ToArray();
and then, you need to change the If condition as follows.
if (file.Contains(typed))
{
File.Delete(Path.Combine(loc + #"\shortcuts",typed));
Console.WriteLine("hi");
}
In this Scenario, user would need to input the file name with extension.
If you want the User to input only the filename(without extension, as in your code), then, you could run into a situation where there could be two files with different extension.
"test.jpg"
"test.bmp"
Update
Based on your comment that you cannot store extensions, please find the updated code below. In this scenario, you do not need to change the array. Since you are only storing lnk files, you can append the extension to the file name to complete the path during Path.Combine.
if (file.Contains(typed))
{
File.Delete(Path.Combine(loc , #"shortcuts",$"{typed}.lnk"));
Console.WriteLine("hi");
}

Display csv read data in console application in c#

I am completely new to programming and trying to get the complete row data from csv file based on column value in c#. Example data is as follows:
Mat_No;Device;Mat_Des;Dispo_lvl;Plnt;MS;IPDS;TM;Scope;Dev_Cat
1111;BLB A601;BLB A601;T2;PW01;10;;OP_ELE;LED;
2222;ALP A0001;ALP A0001;T2;PW01;10;;OP_ELE;LED;
If user enters a Mat_No he gets the full row data of that particular number.
I have two files program.cs and filling.cs
overViewArea.cs contain following code for csv file reading:I dont know how to access the read values from program.cs file and display in console
`using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
using System.Data;
namespace TSDB
{
class fillData
{
public static fillData readCsv()
{
fillData getData= new fillData ();
using (var reader = new StreamReader(#"myfile.csv"))
{
List<string> headerList = null;
while (!reader.EndOfStream)
{
var line = reader.ReadLine();
if(headerList==null)
{
headerList = line.Split(';').ToList();
}
else
{
var values = line.Split(';');
for(int i = 0; i< headerList.Count; i++)
{
Console.Write(headerList[i] + "=" + values[i]+";");
}
Console.WriteLine();
}
}
}
return fillData;
}
}
}`
Program.cs has following code
class Program
{
static void Main(string[] args)
{
fillData data= fillData.readCsv();
Console.ReadLine();
}
}
First, please, do not reinvent the wheel: there are many CSV readers available: just use one of them. If you have to use your own routine (say, for a student project), I suggest extracting method. Try using File class instead of Stream/StreamReader:
// Simple: quotation has not been implemented
// Disclamer: demo only, do not use your own CSV readers
public static IEnumerable<string[]> ReadCsvSimple(string file, char delimiter) {
return File
.ReadLines(file)
.Where(line => !string.IsNullOrEmpty(line)) // skip empty lines if any
.Select(line => line.Split(delimiter));
}
Having this routine implemented, you can use Linq to query the data, e.g.
If user enters a Mat_No he gets the full row data of that particular
number.
Console.WriteLine("Mat No, please?");
string Mat_No_To_Filter = Console.ReadLine();
var result = ReadCsvSimple(#"myfile.csv", ';')
.Skip(1)
.Where(record => record[0] == Mat_No_To_Filter);
foreach (var items in result)
Console.WriteLine(string.Join(";", items));

How can I print values from a text file in the console?

I've been trying to read some values from a Values.txt file and then print them in the console using C#. Everything appears to work. I've debugged the code and found nothing wrong and the program is compiling. The problem is that the values wont appear on the console. It just prints empty lines.
Here's my code :
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace TestFileReadTest
{
class Program
{
static void Main(string[] args)
{
StreamReader myReader = new StreamReader("Values.txt");
string line = "";
while (line != null)
{
line = myReader.ReadLine();
if (line!= null)
Console.WriteLine();
}
myReader.Close();
Console.WriteLine("Allo");
Console.ReadLine();
}
}
}
I'm using Visual Studio Express 2013
Nowhere do you actually print the values to the console.
You print an empty line here:
Console.WriteLine();
You probably meant to print the line variable:
Console.WriteLine(line);
You forgot to add variable lineto Console.WriteLine():
while (line != null)
{
line = myReader.ReadLine();
if (line!= null)
Console.WriteLine(line);
}

String overflowing when concatting

I'm trying to make a program packer but i always fail because when i concat three strings(one contains prefix of source, one contains executable content, other contains suffix of source) content overflows into suffix. Code:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.CodeDom.Compiler;
using Microsoft.CSharp;
using System.IO;
using System.IO.Compression;
namespace ProgramPacker
{
public partial class Form1 : Form
{
static string prefix = #"using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
namespace ProgramPacker
{
class Program
{
static string inside = #" + "\"";
static string suffix = "\";\n" + #"static void Main(string[] args)
{
string temp = Path.GetRandomFileName() +" + "\"" + #".exe" + "\"" + #";
BinaryWriter sw = new BinaryWriter(new FileStream(temp, FileMode.Create));
sw.Write(inside);
sw.Flush();
sw.Close();
System.Diagnostics.Process.Start(temp);
}
}
}";
public string code = "";
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
openFileDialog1.ShowDialog();
BinaryReader br = new BinaryReader(new FileStream(openFileDialog1.FileName, FileMode.Open));
byte[] data = new byte[br.BaseStream.Length];
br.Read(data, 0, (int)br.BaseStream.Length);
br.Close();
string inside = Encoding.UTF7.GetString(data);
code = string.Concat(prefix, string.Concat(inside, suffix));
}
private void button2_Click(object sender, EventArgs e)
{
Console.Write(code);
CSharpCodeProvider cs = new CSharpCodeProvider();
ICodeCompiler compile = cs.CreateCompiler();
CompilerParameters param = new CompilerParameters();
param.GenerateInMemory = false;
param.ReferencedAssemblies.Add("mscorlib.dll");
param.ReferencedAssemblies.Add("System.dll");
param.ReferencedAssemblies.Add("System.Core.dll");
param.GenerateExecutable = true;
param.OutputAssembly = Environment.CurrentDirectory + "/a.exe";
param.WarningLevel = 4;
CompilerResults comp = compile.CompileAssemblyFromSource(param, code);
foreach (CompilerError error in comp.Errors)
{
MessageBox.Show(error.Line + " " + error.Column + " " + error.ErrorText);
}
MessageBox.Show(comp.PathToAssembly);
MessageBox.Show("Finish!");
}
}
}
It outputs:
using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
namespace ProgramPacker
{
class Program
{
static string inside = #"?ãÎoüoy±ôãøÿ?ÿQÔh¦Rt!?^ÿyóë=G:Fÿ»??¿Ç/}òKÿ?úõßû3õMù?c·?Äûòëoª?À_Û>LÖïá^öÿ·õ©üüòcÊ?ª??÷Ô?î:^ȯÏäG¶?ù ?ñË?oñëy:ôã7??ò#ÚyN?w¿=?ëÆ÷ëÛßTëºÓ»yßüø]áå{ö/àïªêL©Oÿ;ú5rù% ä¸?1)Ï?¥?y®ÿ]0QL8û×ÖGòów±?øÿèü[?ª~éá¿ÿó£üüJ~ܹ
Êw¡h??/?úçeñÈ_?¿?ü½L^ywü7?,ùÅû¿ß£ó÷w?É~Ç????ê?ÿQÌyç¿??¹Cö×vZ__>?? ûïx?_ü"õ!ì; ;ùõåÇ?ú3*­¿ #ÿV?èÿ¿Ë??/½P¶y?â¡??ùñÿÑæä/A¶_ò?v??ÿ?ÿQtÄx÷w?O'N?u$ÿk÷U«yÆò?£.Y?ùw(?ßÔ6ÿ]2ÿeUÆò¿?ضö·ßO~ü#*y£Jæ·Ä w yóYëï´
õ}y¡ä¨ù÷YPdú?Z©Óé¼R?æg?ÀSyà쬽Éÿ­ûÁ?ym>ut?ÿA??>?¿[ôçF ê´)9ß9xÿ£¿?
åùïyí ÁTlù
-ùñ?Òÿ·!·
E?£üO5÷]çºy?7Áè¿?Zô?(å§
#ü¥úõ®?o«âû]0Èßä7¿à??¿õ?d?ѵ;Jü_K?úAMìT>Àü1mR0sâ¿ê¨õ{äö×ó??¿.úÿõ½Eä?ÔïÿÎÿ±³v'ÿûìw ?»oÃø1±WtB
É¡wì&øuå£Îÿ?Éw?|úWÿ=ö÷_ÿ·?y®YWöwû¿ßß?Öe'û?%?yß/×Àî-yÿ.?8åóù?ûÇÚ6ÿÂßøï?Áàï?{8Zy?¿Å5yø ÇpÏ9=ó»üÑ>Õ?Èÿ?Y¿,?ëÿ?Êçÿì_}E?÷Ûú|î$ò÷ø}Jÿ^Êtò¿?#á|ò{Ø`<ªÿQ?QLæ½õo)¿ü&¿áÂÿ¼ó¿_÷7yMå8)¿Ùo'¿õ±üü=~#LÚ¿ó§¢Ë÷üO?Æ?å÷WJÍ$¾¸øW?A?Òÿ(09Áÿà³_ëÿù3l?SWYµßô÷¤~?ÀG¿ñ
??Às%ÍyÑ;Ò¸!ÿ?_Iÿ¼¼í/Ôrö
?T´ôÑùyǹßE~üV?ñ¿C~VßùuÿG X8|._¼Å_:Æü-?îü:?øì?|W ¤ÃÓW01?$å×?Û#ùIÿû·1:4û½ü._y^òÙNó?º1?ßIÍ?ÿ¿ß_~|ÖùX?#?në_B?¡µ~_×ãÿhãèïØÏßì¡yïôk_y;HÿÛyÿàâ/sÀ??? $ìw0Jüßü«#?ûo?¿îËX
´úÏ?Æ?Y>øçÿFpyÅÿèËöyK¡²Ì`}ù½Ò¿íÿÀñn"?Í?ëOëi»ò¹Î~çÿ?_òüîÿh£ôáêDøÏÿ¶?ç·fy ÄúçÿÖÿ?yÿ?¿?ã0ÿ¿Ë÷åå?ÿQ|ü/ü9¿?÷×Hè×ÉÏ#õ??æ?ÿâ?x?ß?5µ}~Øy¾ß^øè{¿
y{íü;Òÿ¿óú7¤¡î?» yû?ÀÓøiP?ÿÀ_ôK?Gëªíá#??ú%íwS×ñ¿¨#Û¦ÿÿÛªy\]¼÷Z~yR~ü¶ÿ£hû???ÇãÿQVèÿ©?÷{O?Gë¬ ??¡ø\«L` æcëí¿ ½?»?ü?oë¼Ätÿ>ò÷£­_¯ÖiÄ?¯ÿÓ¿÷Ï?(c¦äàéûèó?ü£´çÕè4üy_
r?qÆ¿ø'?KÿÀ_ó×xùkÔ¿FõkÌ~õ¯1y5Ú_ã'??n~âר~å¯ñkü»¿Æø×رÿÿ5~?_ã7ø5~Í_ã?Z4ÔrñkL~ò׸?5Òßûÿ??ñïñnQ¦?yYÕò³vÇ;¥ùrZÍ?åÅg}õæÙöÁGiÓfËYVVËü³®óæ£ßãè7NgM?/&åuJrustInfo>
</assembly>
;
}
}
}
Any help?
EDIT: Why is everyone down-voting? I just asked a question.
Don't use bare UTF7 or UTF8 strings, use Base64 encoding instead.
// given: byte[] data = new byte[...]
string inside = System.Convert.ToBase64String(data);
code = string.Concat(prefix, string.Concat(inside, suffix));
// in your target code
sw.Write(System.Convert.FromBase64String(inside));
You've run into a problem of representation, one that you're not likely to fix with your code as-is.
However, you can choose to follow a similar approach with just minor modifications (which don't actually compress your program much at all).
Remove the # from the definition of the string inside. This is one of the causes of your problems.
You can't just put a BELL character or NUL character in-line in your string, instead write out their unicode escape sequences:
string inside = String.Concat(
data.Select(b => String.Format(#"\u{0:X4}", b)));
Now, in your suffix code, reinterpret your inside string as characters which you cast to bytes:
sw.Write(inside.Select(c => (byte)c).ToArray()); // hardly efficient
I was able to use these modifications and successfully "pack" and execute the following:
C:\temp>type hello.cs
using System;
class M {
static void Main(string[] args) {
System.IO.File.Create("hello.world");
}
}
C:\temp>csc hello.cs
Microsoft (R) Visual C# 2010 Compiler version 4.0.30319.1
Copyright (C) Microsoft Corporation. All rights reserved.
C:\temp>pack.exe hello.exe
3584 bytes
C:\temp>a.exe
C:\temp>dir *.world
Volume in drive C is OSDisk
Volume Serial Number is AABD-D663
Directory of C:\temp
03/22/2012 16:36 0 hello.world
1 File(s) 0 bytes
0 Dir(s) 279,351,762,944 bytes free
Better use CodeCompileUnit to generate C# code from a C# program:
http://msdn.microsoft.com/en-us/library/system.codedom.codecompileunit.aspx
You can also use this to compile the generated ATS into an assembley.
Or parse your template parts from files. That would make the code much more readable.
You can't just express executable binary code as a C# string without escaping it. At least you need to replace any occurrences of the double-quote character ('"') with a sequence of two double-quote characters. I would be very surprised if that's the only problem you encounter, however.
Note that the string might contain control characters that cause the screen to display the string in a garbled way, but that wouldn't necessarily cause the code containing that string to compile improperly. For example, if you have a verbatim string containing a backspace ("stac{backspace}koverflow", say), the character after the backspace would overwrite the character before the backspace, so viewing the string on the screen would give an inaccurate representation of its contents ("stakoverflow"). The compiler would presumably see the full 14-character string including the backspace.

Categories