I am rookie in C#, but I need solve one Problem.
I have several text files in Folder and each text files has this structure:
IdNr 000000100
Name Name
Lastname Lastname
Sex M
.... etc...
Load all files from Folder, this is no Problem ,but i need delete "zero" in IdNr, so delete 000000 and 100 leave there. After this file save. Each files had other IdNr, Therefore, it is harder :(
Yes, it is possible each files manual edit, but when i have 3000 files, this is not good :)
Can C# one algorithm, which could this 000000 delete and leave only number 100?
Thank you All.
Vaclav
So, thank you ALL !
But in the End I have this Code :-) :
using System.IO;
namespace name
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Browse_Click(object sender, EventArgs e)
{
DialogResult dialog = folderBrowserDialog1.ShowDialog();
if (dialog == DialogResult.OK)
TP_zdroj.Text = folderBrowserDialog1.SelectedPath;
}
private void start_Click(object sender, EventArgs e)
{
try
{
foreach (string file in Directory.GetFiles(TP_zdroj.Text, "*.txt"))
{
string text = File.ReadAllText(file, Encoding.Default);
text = System.Text.RegularExpressions.Regex.Replace(text, "IdNr 000*", "IdNr ");
File.WriteAllText(file, text, Encoding.Default);
}
}
catch
{
MessageBox.Show("Warning...!");
return;
}
{
MessageBox.Show("Done");
}
}
}
}
Thank you ALL ! ;)
You can use int.Parse:
int number = int.Parse("000000100");
String withoutzeros = number.ToString();
According to your read/save file issue, do the files contain more than one record, is that the header or does each record is a list of key and value like "IdNr 000000100"? It's difficult to answer without these informations.
Edit: Here's a simple but efficient approach which should work if the format is strict:
var files = Directory.EnumerateFiles(path, "*.txt", SearchOption.TopDirectoryOnly);
foreach (var fPath in files)
{
String[] oldLines = File.ReadAllLines(fPath); // load into memory is faster when the files are not really huge
String key = "IdNr ";
if (oldLines.Length != 0)
{
IList<String> newLines = new List<String>();
foreach (String line in oldLines)
{
String newLine = line;
if (line.Contains(key))
{
int numberRangeStart = line.IndexOf(key) + key.Length;
int numberRangeEnd = line.IndexOf(" ", numberRangeStart);
String numberStr = line.Substring(numberRangeStart, numberRangeEnd - numberRangeStart);
int number = int.Parse(numberStr);
String withoutZeros = number.ToString();
newLine = line.Replace(key + numberStr, key + withoutZeros);
newLines.Add(line);
}
newLines.Add(newLine);
}
File.WriteAllLines(fPath, newLines);
}
}
Use TrimStart
var trimmedText = number.TrimStart('0');
This should do it. It assumes your files have a .txt extension, and it removes all occurrences of "000000" from each file.
foreach (string fileName in Directory.GetFiles("*.txt"))
{
File.WriteAllText(fileName, File.ReadAllText(fileName).Replace("000000", ""));
}
These are the steps you would want to take:
Loop each file
Read file line by line
for each line split on " " and remove leading zeros from 2nd element
write the new line back to a temp file
after all lines processed, delete original file and rename temp file
do next file
(you can avoid the temp file part by reading each file in full into memory, but depending on your file sizes this may not be practical)
You can remove the leading zeros with something like this:
string s = "000000100";
s = s.TrimStart('0');
Simply, read every token from the file and use this method:
var token = "000000100";
var result = token.TrimStart('0');
You can write a function similar to this one:
static IEnumerable<string> ModifiedLines(string file) {
string line;
using(var reader = File.OpenText(file)) {
while((line = reader.ReadLine()) != null) {
string[] tokens = line.Split(new char[] { ' ' });
line = string.Empty;
foreach (var token in tokens)
{
line += token.TrimStart('0') + " ";
}
yield return line;
}
}
}
Usage:
File.WriteAllLines(file, ModifiedLines(file));
Related
Ok so i am making a tool for a special need.
There will be .mif files which i can open as a text file and read the content.
Using something simple like
DialogResult openFile = form.openFileDialog1.ShowDialog();
if (openFile == DialogResult.OK)
{
int size = -1;
try
{
//Add commas here
}
catch (IOException)
{
}
}
Now how do i add a comma at the end of each line in a file?
e.g something like this
319621.99946835 110837.002493295
319640.501385461 110850.59860145
319695.199120806 110879.700271183
to something like this (notice the commas at the end of each line)
319621.99946835 110837.002493295,
319640.501385461 110850.59860145,
319695.199120806 110879.700271183,
Now the pattern is different for this and it occurs 1000s of time in one file
Any ideas?
string sFilePath = "Insert.File.Path.Here";
File.WriteAllLines(sFilePath, File.ReadAllLines(sFilePath).Select(x => string.Format("{0},",x)));
How to read a file line by line you will find in this post.
at each line do simply:
CurrentLine = CurrentLine + ",";
If your text file isn't big, you can try this:
var path = "myfile.txt";
var lines = File.ReadAllLines (path);
var newContent = string.Join (",\r\n", lines);
File.WriteAllText (path, newContent);
It will not add comma to last line.
Use the methods of the File class:
public static string[] ReadAllLines(
string path
)
public static void WriteAllLines(
string path,
string[] contents
)
Like this
string[] lines = File.ReadAllLines(openFile.FileName);
for (int i = 0; i < lines.Length; i++) {
lines[i] += ",";
}
File.WriteAllLines(openFile.FileName, lines);
So I have a generic number check that I am trying to implement:
public static bool isNumberValid(string Number)
{
}
And I want to read the contents of a textfile (only contains numbers) and check each line for the number and verify it is the valid number using isNumberValid. Then I want to output the results to a new textfile, I got this far:
private void button2_Click(object sender, EventArgs e)
{
int size = -1;
DialogResult result = openFileDialog1.ShowDialog(); // Show the dialog.
if (result == DialogResult.OK) // Test result.
{
string file = openFileDialog1.FileName;
try
{
string text = File.ReadAllText(file);
size = text.Length;
using (StringReader reader = new StringReader(text))
{
foreach (int number in text)
{
// check against isNumberValid
// write the results to a new textfile
}
}
}
catch (IOException)
{
}
}
}
Kind of stuck from here if anyone can help?
The textfile contains several numbers in a list:
4564
4565
4455
etc.
The new textfile I want to write would just be the numbers with true or false appended to the end:
4564 true
You don't need to read the entire file into memory all at once. You can write:
using (var writer = new StreamWriter(outputPath))
{
foreach (var line in File.ReadLines(filename)
{
foreach (var num in line.Split(','))
{
writer.Write(num + " ");
writer.WriteLine(IsNumberValid(num));
}
}
}
The primary advantage here is a much smaller memory footprint, as it only loads a small part of the file at a time.
You could try this to keep with the pattern you were initially following...
private void button1_Click(object sender, EventArgs e)
{
DialogResult result = openFileDialog1.ShowDialog(); // Show the dialog.
if (result == DialogResult.OK) // Test result.
{
string file = openFileDialog1.FileName;
try
{
using (var reader = new StreamReader(file))
{
using (var writer = new StreamWriter("results.txt"))
{
string currentNumber;
while ((currentNumber = reader.ReadLine()) != null)
{
if (IsNumberValid(currentNumber))
writer.WriteLine(String.Format("{0} true", currentNumber));
}
}
}
}
catch (IOException)
{
}
}
}
public bool IsNumberValid(string number)
{
//Whatever code you use to check your number
}
You need to replace your loop to look like this:
string[] lines = File.ReadAllLines(file);
foreach (var s in lines)
{
int number = int.Parse(s);
...
}
This would read each line of file, assuming that there is only one number per line,
and lines are separated with CRLF symbols. And parse each number to integer, assuming that integer is not greater than 2,147,483,647 and not less than -2,147,483,648, and integers are stored in your locale settings, with or without group separators.
In case if any line is empty, or contains non-integer - code will throw an exception.
You could try something like this:
FileStream fsIn = new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.Read);
using (StreamReader sr = new StreamReader(fsIn))
{
line = sr.ReadLine();
while (!String.IsNullOrEmpty(line)
{
line = sr.ReadLine();
//call isNumberValid on each line, store results to list
}
}
Then print the list using FileStream.
As other people have mentioned, your isNumberValid method could make use of the Int32.TryParse method, but since you said your text file only contains numbers this may not be necessary. If you're just trying to match the number exactly, you can use number == line.
First, load all lines of the input file in a string array,
then open the output file and loop over the array of strings,
Split each line at the space separator and pass every part to your static method.
The static method use Int32.TryParse to determine if you have a valid integer or not without throwing an exception if the input text is not a valid Int32 number.
Based on the result of the method write to the output file the desidered text.
// Read all lines in memory (Could be optimized, but for this example let's go with a small file)
string[] lines = File.ReadAllLines(file);
// Open the output file
using (StringWriter writer = new StringWriter(outputFile))
{
// Loop on every line loaded from the input file
// Example "1234 ABCD 456 ZZZZ 98989"
foreach (string line in lines)
{
// Split the current line in the wannabe numbers
string[] numParts = line.Split(' ');
// Loop on every part and pass to the validation
foreach(string number in numParts)
{
// Write the result to the output file
if(isNumberValid(number))
writer.WriteLine(number + " True");
else
writer.WriteLine(number + " False");
}
}
}
// Receives a string and test if it is a Int32 number
public static bool isNumberValid(string Number)
{
int result;
return Int32.TryParse(Number, out result);
}
Of course this works only if your definition of 'number' is equal to the allowed values for a Int32 datatype
I have created something that grabs all file names that have the extension .lua with them. This will then list them in a CheckListBox. Everything goes well there but I want to know which one of the CheckListBox's are ticked/checked and then open them in notepad.exe.
To dynamically add the files Code (works perfectly, and adds the files i want)
string appData = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData);
string path = appData + "\\Lua";
string[] fileArray = Directory.GetFiles(path, "*.lua");
for (int i = 0; i < fileArray.Length; i++)
{
string Name = Path.GetFileName(fileArray[i]);
string PathToLua = fileArray[i];
ScriptsBoxBox.Items.AddRange(Name.Split(new string[] { "\r\n" }, StringSplitOptions.RemoveEmptyEntries));
Console.WriteLine(fileArray[i]);
}
Then when i check the items i want to open in notepad i use `
System.Diagnostics.Process.Start("notepad.exe", ScriptsBoxBox.CheckedItems.ToString());
Or
System.Diagnostics.Process.Start("notepad.exe", ScriptsBoxBox.CheckedItems);
Neither works and im pretty sure it's on my end. So my problem is that i cannot open the file that is ticked/checked in checklistbox and want to resolve this problem. However when I do
System.Diagnostics.Process.Start("notepad.exe", PathToLua);
It opens the files with .lua extension ticked or not which makes sense.
I don't think there are any arguments that you can pass to notepad to open a list of specific files. However, you can use a loop to open each file.
foreach (var file in ScriptsBoxBox.CheckedItems)
{
System.Diagnostics.Process.Start("notepad.exe", file);
}
I don't know WinForms as well as WPF but here goes
You need an object that contains your values
public class LuaFile
{
public string FileName { get; set; }
public string FilePath { get; set; }
public LuaFile(string name, string path)
{
FileName = name;
FilePath = path;
}
public override string ToString()
{
return FileName;
}
}
Replace your for loop with
foreach (var file in files)
{
ScriptsBoxBox.Items.Add(new LuaFile(Path.GetFileName(file), file));
}
And to run the checked files
foreach (var file in ScriptsBoxBox.CheckedItems)
{
System.Diagnostics.Process.Start("notepad.exe", ((LuaFile)file).FilePath);
}
Thanks everyone that helped but I solved it on my own (pretty easy when you read :P)
For anyone in the future that wants to do this here is how i accomplished it.
string appData = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData);
string path = appData + "\\Lua";
string[] fileArray = Directory.GetFiles(path, "*.lua");
for (int i = 0; i < fileArray.Length; i++)
{
string Name = Path.GetFileName(fileArray[i]);
string PathToLua = fileArray[i];
//ScriptsBoxBox.Items.AddRange(Name.Split(new string[] { "\r\n" }, StringSplitOptions.RemoveEmptyEntries));
// Console.WriteLine();
Console.WriteLine(ScriptsBoxBox.CheckedItems.Contains(Name));
var pathname = ScriptsBoxBox.CheckedItems.Contains(Name);
if (ScriptsBoxBox.CheckedItems.Contains(Name))
{
System.Diagnostics.Process.Start("notepad.exe", fileArray[ScriptsBoxBox.CheckedItems.IndexOf(Name)]); // I supposed this would get the correct name index, and it did! fileArray by default seems to get the path of the file.
}
I'm new to programming and face some difficulties. I hope to save the data I'm generating (a WPF DataGrid) into a text file.
This is what I currently have:
MainWindow.xaml.cs:
private void SaveButton_Click(object sender, RoutedEventArgs e)
{
string fileName = #"D:\projects\PersonInfos\Files\PersonInfos_Copy.txt";
PersonInfosTable.ConvertToTXTFile(fileName);
}
PersonInfosTable.cs:
public void ConvertToTXTFile(string fileName)
{
StringBuilder sb = new StringBuilder();
System.Text.Encoding Output = null;
Output = System.Text.Encoding.Default;
foreach (PersonInfos personinfos in PersonInfoDetails)
{
if (PersonInfos.SelectCheckBox == true)
{
string line = String.Format("L§" + personinfos.FirstName + "§" + personinfos.LastName + "§");
sb.AppendLine(line);
StreamWriter file = new StreamWriter(fileName);
file.WriteLine(sb);
file.Close();
}
}
}
Unfortunately, this doesn't work. PersonInfosDetails is of type ObservationCollections<T> and SelectCheckBox is the check box selected by the user, and indicates which files the user wants to save.
Any ideas or suggestions? I'd appreciate your help so much and thank you so much for your time!
It is not clear what is the SelectCheckBox property. However, you need to move the writing part of your program outside the loop. Inside the loop just add every person info to your StringBuilder instance.
public void ConvertToTXTFile(string fileName)
{
StringBuilder sb = new StringBuilder();
System.Text.Encoding Output = System.Text.Encoding.Default;
foreach (PersonInfos personinfos in PersonInfoDetails)
{
// Collect every personinfos selected in the stringbuilder
if (personinfos.SelectCheckBox == true)
{
string line = String.Format("L§" + personinfos.FirstName + "§" + personinfos.LastName + "§");
sb.AppendLine(line);
}
}
// Now write the content of the StringBuilder all together to the output file
File.WriteAllText(filename, sb.ToString())
}
Have you tried How to: Write to a Text File (C# Programming Guide)?
Also, the code you've supplied won't work unless SelectCheckBox is a static property of the PersonInfos class. You'll probably have to change the if statement to
if (personInfos.SelectCheckBox == true)
{
// ...
}
What I want to do is actually have my program open up and set a string array so that i can use it for if commands (its used to block people) and I want to store another string in there so that it can be saved and still be used if the program restart. Can someone show me how to do this? Please and thank you :]
You could use the following:
string[] lines = File.ReadAllLines(#"Path here").ToArray();
This splits each line up into the array.
As for saving to file, google "saving to file in c#", you will get plenty of results and tutorials.
This is definitely better then the solution I posted first:
File.WriteAllLines(fileName, yourStringArray);
yourStringArray = File.ReadAllLines(fileName);
File.WriteAllLines
File.ReadAllLines
Below my first answer. Correct, but crap!
Something like this should work for you. Don't blame me for inaccuracy, I am not wide awake yet! ;)
{
string fileName = #"d:\temp\blacklist.txt";
char seperator = ';';
public Form1()
{
InitializeComponent();
string[] users = { "Dave", "John", "Shawn" };
//Save(users);
users = Load();
}
public string[] Load()
{
string line;
using (StreamReader sr = new StreamReader(this.fileName))
{
line = sr.ReadToEnd();
}
return line.Split(seperator);
}
public void Save(string[] users)
{
using (StreamWriter sw = new StreamWriter(this.fileName))
{
string line = string.Empty;
foreach (string user in users)
{
line += string.Format("{0}{1}", user, seperator);
}
sw.WriteLine(line);
sw.Flush();
}
}
}