Problems reading and writing to a text file in C# - c#

Ok so I have looked at every other question that relates to my problem and can't see where I am going wrong. My objective is to write the results of a dice simulator to a text file then read that contents into a listbox in C#. Here is my code so far:
namespace WpfApplication1
{
public MainWindow()
{
InitializeComponent();
}
private void button1_Click(object sender, RoutedEventArgs e)
{
try
{
Random RandomValue = new Random();
Random RandomValue2 = new Random();
using (StreamWriter outputFile = new StreamWriter("C:\\Example.txt"))
{
for (int i = 0; i < 100; i++)
{
int face1 = RandomValue.Next(1, 7);
int face2 = RandomValue2.Next(1, 7);
int toss = face1 + face2;
outputFile.WriteLine(toss);
}
outputFile.Close();
}
}
catch (Exception ex)
{
listBox1.Items.Add(ex);
}
}
private void button2_Click(object sender, RoutedEventArgs e)
{
try
{
using (StreamReader inputFile = new StreamReader("C:\\Example.txt"))
{
String toss;
for (int i = 0; i > 100; i++)
{
toss = inputFile.ReadLine();
listBox1.Items.Add(toss);
}
catch (Exception ex)
{
listBox1.Items.Add(ex);
}
}
}
}
}
When I try running the program I receive the error: System.UnauthorizedAccessException: Access to the path 'C:\Example.txt' is denied.
I think that where I am going wrong is actually creating the text file. When I try to read from it I receive the same message. I am extremely new to C# and have the feeling that I am not calling the file correctly. Any insight would be extremely welcome!

Alright everyone, first I want to thank you all for your help. I found where I was going wrong and why it was not working correctly. First, running C# as an administrator solved the access issues, thank you Selman22. After that it was writing to the file just fine but would not read the file and move the digits to the listbox. After reviewing the code more closely I realized I was declaring the for loop to run as long as I was greater than 100 rather than smaller:
for (int i = 0; i > 100; i++)
After changing the for statement to:
for (int i = 0; i < 100; i++)
It now runs smoothly. Thank you all again!

Related

Long Hang Time On File Load| Binary| C#| List

I am wondering why the load time for the file is so long . i would appreciate it if you would take time to look where it says
if (ReadType == 1)
Around 12,000 items loading
it takes nearly 12 seconds to load a file with a short structure i don't think this is right. I'm new to c# and could use any pointers attached below is the code and the file structure:
here also is attached a video of the issue:
video
screenshot of file:
structureloaded
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace StringEditor
{
public class ItemStr
{
public int a_index;
public byte[] a_name { get; set; }
public byte[] a_descr1 { get; set; }
}
}
private void tsbOpen_Click(object sender, EventArgs e)
{
OpenFileDialog ofd = new OpenFileDialog();
ofd.Filter = "String|*.lod";
if (ofd.ShowDialog() != DialogResult.OK)
return;
if (!ofd.FileName.Contains("strItem") && !ofd.FileName.Contains("strSkill")) //check to see if user isn't opening the right files if not return;
return;
else if (ofd.FileName.Contains("strItem"))
ReadType = 1;
else if (ofd.FileName.Contains("strSkill"))
ReadType = 2;
FileStream fs = new FileStream(ofd.FileName, FileMode.Open);
BinaryReader br = new BinaryReader(fs);
if (ReadType == 1)
{
int max = br.ReadInt32();
int max1 = br.ReadInt32();
for (int i = 0; br.BaseStream.Position < br.BaseStream.Length; i++)
{
ItemStr itemstr = new ItemStr();
itemstr.a_index = br.ReadInt32();
itemstr.a_name = br.ReadBytes(br.ReadInt32());
itemstr.a_descr1 = br.ReadBytes(br.ReadInt32());
itemStringList.Add(itemstr);
listBox1.Items.Add(itemstr.a_index.ToString() + " - " + Encoding.GetEncoding(ISO).GetString(itemstr.a_name));
}
EnableFields();
}
fs.Close();
br.Close();
if (ReadType == 2)
{
int max = br.ReadInt32();
int max1 = br.ReadInt32();
for (int i = 0; i < max; i++)
{
skillStr skillStr = new skillStr();
skillStr.a_index = br.ReadInt32();
skillStr.a_name = br.ReadString();
skillStr.a_tool_tip = br.ReadString();
skillStr.a_descr1 = br.ReadString();
skillStringList.Add(skillStr);
string test = skillStr.a_index + "- " + skillStr.a_name;
listBox1.Items.Add(test);
}
EnableFields();
}
fs.Close();
br.Close();
}
I wrote a small test on my core i5 machine. New form, one button, one listbox:
private void button1_Click(object sender, EventArgs e)
{
for (int i = 0; i < 30000; i++)
listBox1.Items.Add(i.ToString());
}
(I wrote it guessing at the index numbers in your screenshot). Clicked go. Had to wait 11 seconds before the UI became usable again.
I modified it to this:
private void button1_Click(object sender, EventArgs e)
{
listBox1.BeginUpdate();
for (int i = 0; i < 30000; i++)
listBox1.Items.Add(i.ToString());
listBox1.EndUpdate();
}
And there was a barely perceptible delay before it was usable again
The majority of the problem isn't reading the file, it's having the listbox refresh itself X thousands of times as you add one by one. Use Begin/End update to signal that you're loading a large amount of items...
...but then again, ask yourself what is a user REALLY going to do with X tens of thousands of items in a listbox? As a UI/UX guideline, avoid loading more than about 20 to 30 items into a list. Beyond that it's getting into unnavigable, especially at the quantities you're loading. Consider a type to search box - a one pixel jump of the scroll bar is going to move through more items than can fit vertically in your list!
If you're loading a lot of data from a file (or anywhere) into a list box, consider using the VirtualList approach - an example can be found here:
ListView.VirtualMode Property
You probably also want to consider performing the load in a background thread so that the user doesn't experience the apparent "hanging" delay that loading a lot of data can produce.
Listbox.beginupdate() and listbox.endupdate() fixed my problem thanks for the help guys.

