Fetching Directory Count - c#

I need a little help with a little project I'm working on in C#.
Here is my code:
//TO FETCH DIRECTORY TEST
System.IO.DirectoryInfo dir = new System.IO.DirectoryInfo(#"C:\Users\Tahmid\Downloads");
int count = dir.GetFiles().Length;
Simply what I want it to do is see how many files is in my "Downloads" folder.
I ran into 2 problems though.
First problem is the word System is underlined in green and it says "Unreachable Code Detected".
At first I thought It might be caused by a namespace I'm missing, I checked back at my code and saw I already have using System.IO; and using System;. I think these 2 are the one's I need for the directory count.
So I am out of idea's on why its underlined green. xD
Second problem is that when I put those 2 lines of code into my project it breaks another section of my code which is this:
case "switch window":
SendKeys.Send("%{TAB " + count + "}");
count += 1;
break;
I get "count" underlined in blue saying "Use of unassigned local variable 'count'"
I'm quite baffled at the fact why the 2 lines of code to fetch the directory length break that.

We need to see more of your code to know the answers for sure... but here are some ideas that might help.
This would cause the first error
if (false)
{
// this code is unreachable... false will never be true.
//TO FETCH DIRECTORY TEST
System.IO.DirectoryInfo dir = new System.IO.DirectoryInfo(#"C:\Users\Tahmid\Downloads");
int count = dir.GetFiles().Length;
}
The second error is because you are using count before initializing it ... something like this:
int count;
/// ... more code
case "switch window":
SendKeys.Send("%{TAB " + count + "}"); // uninitialized use.
count += 1;
break;
Where you need this:
int count;
count = 0; // now count has a value.
/// ... more code
case "switch window":
SendKeys.Send("%{TAB " + count.ToString() + "}");
count += 1;
break;
The 2nd being caused by the first is clear -- if the code is never reachable then it will never set count to a value so count is initialized.

Related

Why do I need to initialize the string variable 'name'?

This was frustrating to solve. I kept getting the error "Use of unassigned local variable" on the 'name' variable in the line of code near the end where it outputs to the List Box.
The solution was to initialize the variable 'name'.
At first, I had simply declared the 'name' variable without initializing it. This threw the error of "Use of unassigned local variable". When I finally also initialized that variable (as shown below), the error went away.
But I don't understand this, because, by the time the code reaches that output line, the name variable does get assigned.
Can someone please explain WHY initializing the 'name' variable got rid of the compiling error?
'''
try
{
StreamReader inputFile; // StreamReader object to read the file
string line; // To hold a line from the file.
int row = 0; // Student/line counter.
int column = 0; // Counter for columns in CSV file.
int total = 0; // Accumulator for grades.
double average = 0; // Average test score
string name = ""; // each student's name
// Create delimiter array
// Why is this necessary? Why not just put the delimiter in the Split method call?
//char[] delim = { ',' };
// Open the CSV file
inputFile = File.OpenText("Grades.csv");
while (!inputFile.EndOfStream)
{
// increment the row counter
row++;
// Read a line from the file
line = inputFile.ReadLine();
// Get the test scores as tokens
string[] scores = line.Split(',');
// Set the accumulator to zero
total = 0;
// Calculate the total of the test score tokens
for (column = 0; column < scores.Length; column++)
{
if (column == 0)
{
name = scores[column];
}
else
{
total += int.Parse(scores[column]);
}
}
// Calculate the average test score
average = (double)total / (scores.Length - 1);
// Display the average
//averagesListBox.Items.Add("The average for student " + row + " is " + average.ToString("n1"));
averagesListBox.Items.Add("The average for " + name + " is " + average.ToString("n1"));
}
// Close the file
inputFile.Close();
// Display the total records read
totalLabel.Text = row.ToString("n0");
}
catch (Exception ex)
{
// Display an error message
MessageBox.Show(ex.Message);
}
}
'''
The compiler cannot prove that it does get set anywhere. What if scores.Length is zero? Then there is no assignment. So the compiler is correct in throwing an error of possible situation where it is not assigned a value.
If you add a condition for scores.Length always being over zero the compiler might be able to deduce that a value is always set. And you could always set it directly to the first element in an array and loop starting from 1 anyway, which is much more efficient.
Actually, it it possible that you're using the name variable without initialization if column < scores.Length.
That's what the warning is about.

Second for loop isn't running inside my update

This if statement within the update() have 2 for-loop, but it only runs the first one after the if condition is activated, and I don't know why.
I'm building a code for path optimizing in unity. Currently I have to find out the path that came across the nodes/points/positions with a certain positions array that the index is the order the path should follow. Some path between 2 nodes are repeated , ex: A to B and B to A is consider the same path and shall thicken the width of line AB eventually rendered. So I tried to sort out the position array into 2 different array for comparing if any of the pair of nodes(or we can say line) is repeated. And I encountered a problem in if statement within the update().
The first should sort out the original array for later comparison. The second one is just for testing if the first one do their job. No comparing yet. However after hitting play and satisfy the if statement I can see all the Debug.log in the first one, everything is normal, the sorting is normal, while the second one just doesn't print anything at all.
I tried comment out the first one, and the second one will run.
I tried to put second one outside the if statement, after it, and without commenting the first one, the second one won't run.
I tried to put the second one before the first one, in the if statement, the second one will run and the first one won't.
So I think this might be some kind of syntax error or am I using the if statement wrong? Please help.
if (l > 0)//activate when we choose any preset processes
{
for (int n = 0; n <= positions.Length; n++)//this loop will sort all the pos1 and pos 2 into array for current frame
{
curPos_1 = positions[n];//current position of node 1
curPos_2 = positions[n + 1];
Debug.Log("CURPOS_1 of line number " + n + " is " + curPos_1);
Debug.Log("CURPOS_2 of line number " + n + " is " + curPos_2);
flag[n] = 0;
Pos_1[n] = curPos_1;
Pos_2[n] = curPos_2;
Debug.Log("POS_1 array of line number " + n + " is " + Pos_1[n]);
Debug.Log("POS_2 array of line number " + n + " is " + Pos_2[n]);
}
for (int o = 0; o <= positions.Length; o++)
{
Debug.Log("flag of number " + o + " is " + flag[o]);
}
}
As described, all for loop should print something. Not just one of it.
Have you checked your Unity Console Window ?
In your first loop you get the next item but its condition will fail at the end, i.e. off by one.
Correct code should be something like this:
var floats = new float[100];
for (var i = 0; i < floats.Length - 1; i++)
{
var f1 = floats[i];
var f2 = floats[i + 1];
}
Now, Unity, has a behavior of ON ERROR RESUME NEXT, so it's highly probable that an error has occured but you haven't seen it (did you turn off the red icon for toggling errors in console ?).
Also, for some conditions only you know about (you didn't post the whole context), it could work once after you've changed some state of your program.

Possible Empty statement error in a loop

This is my first loop assignment, so I am struggling to find the error, but the code looks like this:
//Loop
for (yearDisp == startYr; yearDisp <= endYr; yearDisp++); <-EMPTY STATEMENT ERROR
{
listBoxDisp.Items.Add("Year:" + yearDisp.ToString());
yearDisp = yearDisp + 1;
I might be putting the whole thing together wrong.. I need to create something like this:
User enters two years (ex: 1988 and 2022) and when I hit the "GO" button, the loop needs to display each year in the listbox starting with 1988, and 1999, 2000, etc all the way to 2022. Then it needs to stop.
Where am I going wrong, and why it that semicolon creating a "possible empty statement error?
Thanks in advance.
Get rid of that semicolon you pointed out. Semicolon marks the end of a statement... and you don't want your for loop to end there, otherwise it's empty. That's why you get that error.
yearDisp == startYr should be yearDisp = startYr. It's an assignment not an equality check.
Add a curly brace at the end of your for loop.
I am not sure if it's by design, but you're iterating your yearDisp twice. Once by yearDisp++ and second time by yearDisp = yearDisp + 1. If you only mean to do it once, get rid of one of them.
for (yearDisp = startYr; yearDisp <= endYr; yearDisp++)
{
listBoxDisp.Items.Add("Year:" + yearDisp.ToString());
//yearDisp = yearDisp + 1; <-- may be a design error, do you need this one?
}

Outlook.Items Restrict() weird behavior

I just want to filter my Mails with the Restrict-Method like so:
restriction += "[ReceivedTime] < '" + ((DateTime)time).ToString("yyyy-MM-dd HH:mm") + "'";
var count = oFolder.Items.Restrict(restriction).Count;//Cast<object>().ToList();
for (int i = 0; i < count; i++)
{
var crntReceivedTime = ((OutLook.MailItem)oFolder.Items.Restrict(restriction).Cast<object>().ToList()[i]).ReceivedTime;
if (crntReceivedTime > time)
{
string t = "";
}
}
Theoretically the line string t = ""; should never be called, because I determined the Items to never have entries which ReceivedTime's value is bigger than time.
The problem is the line gets called, what means the restricted Items Collection contains entries which its shouldn't contain.
Did I do something wrong or is the Restrict()-method just failing?
Firstly, you are using multiple dot notation. You are calling Restrict (which is expensive even if it is called once) on each step of the loop. Call it once, cache the returned (restricted) Items collection, then loop over the items in that collection.
Secondly, what is the full restriction? You are using += to add an extra restriction on ReceivedTime. What is the actual value of the restriction variable?
Edit: I had no problem with the following script executed from OutlookSpy (I am its author - click Script button, paste the script, click Run):
restriction = " [ReceivedTime] < '2011-06-11 00:00' "
set Folder = Application.ActiveExplorer.CurrentFolder
set restrItems = Folder.Items.Restrict(restriction)
for each item in restrItems
if TypeName(item) = "MailItem" Then
Debug.Print item.ReceivedTime & " - " & item.Subject
End If
next

Errata in Extreme Programming Adventures in C#?

I'm trying to work my way through Ron Jeffries's Extreme Programming Adventures in C#. I am stuck, however, in Chapter 3 because the code does not, and cannot, do what the author says it does.
Basically, the text says that I should be able to write some text in a word-wrap enabled text box. If I then move the cursor to an intermediate line and hit enter, the code should re-display the lines before the cursor, add a couple of lines and a set of HTML paragraph tags, then append the rest of the lines. The code doesn't match the text because it uses the textbox.lines property. Well, no matter how many word-wrapped lines there are in a text box, there's only ONE line in the Lines property until you hit a carriage return. So, the statement that the code should, "Copy the rest of the lines into the buffer" appears wrong to me.
I'd appreciate anybody having experience with the book telling me what I'm reading, or doing, wrong!
Thanks.
EoRaptor
Try emailing Ron Jeffries directly. I have the book - somewhere, but I don't remember it not working. His email address is ronjeffries at acm dot org and put [Ron] in the subject line.
(And for those wondering - his email info was right from his website Welcome page)
I've also just started this book and had exactly the same problem although the code you have included looks further along than where I am.
The 'subscript out of range' occurred for 2 reasons, first as Ron explains he was just testing and so returned a hard-coded value of 3 before he wrote the CursorLine() function, which means you I think at least 4? lines of text which as you say need to be pasted in, or maybe set the text to this value before running, also as you say they need to have carriage returns to make txtbox.Lines return an array of strings.
The second reason occurs even after CursorLine() has been implemented but only happens if the text box is empty as txtbox.Lines returns string[0] but I think Ron is implementing a 'User Story' which says that when text has been entered and user presses enter, so not sure if he fixes this later, but will probably find out!
The author's do state that they are learning C# and will show the development wart's and all, which is one of the reasons I have chosen to study this book as I think it is encouraging me to develop projects. I also try to do the code first before looking at his solutions to see if I'm thinking the same way, but maybe I know C# a little better than I give myself credit for, or I'm completly crap, but I've noticed a few things, first he says that overriding OnKeyDown() doesn't work, but I think he must have got confused and tried to do in Form, instead of deriving from TextBox and overriding there.
This was my code when reading the 'User Story':
int curPos = txtbox.SelectionStart;
string Wrd = Environment.NewLine + "<P></P>" + Environment.NewLine;
txtbox.SelectedText = Wrd;
int pl = Environment.NewLine.Length + 3; // "<P>" length is 3
// Put text cursor inbetween <P> tags
txtbox.SelectionStart = curPos + pl;
It works differently to Ron's code, but was just my interpretation of the 'User Story' and not sure how should act if text is selected or wether to split line if text cursor in the middle etc.
Also in 'My Adventures' in Extreme Programming Adventures in C#
txtbox.GetLineFromCharIndex(txtbox.SelectionStart)
gets the cursor line position and doesn't matter if no carriage returns or resized,
as far as I can tell, I done little test with:
txtbox.GetLineFromCharIndex(txtbox.TextLength)
which returns the total amount of lines, which will vary if you resize the text box.
Using C# I always look for solutions which already exsist and people may slate me for this but I think MS have created a great language with great components which do what you expect them to do, so don't have to re-create the wheel each time.
Although like I say it's early days in this book and perhaps these simple solutions aren't extensible enough and maybe Ron's taking that into account, although he did mention just get it working then worry about that later is more the XP way.
Warren.
print("using System;
using System.Collections;
using System.Collections.Generic;
using System.Text;
namespace NotepadOne {
public class TextModel {
private String[] lines;
private int selectionStart;
private int cursorPosition;
public TextModel() {
}
public String[] Lines {
get {
return lines;
}
set {
lines = value;
}
}
public int SelectionStart {
get {
return selectionStart;
}
set {
selectionStart = value;
}
}
public int CursorPosition {
get {
return cursorPosition;
}
set {
cursorPosition = value;
}
}
public void InsertControlPText() {
lines[lines.Length - 1] += "ControlP";
}
public void InsertParagraphTags() {
int cursorLine = CursorLine();
String[] newlines = new String[lines.Length + 2];
for (int i = 0; i <= cursorLine; i++) {
newlines[i] = lines[i];
}
newlines[cursorLine + 1] = "";
newlines[cursorLine + 2] = "<P></P>";
for (int i = cursorLine + 1; i < lines.Length; i++) {
newlines[i + 2] = lines[i];
}
lines = newlines;
selectionStart = NewSelectionStart(cursorLine + 2);
}
private int CursorLine() {
int length = 0;
int lineNr = 0;
foreach (String s in lines) {
if (length <= SelectionStart && SelectionStart <= length + s.Length + 2) {
break;
length += s.Length + Environment.NewLine.Length;
lineNr++;
}
lineNr++;
}
return lineNr;
}
private int NewSelectionStart(int cursorLine) {
int length = 0;
for (int i = 0; i < cursorLine; i++) {
length += lines[i].Length + Environment.NewLine.Length;
}
return length + 3;
}
}
}
");
The InsertParagraphTags method is called by pressing the enter key in the textbox.
BTW, the break here is that there is a subscript out of range error if you try to hit enter at the end of the text. I'm sure I could figure out how to get around this but then my code won't look like his code; which is what I'm trying to learn.
Randy

Categories

Resources