I am currently working with Reverse Polish Notation. I have able to perform all operation in exception of exponential math. I am aware that C# sharps performs exponential math with Math.Pow but using that in my code is giving me an error 'System.Collections.Generic.Stack<T>.Push(T)' is a 'method', which is not valid in the given context. You can find the specific issue in the last if else statement. Any idea how I can properly correct or create a way to perform exponential math?
Code
private string inputValue = "";
private void RPNCalc(string rpnValue)
{
Stack<int> stackCreated = new Stack<int>();
stackCreated.Clear();
string[] inputArray = rpnValue.Split();
int end = inputArray.Length - 1;
int numInput;
int i = 0;
do
{
if ("=+-*/%^".IndexOf(inputArray[i]) == -1)
{
try
{
numInput = Convert.ToInt32(inputArray[i]);
stackCreated.Push(numInput);
}
catch
{
MessageBox.Show("Please check the input");
}
}
else if (inputArray[i]== "+")
{
try
{
int store1 = stackCreated.Pop();
int store2 = stackCreated.Pop();
stackCreated.Push(store2 + store1);
}
catch
{
}
}
else if (inputArray[i]== "-")
{
try
{
int store1 = stackCreated.Pop();
int store2 = stackCreated.Pop();
stackCreated.Push(store2 - store1);
}
catch
{
}
}
else if (inputArray[i]== "%")
{
try
{
int store1 = stackCreated.Pop();
int store2 = stackCreated.Pop();
stackCreated.Push(store2 % store1);
}
catch
{
}
}
else if (inputArray[i]== "*")
{
try
{
int store1 = stackCreated.Pop();
int store2 = stackCreated.Pop();
stackCreated.Push(store2 * store1);
}
catch
{
}
}
else if (inputArray[i]== "/")
{
try
{
int store1 = stackCreated.Pop();
int store2 = stackCreated.Pop();
stackCreated.Push(store2 / store1);
}
catch
{
}
}
else if (inputArray[i] == "^")
{
try
{
int store1 = stackCreated.Pop();
int store2 = stackCreated.Pop();
stackCreated.Push.Math.Pow(store1, store2);
}
catch
{
}
}
}
while(i++ < end && inputArray[i]!= "=" && stackCreated.Count != 0);
string result = inputValue + " " + stackCreated.Pop().ToString() + Environment.NewLine;
TxtOutputBox.AppendText(result);
TxtInputBox.Clear();
}
Should be:
stackCreated.Push((int)Math.Pow(store1, store2));
This will perform the power operation, and then push the result onto the stack.
Its like doing:
int tmp = (int)Math.Pow(store1, store2);
stackCreated.Push(tmp);
Also note that Math.Pow works on doubles. Your ints (store1 and store2) will be automatically converted up to a double, but you need to tell the compiler to cast the result back down to an int.
Related
I have implemented functionality using pdfbox to extract words from any pdf. It extracts the words line by line. Below is the class that I am using for this purpose:
class PDFTextLocationStripper : PDFTextStripper
{
public string textWithPostion = "";
public Dictionary<float, Dictionary<float, PdfWord>> pdfWordsByXByY;
public PDFTextLocationStripper(): base()
{
try
{
textWithPostion = "";
pdfWordsByXByY = new Dictionary<float, Dictionary<float, PdfWord>>();
}
catch (Exception ex)
{
}
}
protected override void processTextPosition(TextPosition text)
{
try
{
float textX = text.getXDirAdj();
float textY = text.getYDirAdj();
if (!String.IsNullOrWhiteSpace(text.getUnicode()))
{
if (pdfWordsByXByY.ContainsKey(textY))
{
Dictionary<float, PdfWord> wordsByX = pdfWordsByXByY[textY];
if (wordsByX.ContainsKey(textX))
{
PdfWord word = wordsByX[textX];
wordsByX.Remove(word.Right);
word.EndCharWidth = text.getWidthDirAdj();
if (text.getHeightDir() > word.Height)
{
word.Height = text.getHeightDir();
}
word.EndX = textX;
word.Text += text.getUnicode();
if (!wordsByX.Keys.Contains(word.Right))
{
wordsByX.Add(word.Right, word);
}
}
else
{
float requiredX = -1;
float minDiff = float.MaxValue;
for (int index = 0; index < wordsByX.Keys.Count; index++)
{
float key = wordsByX.Keys.ElementAt(index);
float diff = key - textX;
if (diff < 0)
{
diff = -diff;
}
if (diff < minDiff)
{
minDiff = diff;
requiredX = key;
}
}
if (requiredX > -1 && minDiff <= 1)
{
PdfWord word = wordsByX[requiredX];
wordsByX.Remove(requiredX);
word.EndCharWidth = text.getWidthDirAdj();
if (text.getHeightDir() > word.Height)
{
word.Height = text.getHeightDir();
}
word.EndX = textX;
word.Text += text.getUnicode();
if (!wordsByX.ContainsKey(word.Right))
{
wordsByX.Add(word.Right, word);
}
}
else
{
PdfWord word = new PdfWord();
word.Text = text.getUnicode();
word.EndX = word.StartX = textX;
word.Y = textY;
word.EndCharWidth = word.StartCharWidth = text.getWidthDirAdj();
word.Height = text.getHeightDir();
if (!wordsByX.ContainsKey(word.Right))
{
wordsByX.Add(word.Right, word);
}
pdfWordsByXByY[textY] = wordsByX;
}
}
}
else
{
Dictionary<float, PdfWord> wordsByX = new Dictionary<float, PdfWord>();
PdfWord word = new PdfWord();
word.Text = text.getUnicode();
word.EndX = word.StartX = textX;
word.Y = textY;
word.EndCharWidth = word.StartCharWidth = text.getWidthDirAdj();
word.Height = text.getHeightDir();
wordsByX.Add(word.Right, word);
pdfWordsByXByY.Add(textY, wordsByX);
}
}
}
catch (Exception ex)
{
}
}
}
Here, is the code to call this class:
private Dictionary<float, Dictionary<float, PdfWord>> ExtractTextWithLocation(PDDocument doc)
{
try
{
PDFTextLocationStripper textStripper = new PDFTextLocationStripper();
textStripper.setSortByPosition(true);
textStripper.getText(doc);
return textStripper.pdfWordsByXByY;
}
catch (Exception ex)
{
return null;
}
}
This code extracts words which are aligned horizontally fine, but how do I implement functionality to detect words which are vertical or slanting?
I get this error. Later I searched and found out the reason of illegal characters in my XML and its solution. But I don't have the access to edit any of these files. My job is to read and fetch the tag value, attribute value and similar stuff. SO I can't replace the binary characters with escapes like '\x01' with . Also I tried to include CheckCharacters =false in XMLreader settings. It doesn't take this. Still it is throwing the same error.
Is it not possible to fix in XMLreader? I read about XMLtextReader. It can skip the exception. But already I have coded for all my features using XMLreader. It would be good if I can find a solution for this. Otherwise I would have to change all my code.
My code:
private void button1_Click(object sender, EventArgs e)
{
int i = 0;
var filenames = System.IO.Directory
.EnumerateFiles(textBox1.Text, "*.xml", System.IO.SearchOption.AllDirectories)
.Select(System.IO.Path.GetFullPath);
foreach (var f in filenames)
{
var resolver = new XmlUrlOverrideResolver();
resolver.DtdFileMap[#"X1.DTD"] = #"\\location\X1.DTD";
resolver.DtdFileMap[#"R2.DTD"] = #"\\location\X2.DTD";
resolver.DtdFileMap[#"R5.DTD"] = #"\\location\R5.DTD";
XmlReaderSettings settings = new XmlReaderSettings();
settings.DtdProcessing = DtdProcessing.Parse;
settings.XmlResolver = resolver;
XmlReader doc = XmlReader.Create(f, settings);
while (doc.Read())
{
if ((doc.NodeType == XmlNodeType.Element) && (doc.Name == "ap"))
{
if (doc.HasAttributes)
{
String fin = doc.GetAttribute("ap");
if (fin == "no")
{
String[] array = new String[10000];
array[i] = (f);
File.AppendAllText(#"\\location\NAPP.txt", array[i] + Environment.NewLine);
i++;
}
else
{
String[] abs = new String[10000];
abs[i] = (f);
File.AppendAllText(#"\\location\APP.txt", abs[i] + Environment.NewLine);
i++;
}
}
}
}
}
MessageBox.Show("Done");
}
This is a very simple example of character "filter" that will replae the 0x06 character with a space:
public class MyStreamReader : StreamReader {
public MyStreamReader(string path)
: base(path) {
}
public override int Read(char[] buffer, int index, int count) {
int res = base.Read(buffer, index, count);
for (int i = 0; i < res; i++) {
if (buffer[i] == 0x06) {
buffer[i] = ' ';
}
}
return res;
}
}
You use it this way:
using (var sr = new MyStreamReader(f)) {
var doc = XmlReader.Create(sr, settings);
Note that it's very simple because it's replacing a character (the 0x06) with another character of the same "length" (the space). If you wanted to replace a character with a "sequence" of characters (to escape it), it would get more complex (not impossible, 30 minutes of work difficult)
(I have checked and it seems the XmlTextReader only uses that method and not the Read() method)
As always, when a programmer tells you 30 minutes, it means 0 minutes or 2 hours :-)
This is the "more complex" ReplacingStreamReader:
/// <summary>
/// Only the Read methods are supported!
/// </summary>
public class ReplacingStreamReader : StreamReader
{
public ReplacingStreamReader(string path)
: base(path)
{
}
public Func<char, string> ReplaceWith { get; set; }
protected char[] RemainingChars { get; set; }
protected int RemainingCharsIndex { get; set; }
public override int Read()
{
int ch;
if (RemainingChars != null)
{
ch = RemainingChars[RemainingCharsIndex];
RemainingCharsIndex++;
if (RemainingCharsIndex == RemainingChars.Length)
{
RemainingCharsIndex = 0;
RemainingChars = null;
}
}
else
{
ch = base.Read();
if (ch != -1)
{
string replace = ReplaceWith((char)ch);
if (replace == null)
{
// Do nothing
}
else if (replace.Length == 1)
{
ch = replace[0];
}
else
{
ch = replace[0];
RemainingChars = replace.ToCharArray(1, replace.Length - 1);
RemainingCharsIndex = 0;
}
}
}
return ch;
}
public override int Read(char[] buffer, int index, int count)
{
int res = 0;
// We leave error handling to the StreamReader :-)
// We handle only "working" parameters
if (RemainingChars != null && buffer != null && index >= 0 && count > 0 && index + count <= buffer.Length)
{
int remainingCharsCount = RemainingChars.Length - RemainingCharsIndex;
res = Math.Min(remainingCharsCount, count);
Array.Copy(RemainingChars, RemainingCharsIndex, buffer, index, res);
RemainingCharsIndex += res;
if (RemainingCharsIndex == RemainingChars.Length)
{
RemainingCharsIndex = 0;
RemainingChars = null;
}
if (res == count)
{
return res;
}
index += res;
count -= res;
}
while (true)
{
List<char> sb = null;
int res2 = base.Read(buffer, index, count);
if (res2 == 0 || ReplaceWith == null)
{
return res;
}
int j = 0;
for (int i = 0; i < res2; i++)
{
char ch = buffer[index + i];
string replace = ReplaceWith(ch);
if (sb != null)
{
if (replace == null)
{
sb.Add(ch);
}
else
{
sb.AddRange(replace);
}
}
else if (replace == null)
{
buffer[j] = ch;
j++;
}
else if (replace.Length == 1)
{
buffer[j] = replace[0];
j++;
}
else if (replace.Length == 0)
{
// We do not advance
}
else
{
sb = new List<char>();
sb.AddRange(replace);
}
}
res2 = j;
if (sb != null)
{
int res3 = Math.Min(sb.Count, count - res2);
sb.CopyTo(0, buffer, index + res2, res3);
if (res3 < sb.Count)
{
RemainingChars = new char[sb.Count - res3];
RemainingCharsIndex = 0;
sb.CopyTo(res3, RemainingChars, 0, RemainingChars.Length);
}
res += res3;
}
else
{
res2 = j;
// Can't happen if sb != null (at least a character must
// have been added)
if (res2 == 0)
{
continue;
}
}
res += res2;
return res;
}
}
}
Use it like:
using (var sr = new ReplacingStreamReader(f))
{
sr.ReplaceWith = x =>
{
return x == 0x6 ? " " : null;
// return x == '.' ? " " : null; // Replace all . with
};
var doc = XmlReader.Create(sr, settings);
Be aware that the ReplacingStreamReader doesn't "know" which part of the xml it is modifying, so rarely a "blind" replace is ok :-) Other than this limitation, you can replace any character with any string (null in the ReplaceWith means "keep the current character", equivalent to x.ToString() in the example given. Returning string.Empty is valid, means remove the current character).
The class is quite interesting: it keeps a char[] RemainingChars with the chars that have been read (and filtered by ReplaceWith) but that haven't been returned by a Read() method because the passed buffer was too much small (the ReplaceWith method could "enlarge" the read string, making it too much big for the buffer!). Note that sb is a List<char> instead of a StringBuilder. Probably using one or the other would be nearly equivalent, code-wise.
You could first read the content into a string replace (escape) the content, and then load it into a XmlReader:
foreach (var f in filenames) {
string text;
using (StreamReader s = new StreamReader(f,Encoding.UTF8)) {
text = s.ReadToEnd();
}
text = text.Replace("\x01",#""); //replace the content
//load some settings
var resolver = new XmlUrlOverrideResolver();
resolver.DtdFileMap[#"X1.DTD"] = #"\\location\X1.DTD";
resolver.DtdFileMap[#"R2.DTD"] = #"\\location\X2.DTD";
resolver.DtdFileMap[#"R5.DTD"] = #"\\location\R5.DTD";
XmlReaderSettings settings = new XmlReaderSettings();
settings.DtdProcessing = DtdProcessing.Parse;
settings.XmlResolver = resolver;
XmlReader doc = XmlReader.Create(text, settings);
//perform processing task
//...
}
A C++ method returns the correct value when I use a conditional breakpoint, but an incorrect value without a breakpoint.
C# method which calls C++:
bool SetProperty(Element element, Node referencePoint, List<Materializer> materializers, List<ulong> properties)
{
// Loop over STLs
for (int i = 0; i < materializers.Count; i++)
{
Materializer materializer = materializers[i];
if (materializer.IsPointInside(referencePoint.X, referencePoint.Y, referencePoint.Z, pentalTreeDatasets[i].top))
{
element.PropertyId = properties[i];
return true;
};
}
return false;
}
C++ methods in the header file:
int CountIntersects(double x, double y, double z, PentalTreeNode ^root)
{
Math3d::M3d rayPoints[2], intersectionPoint;
rayPoints[0].set(x,y,z);
rayPoints[1].set(x,y,1.0e6);
if(!root)
return 0;
else
{
int special = CountIntersects(x,y,z,root->special);
if (x <= root->xMax && x >= root->xMin && y <= root->yMax && y >= root->yMin)
{
if( _stlMesh->IsRayIntersectsPoly(root->index, rayPoints, intersectionPoint))
{
return (1 + special);
}
else
return special;
}
else
{
if (y>root->yMax)
{
return (CountIntersects(x,y,z,root->top)+special);
}
else if(y<root->yMin)
{
return (CountIntersects(x,y,z,root->bottom)+special);
}
else if(x<root->xMin)
{
return (CountIntersects(x,y,z,root->left)+special);
}
else if(x>root->xMax)
{
return (CountIntersects(x,y,z,root->right)+special);
}
else
return special;
}
}
}
bool IsPointInside(double x, double y, double z, PentalTreeNode ^root)
{
int intersectionCount = 0;
Math3d::M3d rayPoints[2], intersectionPoint;
rayPoints[0].set(x,y,z);
rayPoints[1].set(x,y,1.0e6);
if(_box->IsContainingPoint(x,y,z))
{
intersectionCount=CountIntersects(x,y,z,root);
return (intersectionCount%2!=0);
}
}
C++ methods in other header files:
bool IsRayIntersectsPoly(int nPolygonIndex, Math3d::M3d RayPoints[2], CVector3D& IntersectionPoint)
{
CMeshPolygonBase& Poly = m_PolygonArray[nPolygonIndex];
CArrayResultI Result;
int* pPolygonPoints = GetPolygonPoints(Poly, Result);
Math3d::MPlane TrianglePlane;
double Atmp[3], A;
CVector3D* pPoints[3];
pPoints[0] = &m_PointArray[*pPolygonPoints].m_Position;
for(int i = 1; i < Result.GetSize() - 1; i++)
{
pPoints[1] = &m_PointArray[*(pPolygonPoints+i)].m_Position;
pPoints[2] = &m_PointArray[*(pPolygonPoints+i+1)].m_Position;
TrianglePlane.Init(*pPoints[0], *pPoints[1], *pPoints[2]);
TrianglePlane.IntersectLine(RayPoints[0], RayPoints[1], IntersectionPoint);
A = GetTriangleArea(*pPoints[0], *pPoints[1], *pPoints[2]);
for(int j = 0; j < 3; j++)
{
Atmp[j] = GetTriangleArea(*pPoints[j], *pPoints[(j+1)%3], IntersectionPoint);
}
if( fabs(A - Atmp[0] - Atmp[1] - Atmp[2]) < 1.0e-5 ) return true;
}
return false;
};
double GetTriangleArea(CVector3D& T1, CVector3D& T2, CVector3D& T3)
{
double a, b, c, s;
a = (T1 - T2).length();
b = (T2 - T3).length();
c = (T3 - T1).length();
s = 0.5 * (a + b + c);
return( sqrt(s * (s - a)* (s - b)* (s - c)) );
}
When I start the program which calls SetProperty() within the for-loop, the results for some iterator values are wrong. When I set conditional breakpoints for critical iterator values in the for-loop and step over it, then the result is OK for that item. What may be the problem?
This is method in which I post breakpoint. For example, for critical element.Id==2393.
private void StartButton_Click(object sender, EventArgs e)
{
DateTime startTime = DateTime.Now;
List<Materializer> materializers = new List<Materializer>();
List<ulong> properties = new List<ulong>();
// Load STLs
for (int i = 0; (int)i < (this.dataGridView.RowCount - 1); i++)
{
if (dataGridView.Rows[i].Cells[1].Value != null && (string)dataGridView.Rows[i].Cells[1].Value != "")
{
Materializer materializer = new Materializer();
materializer.LoadSTLMesh(dataGridView.Rows[i].Cells[0].Value.ToString());
materializers.Add(materializer);
properties.Add((ulong)dataGridView.Rows[i].Cells[1].Tag);
}
}
CreatePentalTrees(materializers);
int processedElementCount = 0;
int changedElementCount = 0;
// Loop over elements
foreach (Element element in model.ElementsList.Values)
if ((element.Topology == 7 || element.Topology == 8) && !lockedProperties.ContainsKey(element.PropertyId)) // 3D elements only
{
Node center = this.CenterPoint(element, model.NodesList);
if (element.Id == 2393)
{
//if breakpoints thats ok, else not ok
Console.WriteLine(element.Id);
Console.WriteLine(element.PropertyId);
}
if (SetProperty(element, center, materializers, properties)) // Check for center point
{
//changedElements.Add(element.Id, true);
changedElementCount++;
}
else
{
// Check for all nodes if center point does not belong to any STL
int[] nodeOrder;
switch (element.Topology)
{
case 7:
nodeOrder = wedgeNodeOrder;
break;
case 8:
nodeOrder = brickNodeOrder;
break;
default:
throw new Exception("Unknown topology " + element.Topology.ToString());
}
for (int i = 0; i < nodeOrder.Length; i++)
{
Node node = model.NodesList[element.NodeIds[nodeOrder[i]]];
if (SetProperty(element, node, materializers, properties))
{
//changedElements.Add(element.Id, true);
changedElementCount++;
break;
}
}
}
if (++processedElementCount % 100 == 0)
{
labelTime.Text = "Changed/processed elements: " + changedElementCount.ToString() + "/" + processedElementCount.ToString();
labelTime.Refresh();
Application.DoEvents();
}
}
DateTime endTime = DateTime.Now;
labelTime.Text = "Total time: " + (endTime - startTime).TotalSeconds.ToString() + " s";
MessageBox.Show("Completed.");
SaveFileDialog saveFileDlg = new SaveFileDialog();
saveFileDlg.Title = "Save FEMAP neutral file";
saveFileDlg.Filter = "(*.neu)|*.neu";
if (saveFileDlg.ShowDialog() == System.Windows.Forms.DialogResult.OK)
{
FemapNeutral.ExportNeu(saveFileDlg.FileName, model);
}
}
You seem to be calling a lot of methods you haven't listed, and/or the wall of code made me get lost. Adding that code won't help: reducing your problem to a simpler one that demonstrates the problem might.
However, the most likely cause of your problem, if you have unmanaged code reading managed data, is that you failed to marshal or pin the data prior to using the managed code.
Unpinned data can be moved around by the garbage collector in unexpected ways.
I want to read a file with this code but after 682 times i get this error:
Exception of type 'System.OutOfMemoryException' was thrown.
System.IO.StreamReader file = new System.IO.StreamReader(scanpad[lusteller]);
scanpad is an array with the filepaths and lusteller is counter for it.
Scanpad excists 11207 files.
I have also have looked en there is a file on place 682
Anyone a solution?
Here the full version of my code
using (StreamReader file = new System.IO.StreamReader(scanpad[lusteller]))
{
//do stuff
lengte = bestandsnaam.Length;
lengte = lengte - 13;
controller = bestandsnaam.Remove(lengte, 13); // controllertype uit naam halen
do
{
rij = file.ReadLine();
if (rij != null) //error op volgende lijn vermijden
{
if (rij.StartsWith("0") || rij.StartsWith("1") || rij.StartsWith("2") || rij.StartsWith("3"))
{
rijcheck = true;
}
teller = teller + 1;
if (teller > 10)
{
if (rijcheck == true) // rij is datumlijn
{
string[] split = rij.Split(' ');
foutinformatie[0, index] = type; //type ophalen
foutinformatie[3, index] = controller; //controllernaam ophalen
foutinformatie[1, index] = split[0]; //datum ophalen
foutinformatie[2, index] = split[1]; //tijd ophalen
foutinformatie[4, index] = split[2]; //foutcode ophalen
foutinformatie[5, index] = split[5]; //foutteller ophalen
if (controller.StartsWith("MPU") == true)
{
lusarraygraad = 5;
while (lusarraygraad < 360)
{
if (graadmpu[0, lusarraygraad] == split[2])
{
try
{
graad = graadmpu[1, lusarraygraad];
foutinformatie[7, index] = graad;
}
catch
{
}
lusarraygraad = lusarraygraad + 499;
graadgevonden = true;
}
lusarraygraad = lusarraygraad + 1;
}
foutinformatie[7, index] = graad;
if (graadgevonden == false)
{
foutinformatie[7, index] = "";
}
graadgevonden = false;
}
//////////////////////////////////////////////////////////////////////////
if (controller.StartsWith("AAUX") == true)
{
lusarraygraad = 4;
while (lusarraygraad < 30)
{
if (graadaaux[0, lusarraygraad] == split[2])
{
try
{
graad = graadaaux[1, lusarraygraad].ToString();
foutinformatie[7, index] = graad;
}
catch
{
}
lusarraygraad = lusarraygraad + 499;
graadgevonden = true;
}
lusarraygraad = lusarraygraad + 1;
}
foutinformatie[7, index] = graad;
if (graadgevonden == false)
{
foutinformatie[7, index] = "";
}
graadgevonden = false;
}
if (controller.StartsWith("ACTRL") == true)
{
lusarraygraad = 6;
while (lusarraygraad < 85)
{
if (graadactrl[0, lusarraygraad] == split[2])
{
try
{
graad = graadactrl[1, lusarraygraad].ToString();
foutinformatie[7, index] = graad;
}
catch
{
}
lusarraygraad = lusarraygraad + 499;
graadgevonden = true;
}
lusarraygraad = lusarraygraad + 1;
}
foutinformatie[7, index] = graad;
if (graadgevonden == false)
{
foutinformatie[7, index] = "";
}
graadgevonden = false;
}
try
{
telleromschrijving = 6;
informatie = "";
while (split[telleromschrijving] != " ")
{
informatie = informatie + " " + split[telleromschrijving];
telleromschrijving = telleromschrijving + 1;
}
}
catch
{
foutinformatie[6, index] = informatie; //foutteller ophalen
}
rijcheck = false;
rij = file.ReadLine();
while (varcheck < 40)
{
// rij met eerste variable
if (rij != "")
{
variable[indexlokaal, varteller] = rij;
foutinformatie[varteller + 8, index] = variable[indexlokaal, varteller] = rij;
varteller = varteller + 1;
rij = file.ReadLine();
}
else
{
foutinformatie[varteller + 8, index] = " ";
varteller = varteller + 1;
}
varcheck = varcheck + 1;
}
varcheck = 0;
varteller = 0;
indexlokaal = indexlokaal + 1;
index = index + 1;
}
}
}
}
while (rij != null);
file.Close();
file.Dispose();
}
I imagine 682 is just a number where you happen to be running out of memory, not a special number. you should encapsulate your streamreader into
using(StreamReader file = new System.IO.StreamReader(scanpad[lusteller]))
{
//do stuff
}
This way, your streamreader is disposed of after being used, clearing memory
EDIT FOR UPDATE
Inside your streamreader you also have
rij = file.ReadLine();
while (varcheck < 40)
{
// rij met eerste variable
if (rij != "")
{
variable[indexlokaal, varteller] = rij;
foutinformatie[varteller + 8, index] = variable[indexlokaal, varteller] = rij;
varteller = varteller + 1;
rij = file.ReadLine();
}
but you are not checking if ReadLine is returning null again, looking at
http://msdn.microsoft.com/en-GB/library/system.io.streamreader.readline.aspx
This can also cause a outofmemory exception as your stream has reached null and yet you have continued onwards
It all depends on what you do with the StreamReader.
First of all you need to dispose it, but I don't believe it's the issue as the GC would have collected it before running out of memory (unless you also hold a reference to it).
If you use something like "ReadToEnd" and the content of the files is large you hit Large Object Heap with the strings created (and if you manipulate them by creating sub-string it can get worse).
After a while the heap becomes fragmented so you run out of memory because it is unable to find large enough memory chunk for your request.
Well, that's my guess with little info into your code, good luck.
Try use Using:(disposed memory after read)
using(System.IO.StreamReader file = new System.IO.StreamReader(scanpad[lusteller]))
{
}
I am working on a Reverse polish notation calculator. I created a method that will take care of the calculations but there are three lines in my code that are causing an error. After every = an operation is performed and then displayed. I am trying to grab the string from TxtInputBox and convert to integers but it always shows the catch message Please check the input. Then nothing gets calculated or display. I am sure that my first if statement will check for actual integers and avoid the characters. My ultimate goal is to input a formula in rpn format and have the result display in the multiline textbox.
Sample Input 5 6 -=
Code
namespace rpncalc
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void RPNCalc(TextBox TxtBoxInputbox, TextBox TxtBoxOutputbox)
{
Stack<int> stackone = new Stack<int>();
stackone.Clear();
string[] inputarray = TxtBoxInputbox.Text.Split();
int end = inputarray.Length - 1;
int numinput;
int i = 0;
do
{
if(inputarray[i] != "=" && inputarray[i] != "+" && inputarray[i] != "-" && inputarray[i] != "*" && inputarray[i] != "/")
{
try
{
numinput = Convert.ToInt32(inputarray[i]);
stackone.Push(numinput);
}
catch
{
MessageBox.Show("Please check the input");
}
}
else if (inputarray[i]== "+")
{
try
{
int store1 = stackone.Pop();
int store2 = stackone.Pop();
stackone.Push(store2 + store1);
}
catch
{
}
}
else if (inputarray[i]== "-")
{
try
{
int store1 = stackone.Pop();
int store2 = stackone.Pop();
stackone.Push(store2 + store1);
}
catch
{
}
}
else if (inputarray[i]== "+")
{
try
{
int store1 = stackone.Pop();
int store2 = stackone.Pop();
stackone.Push(store2 + store1);
}
catch
{
}
}
else if (inputarray[i]== "*")
{
try
{
int store1 = stackone.Pop();
int store2 = stackone.Pop();
stackone.Push(store2 + store1);
}
catch
{
}
}
else if (inputarray[i]== "/")
{
try
{
int store1 = stackone.Pop();
int store2 = stackone.Pop();
stackone.Push(store2 + store1);
}
catch
{
}
}
}
while(i < end && inputarray[i]!= "=" && stackone.Count != 0);
string txtout = TxtInputBox + " " + stackone.Pop().ToString() + Environment.NewLine;
TxtOutputBox.AppendText(txtout);
TxtInputBox.Clear();
}
private void Btn_Calc_Click(object sender, EventArgs e)
{
RPNCalc(TxtInputBox, TxtOutputBox);
}
}
}
The Split command, with no argument, is splitting the string on spaces and other whitespace.
There is no space in the input between -= so it is treated as one token that doesn't match the tests in the if statement.
Original answer incorrectly suggested that Split with no argument was splitting into individual characters.
What are you doing to increment i after each iteration of your do loop? I tried out your code and it seems like i is never incremented. Also, when you catch and run
catch
{
MessageBox.Show("Please check the input");
}
You could perhaps change it to:
catch (Exception e)
{
MessageBox.Show(e.ToString());
}
so you could be sure of just what you're catching, and why.
Edit:
Here's my version of your code, now working correctly:
i is incremented in each iteration
Fixed the typo in the minus, multiplication and division operators that made them do addition instead
Removed the redundant addition operator
namespace rpncalc {
public partial class Form1 : Form {
public Form1 () {
InitializeComponent();
}
private void RPNCalc (TextBox TxtBoxInputbox, TextBox TxtBoxOutputbox) {
Stack<int> stackone = new Stack<int>();
stackone.Clear();
string[] inputarray = TxtBoxInputbox.Text.Split();
int end = inputarray.Length - 1;
int numinput;
int i = 0;
do {
if (inputarray[i] != "=" && inputarray[i] != "+" && inputarray[i] != "-" && inputarray[i] != "*" && inputarray[i] != "/") {
try {
numinput = Convert.ToInt32(inputarray[i]);
stackone.Push(numinput);
} catch (Exception e) {
MessageBox.Show(e.ToString());
}
} else if (inputarray[i] == "+") {
try {
int store1 = stackone.Pop();
int store2 = stackone.Pop();
stackone.Push(store2 + store1);
} catch {
}
} else if (inputarray[i] == "-") {
try {
int store1 = stackone.Pop();
int store2 = stackone.Pop();
stackone.Push(store2 - store1);
} catch {
}
} else if (inputarray[i] == "*") {
try {
int store1 = stackone.Pop();
int store2 = stackone.Pop();
stackone.Push(store2 * store1);
} catch {
}
} else if (inputarray[i] == "/") {
try {
int store1 = stackone.Pop();
int store2 = stackone.Pop();
stackone.Push(store2 / store1);
} catch {
}
}
}
while (i++ < end && inputarray[i] != "=" && stackone.Count != 0);
string txtout = TxtInputBox.Text + " " + stackone.Pop().ToString() + Environment.NewLine;
TxtOutputBox.AppendText(txtout);
TxtInputBox.Clear();
}
private void Btn_Calc_Click (object sender, EventArgs e) {
RPNCalc(TxtInputBox, TxtOutputBox);
}
}
}