reading from a file, input string is incorrect C#

I'm trying to read a file from a .txt, the file is a few numbers. But when I run the program I'm getting input string is not in the correct format. I passed everything into integers using parse. What am I missing?
private void button1_Click(object sender, EventArgs e)
{
try
{
const int Size = 10;
int[] numbers = new int[Size];
int index = 0;
StreamReader inputFile;
inputFile = File.OpenText("Sales.txt");
while(index < numbers.Length && !inputFile.EndOfStream)
{
numbers[index] = int.Parse(inputFile.ReadLine());
index++;
}
inputFile.Close();
foreach( int value in numbers)
{
listBox1.Items.Add(value);
}
}
catch(Exception ex)
{
MessageBox.Show(ex.Message);
}
}
}
}
This is due to your input file consisting of doubles, not ints. Any non-whole number must be stored as a double or a float if you do not want to lose the numbers after the decimal point. Try the following code.
private void button1_Click(object sender, EventArgs e)
{
try
{
const int Size = 10;
double[] numbers = new double[Size];
int index = 0;
StreamReader inputFile;
inputFile = File.OpenText("Sales.txt");
while(index < numbers.Length && !inputFile.EndOfStream)
{
numbers[index] = double.Parse(inputFile.ReadLine());
index++;
}
inputFile.Close();
foreach(double value in numbers)
{
listBox1.Items.Add(value);
}
}
catch(Exception ex)
{
MessageBox.Show(ex.Message);
}
}
However, the issue may also be that your data isn't separated by lines, but by spaces. According to your comment, this may be the case. To fix that, you would use the following code.
private void button1_Click(object sender, EventArgs e)
{
try
{
foreach (double value in File.ReadAllText("Sales.txt").Split(' ').Select((x) => (double.Parse(x))))
{
listBox1.Items.Add(value);
}
}
catch(Exception ex)
{
MessageBox.Show(ex.Message);
}
}
What this solution does is ReadAllText from the file, which automatically handles streams, opening, and closing of the file. I pass that into the Split function, which splits a single String into substrings where the parameter is found. So, if you have 123.613 7342.152 as your String, it will return you a String[] that consists of 123.613 and 7342.152. However, these values are still Strings. We still need to parse them into numbers. We can do this by using the LINQ Select operator, and passing it in a lambda that will call double.Parse(...) on the value and return it as an IEnumerable<double>.

error input string was not in a correct format c#

