I have a console application that uses a number of command line switches to control various methods. Each of the command line switches is handled by a switch statement that is within a for loop that iterates over each of the args.
for (int x = 0; x < args.Length; x++)
{
switch (args[x])
{
...
}
}
This works perfectly for my needs, however I need to add a --loop switch that causes the preceding args to be looped indefinitely based upon a timeout period specified by the --set-timeout switch.
The code I have so far is:
switch (args[x])
{
case "--set-timeout-5m":
timeout = 300000;
System.Threading.Thread.Sleep(timeout);
break;
....
case "--loop":
x = 0;
break;
}
The problem is setting x does not cause the for loop to continue from the start of args. It just sits there.
I am expecting x to have scope as the code is within the for loop and no errors are generated in Visual Studio. I am also expecting the break statement to break the case and pass x to the for loop.
Can anyone explain why it does not work or perhaps post a workaround?
for (int x = 0; x < 10; x++)
{
Console.Write(x);
x = 0;
}
prints
0 1 1 1 1 1 1 1 1 ...
because x++ is executed after each iteration.
If you want it to print
0 0 0 0 0 0 0 0 0 ...
you need to change it to
for (int x = 0; x < 10; x++)
{
Console.Write(x);
x = -1;
}
Your Thread.Sleep will just block the current thread. To set a timeout, get the current date before the loop:
DateTime start = DateTime.Now;
Then, on each iteration, check if the current time has exceeded the timeout, and if it has, break out of the loop:
if(DateTime.Now.Subtract(start).TotalMilliseconds >= timeout) {
// Stop your processin'!
}
Related
Why does While loop post-increments (or post-decrements) a variable right after examination of the condition and not after the whole loop?
As in:
int x = 0;
while (x++ < 5)
Console.WriteLine(x);
The output is: 1 2 3 4 5, when I believe it should be 0 1 2 3 4. It seems it checks the condition - true - inrements right away. Is that normal behaviour, becase I've recently been practising Plain C and it's completely different.
Should I rather go with this option for more clarity?
while (x < 5)
Console.WriteLine(x);
++x;
If you would use a for loop your expected answer would be correct:
the while does not have any special inner workings like that.
for (x = 0; x < 5; x++)
is the way to write this with the most clarity.
The behavior is correct and ANSI-C does it in the same way, if you execute the same code.
x++ is "one command" and the increment is already done as soon as you move on to the next command.
The difference between x++ and ++x is, that the later one returns the "new value" and the first one returns the "old value".
May the following be what you want:
int x = 0;
do
{
Console.WriteLine(x++);
}
while (x < 5);
But I also think in general this specific case of "do it 5-times" is best solved with a for-loop as suggested by #ikdekker.
Your loop is equivalent to:
int x = 0;
while (x < 5)
{
x++;
Console.WriteLine(x);
}
Since the incrementation will be done immeditely after the condition line (x<5).
So your second loop is the correct one (you should add braces though), or if you really want condition and increment in the same time you can use the do..while loop:
int x = 0;
do
{
Console.WriteLine(x);
} while (++x < 5);
You can use a for loop for this as has been mentioned. You can also declare the x variable inside the for loop.
for (var x = 0; x < 5; x++)
{
Console.WriteLine(x);
}
you are using x++ in the wrong place
Console.WriteLine(x++)
instead of
while(x++ < 5)
mark as answer if it helps
I'm writing a chess engine in C#, and I'm trying to debug move generation. I've been using breakpoints so far to check variables, but I need a better way to debug. Despite the fact that a breakpoint shows that this list has a length of 86, the loop only runs 5 times. The only thing I can think of is that the arrays in the list have a length of 5, but I have no idea what would be causing this.
foreach (int[] debugBoard in futures)
{
for (int i = 0; i < 5; i++)
{
Debug.Write(debugBoard[i].ToString().PadLeft(3, ' '));
}
Debug.Write("\n");
int[,] debugOutBoard = new int[8, 8];
Array.Copy(chessBoard.Pieces(), debugOutBoard, 64);
if (debugBoard[0] < 0 || debugBoard[1] < 0 || debugBoard[2] < 0 || debugBoard[3] < 0 || debugBoard[0] > 7 || debugBoard[1] > 7 || debugBoard[2] > 7 || debugBoard[3] > 7)
break;
debugOutBoard[debugBoard[2], debugBoard[3]] = debugOutBoard[debugBoard[0], debugBoard[1]];
debugOutBoard[debugBoard[0], debugBoard[1]] = 0;
int rowLength = debugOutBoard.GetLength(0);
int colLength = debugOutBoard.GetLength(1);
for (int i = 0; i < rowLength; i++)
{
for (int j = 0; j < colLength; j++)
{
Debug.Write(debugOutBoard[i, j].ToString().PadLeft(3, ' '));
}
Debug.Write(Environment.NewLine + Environment.NewLine);
}
}
Also, I tried using a concurrentbag to store moves in (I was going to multithread the move processing later on) but as soon as the foreach loop touched the concurrent bag, all the memory values of the bag changed to one value. I've been stuck on this roadblock for days, and I really need help.
Your if statement breaks out of the for loop when its condition is met, I presume this happens for the first time on the 5th/6th iteration.
What I meant to do is iterate to the next element. What command would I use to do that? –
You need to use continue instead of break
If 'futures' contains 86 items the only way it could stop iterating is if an exception occurs. Visual studio (In default settings) should break when this occurs unless you handle the exception somewhere.
Wrap the whole thing in a try{} catch{} and set a breakpoint in catch and see if it hits.
Not sure what I am doing wrong here. I am new to C# and am trying to convert VB.Net code from an online tutorial. I can't get this For loop to iterate:
if (Screens.Count > 0)
{
for (int i = Screens.Count - 1; i == 0; --i)
{
if (Screens[i].GrabFocus==true)
{
Screens[i].Focused = true;
DebugScreen.FocusScreen = "Focused Screen: " + Screens[i].Name;
break;
}
}
}
There are 2 screens in the list. The second screen (Screens[1]) has GrabFocus set to true. During debugging, execution jumps from line 3 (for ...) right to the last closing brace. The nested "If" statement never executes. Also, I think the break statement is wrong because I am actually trying to end the "For" loop.
You haven't written correctly your for loop. You should replace it with the following:
for (int i = Screens.Count - 1; i >=0; --i)
You start from the value Screens.Count - 1 and you decrease by 1 the i in each step, until i becomes equal to zero. Then you stop.
Generally speaking, the correct syntax is the following:
for (initializer; condition; iterator)
body
The initializer section sets the initial conditions. The statements in this section run only once, before you enter the loop. The section can contain only one of the following two options.
The condition section contains a boolean expression that’s evaluated to determine whether the loop should exit or should run again.
The iterator section defines what happens after each iteration of the body of the loop. The iterator section contains zero or more of the following statement expressions, separated by commas
The body of the loop consists of a statement, an empty statement, or a block of statements, which you create by enclosing zero or more statements in braces.
For more information about this, please have a look here.
What's the problem in your case?
The second bullet. The condition, i==0 is false by the begin. Hence the loop will not be executed at all.
i == 0 should be i >= 0
i.e.
for (int i = Screens.Count - 1; i >= 0; --i)
i == 0 should be replaced with i >= 0
for (int i = Screens.Count - 1; i >=0; --i)
Your for loop is not correct. Here's is the code
if (Screens.Count > 0)
{
for (int i = Screens.Count - 1; i >= 0; --i)
{
if (Screens[i].GrabFocus==true)
{
Screens[i].Focused = true;
DebugScreen.FocusScreen = "Focused Screen: " + Screens[i].Name;
break;
}
}
}
I have a very strange problem with my code. It will fully run the 1st for loop, then complete the foreach, but then it will skip back to the "ThreadStart IMAPDelegate" (line 1 of the for loop) and then crash because of an ArgumentOutOfRangeException. Can someone explain why the program is doing this? I debugged it line by line and it literally just skips back up into the a line in the for loop. If it had normally run the for loop again, it would have set x back to 0 and it would not have crashed. Any suggestions?
for (int x = 0; x < UserInfo.Count; x++)
{
ThreadStart IMAPDelegate = delegate{SendParams(UserInfo[x], IMAPServers[x]); };
MyThreads.Add(new Thread(IMAPDelegate));
}
foreach (Thread thread in MyThreads)
{
thread.Start();
}
This is by design when you use an anonymous method like that. As soon as the thread starts running, it executes the SendParams() method call. Which then bombs because the "x" variable is already incremented beyond UserInfo.Count. Fix:
for (int x = 0; x < UserInfo.Count; x++)
{
int user = x;
ThreadStart IMAPDelegate = delegate{SendParams(UserInfo[user], IMAPServers[user]); };
MyThreads.Add(new Thread(IMAPDelegate));
}
Does anyone know how why this code returns out of range exception?
For example if the leastAbstractions List instance has count == 10, the loop will execute 11 times finishing with i = 10 and returning this exception.
for (int i = 0; i < leastAbstractions.Count; i++)
{
Task.Factory.StartNew((object state) =>
{
this.Authenticate(new HighFragment(leastAbstractions[i])).Reactivate();
}, TaskCreationOptions.PreferFairness);
}
Your loop isn't actually executing 11 times - it's only executing 10 times, but i == 10 by the time some of those tasks execute.
It's the normal problem - you're capturing a loop variable in a lambda expression. Just take a copy of the counter, and capture that instead:
for (int i = 0; i < leastAbstractions.Count; i++)
{
int copy = i;
Task.Factory.StartNew((object state) =>
{
this.Authenticate(new HighFragment(leastAbstractions[copy]))
.Reactivate();
}, TaskCreationOptions.PreferFairness);
}
That way, when your task executes, you'll see the current value of the "instance" of copy that you captured - and that value never changes, unlike the value of i.
See Eric Lippert's blog posts on this: part 1; part 2.