PROBLEM: weather.txt contains weather information for every day in January 2018. Each line is formated:
"Date;Precipitation;HighTemp;LowTemp"
1/1/2018;0;29;10
Split and tokenize each line and display data for the date picked in Form Labels.
The problem I'm having is how to check the tokenized DateTime data to see if it matches the DateTime picked from the DateTimePicker so that I can display the correct information in the labels.
Labels in form to hold corresponding data: dateLabel, precipLable, highLabel, lowLabel.
namespace WeatherData2
{
struct WeatherData
{
public DateTime date;
public double precip;
public int highTemp;
public int lowTemp;
}
public partial class Form1 : Form
{
private List<WeatherData> weatherList = new List<WeatherData>();
public Form1()
{
InitializeComponent();
}
private void ReadFile()
{
try
{
StreamReader inputFile;
string line;
WeatherData entry = new WeatherData();
char[] delim = { ';' };
inputFile = File.OpenText("weather.txt");
while (!inputFile.EndOfStream)
{
line = inputFile.ReadLine();
string[] tokens = line.Split(delim);
DateTime.TryParse(tokens[0], out entry.date);
double.TryParse(tokens[1], out entry.precip);
int.TryParse(tokens[2], out entry.highTemp);
int.TryParse(tokens[3], out entry.lowTemp);
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
private void dateTimePicker1_ValueChanged(object sender, EventArgs e)
{
}
}
}
If any clarification is need, please let me know. I probably wrote that 10 kinds of confusing. Any help would be greatly appreciated. Thanks.
You can use linq to easily check:
private void dateTimePicker1_ValueChanged(object sender, EventArgs e)
{
var pickedDate = dateTimePicker1.Value.ToShortDateString();
if (weatherList.Any(e => e.date == pickedDate))
{
var matching = weatherList.First(e => e.date == pickedDate);
}
}
you also need to make some changes to your loop. right now you are overwriting your entry object for each iteration of the loop and not adding it to you collection.
while (!inputFile.EndOfStream)
{
//create a new instance of entry for each iteration
entry = new WeatherData();
line = inputFile.ReadLine();
string[] tokens = line.Split(delim);
DateTime.TryParse(tokens[0], out entry.date);
double.TryParse(tokens[1], out entry.precip);
int.TryParse(tokens[2], out entry.highTemp);
int.TryParse(tokens[3], out entry.lowTemp);
//add the item to the list
weatherList.Add(entry);
}
Related
I'm a beginner in C#, trying to work on searching through a text file I'm just testing how it works on a quick and small app, the result should show the searched unique number followed by records of the name and phone number in a list box, for example (001 John 0123456789)
Here is my code:
private void SearchButton_Click(object sender, EventArgs e)
{
string match = "";
try
{
StreamReader inputFile = File.OpenText("Transactions.txt");
List<string> TransList = new List<string>();
{
while (!inputFile.EndOfStream)
{
TransList.Add(inputFile.ReadLine());
}
TransList = TransList.FindAll(x=>x.Equals(match)).ToList();
string[] RecordsArray = TransList.ToArray();
foreach (string record in RecordsArray)
{
if (match == textBox1.Text)
{
DataListBox.Items.Add(RecordsArray[0]);
DataListBox.Items.Add(RecordsArray[1]);
DataListBox.Items.Add(RecordsArray[2]);
}
}
inputFile.Close();
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
I need to read a text file containing time stamps and temperatures. The thing is, I need to only show the temperatures in a listBox, spliting the string before displaying it.
So far I've managed to show the text file in the list, but im struggling with removing the timestamps.
My code:
public partial class Form1 : Form
{
OpenFileDialog openFile = new OpenFileDialog();
string line = "";
private void button1_Click(object sender, EventArgs e)
{
if (openFile.ShowDialog() == DialogResult.OK)
{
StreamReader sr = new StreamReader(openFile.FileName);
while(line != null)
{
line = sr.ReadLine();
if(line != null)
{
string[] newLine = line.Split(' ');
listBox1.Items.Add(newLine);
}
}
sr.Close();
}
}
Now the listBox only shows String[] array.
Oh, and also I need to include this in my code:
const int numOfTemp = 50;
double dailyTemp[numOfTemps];
The textfile is in this format:
11:11:11 -10,50
You should take [1] item of the the array after Split:
using System.Linq;
...
private void button1_Click(object sender, EventArgs e)
{
if (openFile.ShowDialog() != DialogResult.OK)
return;
var temps = File
.ReadLines(openFile.FileName)
.Select(line => line.Split(' ')[1]); // we need temperature only
try {
listBox1.BeginUpdate();
// In case you want to clear previous items
// listBox1.Items.Clear();
foreach (string temp in temps)
listBox1.Items.Add(temp);
}
finally {
listBox1.EndUpdate();
}
}
I am attempting to save a simple list to a file without using Serialize. Is this possible?
public partial class Form1 : Form
{
public List<string> _testList = new List<string>();
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
int _add = 0;
string _addString ="";
for (int i = 0; i < 5; i++)
{
_add =+ i;
_addString = Convert.ToString(_add);
_testList.Add(_addString);
}
TextWriter tw = new StreamWriter("SavedList.txt", true);
foreach (string s in _testList)
tw.WriteLine(s);
tw.Close();
StreamReader streamReader = new StreamReader("SavedList.txt");
// Read the data to the end of the stream.
listBox1.Text = streamReader.ReadToEnd();
// Close the text stream reader.
streamReader.Close();
// Close the file stream.
//fileStream.Close();
}
private void button2_Click(object sender, EventArgs e)
{
Close();
}
}
This emits no errors, however it does nothing.
I will use Serialize if necessary, however the suspicion is that is not necessary. Is it?
You can use the File Class to facilitate this.
File.WriteAllLines("SavedList.txt", _testList.ToArray());
To read it back you can then use:
string[] lines = File.ReadAllLines("SavedList.txt");
foreach (string line in lines)
listBox1.Items.Add(line);
your problem is that the Text field of ListBox
doesn't work like that.
change:
listBox1.Text = streamReader.ReadToEnd();
to:
foreach(string s in streamReader.ReadToEnd().Split(new string[]{"\r\n"}))//!!!the end of line characters may differ depending on your system!!!
{
listBox1.Items.Add(s);
}
the Text field holds the currently selected text . it is not for adding items to the list.
Right now my code takes the entire text file and just places it all into one text box. What I am trying to figure out how to do is have it place each line of the file into each separate text box.
namespace HomeInventory2
{
public partial class Form1 : Form
{
public Form1(string prepopulated)
{
InitializeComponent();
textBoxAmount.Text = prepopulated;
}
private void label1_Click(object sender, EventArgs e)
{
}
private void submitButton_Click(object sender, EventArgs e)
{
CreateInventory create = new CreateInventory();
create.ItemAmount = textBoxAmount.Text;
create.ItemCategory = textBoxCategories.Text;
create.ItemProperties = textBoxValue.Text;
create.ItemValue = textBoxValue.Text;
InventoryMngr invtryMngr = new InventoryMngr();
invtryMngr.Create(create);
}
}
Assuming that the order of the lines is always the same and that each TextBox belongs to a line:
IEnumerable<String> lines = File.ReadLines(path);
textBoxAmount.Text = lines.ElementAtOrDefault(0);
textBoxCategories.Text = lines.ElementAtOrDefault(1);
textBoxValue.Text = lines.ElementAtOrDefault(2);
...
Enumerable.ElementAtOrDefault<TSource> Method
Returns the element at a specified index in a sequence or a default
value if the index is out of range (null in this case).
You could use System.IO.File.ReadAllLines(string filename).
What this does is reads each line of the file into a String array.
You could then do something like:
using System.IO;
//Namespace, Class Blah Blah BLah
String[] FileLines = File.ReadAllLines("Kablooey");
textBox1.Text = FileLines[0];
textbox2.Text = FileLines[1];
And so on. I hope this helps :)
I have a Windows Form application. What this application does, is let the user browse to a drive/folder they wish to have files renamed for. This app renames files that have "invalid" characters (that are defined in a RegEx pattern).
What i want to happen here is, after the user decides which drive/folder to use, a datagridview pops up showing the user files in the drive/folder that are going to be renamed. The user then clicks a button to actually rename the files. I'm having trouble though getting the code for my button in DriveRecursion_Results.cs set up. Can anybody help me? Code plz -- i'm extremely new to this and need syntax to look at to understand.
Form1 code:
namespace FileMigration2
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
FolderSelect("Please select:");
}
public string FolderSelect(string txtPrompt)
{
//Value to be returned
string result = string.Empty;
//Now, we want to use the path information to population our folder selection initial location
string initialPathDir = (#"C:\");
System.IO.DirectoryInfo info = new System.IO.DirectoryInfo(initialPathDir);
FolderBrowserDialog FolderSelect = new FolderBrowserDialog();
FolderSelect.SelectedPath = info.FullName;
FolderSelect.Description = txtPrompt;
FolderSelect.ShowNewFolderButton = true;
if (FolderSelect.ShowDialog() == DialogResult.OK)
{
string retPath = FolderSelect.SelectedPath;
if (retPath == null)
{
retPath = "";
}
DriveRecursion_Results dw = new DriveRecursion_Results();
dw.Show();
dw.DriveRecursion(retPath);
result = retPath;
}
return result;
}
}
}
DriveRecursion_Results.cs code: [the button is in here that i need help with!]
namespace FileMigration2
{
public partial class DriveRecursion_Results : Form
{
public DriveRecursion_Results()
{
InitializeComponent();
}
private void listView1_SelectedIndexChanged(object sender, EventArgs e)
{
}
public void DriveRecursion(string retPath)
{
//recurse through files. Let user press 'ok' to move onto next step
// string[] files = Directory.GetFiles(retPath, "*.*", SearchOption.AllDirectories);
string pattern = " *[\\~#%&*{}/<>?|\"-]+ *";
//string replacement = "";
Regex regEx = new Regex(pattern);
string[] fileDrive = Directory.GetFiles(retPath, "*.*", SearchOption.AllDirectories);
List<string> filePath = new List<string>();
dataGridView1.Rows.Clear();
try
{
foreach (string fileNames in fileDrive)
{
if (regEx.IsMatch(fileNames))
{
string fileNameOnly = Path.GetFileName(fileNames);
string pathOnly = Path.GetDirectoryName(fileNames);
DataGridViewRow dgr = new DataGridViewRow();
filePath.Add(fileNames);
dgr.CreateCells(dataGridView1);
dgr.Cells[0].Value = pathOnly;
dgr.Cells[1].Value = fileNameOnly;
dataGridView1.Rows.Add(dgr);
filePath.Add(fileNames);
}
else
{
DataGridViewRow dgr2 = new DataGridViewRow();
dgr2.Cells[0].Value = "No Files To Clean Up";
dgr2.Cells[1].Value = "";
}
}
}
catch (Exception e)
{
StreamWriter sw = new StreamWriter(retPath + "ErrorLog.txt");
sw.Write(e);
}
}
private void button1_Click(object sender, EventArgs e)
{
//What do i type in here to call my FileCleanUp method???
}
}
SanitizeFileNames.cs code:
namespace FileMigration2
{
public class SanitizeFileNames
{
public static void FileCleanup(List<string>filePath)
{
string regPattern = "*[\\~#%&*{}/<>?|\"-]+*";
string replacement = "";
Regex regExPattern = new Regex(regPattern);
foreach (string files2 in filePath)
{
try
{
string filenameOnly = Path.GetFileName(files2);
string pathOnly = Path.GetDirectoryName(files2);
string sanitizedFileName = regExPattern.Replace(filenameOnly, replacement);
string sanitized = Path.Combine(pathOnly, sanitizedFileName);
//write to streamwriter
System.IO.File.Move(files2, sanitized);
}
catch (Exception ex)
{
//write to streamwriter
}
}
}
}
}
}
Any help is appreciated!
Thanks :)
Put
public partial class DriveRecursion_Results : Form {
List<string> filePath;
and in driveRecursion method, just use
filePath = new List<string>();
and in the action button method, why don't you do
if(filePath != null)
SanitizeFileNames.FileCleanup(filePath);
You call filePath.Add twice ?
Your 'else' is in the wrong place too.
What is dgr2?