im working in a project where it has to import excel file and show its details in 3 different data grid .i have a button with codes here.
private void btn1_Click(object sender, EventArgs e)
{
try
{
if (Convert.ToInt32(txtreg.Text) > 0)
{
for (int i = 0; i < dgResult1.Columns.Count; i++)
{
if (dgResult1.Columns[i].HeaderText == "REGHRS")
{
for (int j = 0; j < dgResult1.Rows.Count; j++)
{
if (Convert.ToInt32(dgResult1.Rows[j].Cells["REGHRS"].Value.ToString()) >= 12)
{
dgResult1.Rows[j].Cells["REGHRS"].Value = txtreg.Text;
dgResult2.Rows[j].Cells["REGHRS"].Value = Convert.ToInt32(dgResult2.Rows[j].Cells["REGHRS"].Value.ToString().Trim()) - Convert.ToInt32(txtreg.Text);
dgResult3.Rows[j].Cells["REGHRS"].Value = 0;
}
}
}
}
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message.ToString());
}
}
and it throws an error with input string was not in a correct format .can somebody help me .thanks
This is classic Debugging 101, and it's a good idea to learn it early in your career unless you're the coding Kwisatz Haderach, who can write bug-free code first time, every time :-)
Every time before you attempt a conversion with something like:
Convert.ToInt32(blah)
(I see four of those in your code, two on a single line), you should put in some temporary debug code (message box, or console writeline, or something) to find out what blah is actually set to. This should include the actual string, surrounded by [] characters, and the length of the string.
This will let you identify which string is failing the integer conversion. Once you've established that, the next step will be to work out why.
Handling Convert.ToInt32
your exception occurs by Convert.ToInt32(...) - you use it several times.. that means that in some point a string without a number passed to this function
my guess is that some field from the database contains null and represented by an empty string
althougth Convert.ToInt32 can deal with null values it fails on empty string values
a potential solution - use your own method:
int ConvertInt(string val)
{
return (val.IsNullOrEmpty(val)) ? 0 : int.Parse(val); // Parse aimed to deal with strings only while Convert deals withe several types
}
private void btn1_Click(object sender, EventArgs e)
{
int regNumber = 0;
bool regFlag = int.TryParse(txtreg.Text, regNumber)
if(!regFlag)
{
MessageBox.Show("Reg textbox doesn't have integer value");
return;
}
if(regNumber <= 0)
{
MessageBox.Show("Reg textbox has negative or 0 value");
return;
}
for (int i = 0; i < dgResult1.Columns.Count; i++)
{
if (dgResult1.Columns[i].HeaderText != "REGHRS")
continue;
for (int j = 0; j < dgResult1.Rows.Count; j++)
{
string regHrs = dgResult1.Rows[j].Cells["REGHRS"].Value.ToString();
int regValue = 0;
bool regCheck = int.TryParse(regHrs, out regValue)
if(!regCheck || reg < 12)
continue;
dgResult1.Rows[j].Cells["REGHRS"].Value = txtreg.Text;
//till now both converts should be okay.
dgResult2.Rows[j].Cells["REGHRS"].Value = Convert.ToInt32(dgResult2.Rows[j].Cells["REGHRS"].Value.ToString()) - Convert.ToInt32(txtreg.Text);
dgResult3.Rows[j].Cells["REGHRS"].Value = 0;
}
}
}
The error is that you are converting somewhere wrong integer values. Also you have really bad structure of the code. You should avoid nested if. I wrote how the code should probably look like. Also why catch system exceptions, no user cares about them. You should show relevant text.
Below is my opinion
private void btn1_Click(object sender, EventArgs e)
{
try
{
if (Convert.ToInt32(txtreg.Text) > 0)
{
for (int i = 0; i < dgResult1.Columns.Count; i++)
{
if (dgResult1.Columns[i].HeaderText == "REGHRS")
{
for (int j = 0; j < dgResult1.Rows.Count; j++)
{
if (Convert.ToInt32(dgResult1.Rows[j].Cells["REGHRS"].Value.ToString()) >= 12)
{
dgResult1.Rows[j].Cells["REGHRS"].Value = txtreg.Text;
dgResult2.Rows[j].Cells["REGHRS"].Value = Convert.ToInt32(dgResult2.Rows[j].Cells["REGHRS"].Value.ToString().Trim()) - Convert.ToInt32(txtreg.Text);
dgResult3.Rows[j].Cells["REGHRS"].Value = "0";//UpDate this
}
}
}
}
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message.ToString());
}
}

C# Index was outside the bounds of the array - specific help, please

I'm working on a small programme for booking seats on an airplane - And I keep getting this error. i want the programme to show me which seats on the plane (flysaeder) are being booking by what passenger (passagerer). Only, If I enter in more seats than I have passengers, it won't run - I need it to allow open seats (less "passagerer" than "flysaeder"). What am I doing wrong?
I'm kinda new at this, so I apologize for poor explanation.
Error occurs on "listeOverPassagerer[index] = listeOverPassagerer[i];".
namespace eksamenvingerne
{
public partial class Form1 : Form
{
int flysaeder;
int passagerer;
Random tilfældighed = new Random();
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
listBox1.Items.Clear();
listBox2.Items.Clear();
{
int.TryParse(txtsaeder.Text, out flysaeder);
int.TryParse(txtantalpassagere.Text, out passagerer);
if (passagerer > flysaeder)
{
MessageBox.Show("Ingen frie pladser!");
}
else
{
int[] listeOverPassagerer = Enumerable.Range(0, passagerer).ToArray();
int[] flypladser = new int[flysaeder];
for (int i = 0; i < flysaeder; i++)
{
int index = tilfældighed.Next(0, passagerer);
flypladser[i] = tilfældighed.Next(i, passagerer);
flypladser[i] = listeOverPassagerer[index];
listeOverPassagerer[index] = listeOverPassagerer[i];
}
for (int i = 0; i < flypladser.Length; i++)
{
listBox1.Items.Add("Sæde #" + i + ": Passagernr.:" + flypladser[i]); //listboxen udskriver indholdet af hver eneste plads.
}
}
}
}
}
}
Your logic actually is causing this problem:
First you make sure that passagerer <= flysaeder
if (passagerer > flysaeder)
{
MessageBox.Show("Ingen frie pladser!");
}
Then you do a for loop from 0 to flysaeder -1
for (int i = 0; i < flysaeder; i++)
But flysaeder might be larger than passagerer hence your access of listeOverPassagerer[i] will throw an exception since listeOverPassagerer is of length passagerer

C# Need help editing my line numbering code

I got a code for line numbering, it works perfectly fine for numbering lines the regular way but I'm looking for something a little bit different. I want my code to only count line breaks when i press enter(the program receives an return keycode) and not then the textbox automatically cut the lines with word wrapping. This is the code i'm using right now:
//Instructions
int maxLC = 1; //maxLineCount - should be public
private void InstructionsSyncTextBox_KeyUp(object sender, KeyEventArgs e)
{
int linecount = InstructionsSyncTextBox.GetLineFromCharIndex(InstructionsSyncTextBox.TextLength) + 1;
if (linecount != maxLC)
{
InstructionsLineNumberSyncTextBox.Clear();
for (int i = 1; i < linecount + 1; i++)
{
InstructionsLineNumberSyncTextBox.AppendText(Convert.ToString(i) + "\n");
}
maxLC = linecount;
}
}
How i think i would be done easiest is by saving the line count every time someone presses enter to a list and also everytime someone presses enter it updates the line number texbox with every line number at positions said in list. But i have no idea how to detect when an return is removed. Anybody knows how to solve this?
Extremely basic example that counts the lines in your code you posted:
class Program
{
static void Main(string[] args)
{
string stringFromTextBox =
#" int maxLC = 1; //maxLineCount - should be public
private void InstructionsSyncTextBox_KeyUp(object sender, KeyEventArgs e)
{
int linecount = InstructionsSyncTextBox.GetLineFromCharIndex(InstructionsSyncTextBox.TextLength) + 1;
if (linecount != maxLC)
{
InstructionsLineNumberSyncTextBox.Clear();
for (int i = 1; i < linecount + 1; i++)
{
InstructionsLineNumberSyncTextBox.AppendText(Convert.ToString(i) + ""\n"");
}
maxLC = linecount;
}
}";
Regex r = new Regex("\r", RegexOptions.Multiline);
int lines = r.Matches(stringFromTextBox).Count;
//You'll need to run this line every time the user presses a key
}
}

Categories