#c#
Вопрос:
Я ни за что на свете не смогу заставить это работать, и я знаю, что это будет что-то глупое. Этот код запускается при нажатии кнопки. Я хочу, чтобы он запускался и считывал несколько строк с RichTextBox
входных данных и запускал соответствующий код, как простой язык программирования, который выводит фигуры на холст. До сих пор все, что это делает, — это запускает первую строку на входе и прерывает цикл.
Любая помощь будет признательна.
private void run_button(object sender, EventArgs e)
{
int lineno = 0;
int loopline = 0;
int param = 0;
string commandinit = commandbox.Text.Trim().ToLower();
string[] lines = commandinit.Split('n');
while (lines[lineno] != null)
{
string[] command = lines[lineno].Split(' ', ',');
if (command[lineno].Equals("moveto") == true)
{
if (!Int32.TryParse(command[1], out positionx)) ; //translate string to int
if (!Int32.TryParse(command[2], out positiony)) ;
Canvas.xPos = positionx;
Canvas.yPos = positiony;
lineno ;
}
if (command[lineno].Equals("drawto") == true || command[lineno].Equals("draw") == true)
{
if (!Int32.TryParse(command[1], out positionx)) ; //translate string to int
if (!Int32.TryParse(command[2], out positiony)) ;
Canvas.toX = positionx;
Canvas.toY = positiony;
MyCanvas.DrawLine(Canvas.toX, Canvas.toY);
Refresh();//refresh display
Console.WriteLine("COMMAND - LINE DRAWN");
lineno ;
}
if (command[lineno].Equals("circle") == true)
{
if (!Int32.TryParse(command[1], out positionx)) ;
Canvas.sizec = positionx;
MyCanvas.DrawCircle(Canvas.sizec);
Refresh();//refresh display
Console.WriteLine("COMMAND - DRAW CIRCLE");
lineno ;
}
else
{
Console.WriteLine("While loop broken");
break;
}
}
}
Спасибо за всю вашу помощь, ребята. Это мой обновленный код. Он работает до тех пор, пока следующая строка не станет пустой, когда произойдет сбой в while (lines[lineno] != null)
системе.Исключение IndexOutOfRangeException: «Индекс находился за пределами массива».
private void run_button(object sender, EventArgs e)
{
int lineno = 0;
int loopline = 0;
int param = 0;
string commandinit = commandbox.Text.Trim().ToLower();
string[] lines = commandinit.Split('n');
while (lines[lineno] != null)
{
string[] command = lines[lineno].Split(' ', ',');
if (command[0].Equals("moveto") == true)
{
if (!Int32.TryParse(command[1], out positionx)) ; //translate string to int
if (!Int32.TryParse(command[2], out positiony)) ;
Canvas.xPos = positionx;
Canvas.yPos = positiony;
lineno ;
}
else if (command[0].Equals("drawto") == true || command[0].Equals("draw") == true)
{
if (!Int32.TryParse(command[1], out positionx)) ; //translate string to int
if (!Int32.TryParse(command[2], out positiony)) ;
Canvas.toX = positionx;
Canvas.toY = positiony;
MyCanvas.DrawLine(Canvas.toX, Canvas.toY);
Refresh();//refresh display
Console.WriteLine("COMMAND - LINE DRAWN");
lineno ;
}
else if (command[0].Equals("circle") == true)
{
if (!Int32.TryParse(command[1], out positionx)) ;
Canvas.sizec = positionx;
MyCanvas.DrawCircle(Canvas.sizec);
Refresh();//refresh display
Console.WriteLine("COMMAND - DRAW CIRCLE");
lineno ;
}
else if (command[0].Equals("square") == true)
{
if (!Int32.TryParse(command[1], out positionshape)) ; //translate string to int
Canvas.sizes = positionshape;
MyCanvas.DrawSquare(Canvas.sizes);
Refresh();//refresh display
Console.WriteLine("COMMAND - SQUARE DRAWN");
lineno ;
}
else
{
Console.WriteLine("While loop broken");
break;
}
}
Комментарии:
1. Есть что-то от ваших блоков и скобок
{}
. Если вы правильно вставите свой разнесенный код, закрывающая скобка перед последнейelse
закроет телоwhile loop
2. Я думаю , что было бы легче понять, что здесь происходит, если бы вы перешли на a
switch case
, где случаи-это действие, аdefault case
разрыв цикла.
Ответ №1:
Некоторые предложения:
while (lines[lineno] != null)
не работает. Вы ищетеfor(var i = 0; i < lines.Length; i )
или простоforeach(var line in lines)
.if (command..) {..} if (command..) {..} else {..}
обработает все условия if и блок else для всех команд, кроме «circle». Вы ищетеif() {} else if() else {}
илиswitch()
.- Во внутреннем блоке:
if(!Int32..); if(!Int32..);
не работает из-за точки с запятой в конце if и отсутствующих фигурных скобок вокруг следующего блока кода. Ты ищешьif(a amp;amp; b){c}
.
Как насчет того, чтобы этот код был обрезан для начала?
string commandinit = "MoveTo 1 2rnDraw 1 2rn";
string[] lines = commandinit.Split('n');
foreach (var line in lines)
{
string[] command = line.Trim().Split(' ', ',');
switch (command[0].Trim())
{
case "MoveTo":
{
// ParseMoveToCommand(command);
break;
}
case "Draw":
{
// ParseDrawCommand(command);
break;
}
default:
{
Console.WriteLine("Unknown command");
break;
}
}
}
Ответ №2:
Я запустил код здесь, и он не выполняет «только первую строку». Цикл while действительно пытается продолжаться. Однако вы дважды увеличиваете lineno
переменную, например, для команды «drawto»: когда вы выполняете проход в drawto
if (что верно), вы увеличиваете lineno
. Затем вы переходите к circle
, что ничего не делает, и в конце вы делаете a loopline = lineno
(что нормально), но затем вы делаете lineno
это снова, и это пропускает строку.
В конечном итоге вы перейдете «за пределы массива». Я бы изменил его с цикла while на цикл for for (так как вы уже знаете, сколько строк вы выполняете).
for (lineno = 0; lineno < lines.Length; lineno ){ ... }
Что происходит с вашим кодом? Останавливается ли он, дает ли вам исключение или он просто закроется?
Редактировать: Я бы также рассмотрел возможность выполнения else if
вместо нескольких if
утверждений. Edit2: Ваше else
утверждение будет выполняться КАЖДЫЙ РАЗ, КОГДА команда НЕ ЯВЛЯЕТСЯ «кругом», и разорвет цикл (ранее я удалил остальное из своего кода для тестирования… извините) . Рассмотрите if/else
предложения @Hans Killian. — Я также новичок на этом сайте, поэтому все еще учусь отвечать..
Ответ №3:
Заявление if (command[lineno].Equals("circle") == true)
должно быть else if (command[lineno].Equals("circle") == true)
дополнением к тому, что предложил @Hans Killian.
Ответ №4:
Ваша индексация, когда вы проверяете, какая команда содержится в строке, неверна. Вы используете lineno
, но так и должно быть 0
, так как вы всегда хотите смотреть на первое слово в строке. Вот также, почему это работает для первой строки, потому что для первой строки lineno
равно 0.
Поэтому, когда вы это сделаете
if (command[lineno].Equals("moveto") == true)
это должно быть
if (command[0].Equals("moveto") == true)
(и, конечно, все другие места, которые вы используете command[lineno]
Другая проблема заключается в том, что ваш else
внизу активируется во всех случаях, когда команда не circle
активирована . Чтобы убедиться, что вы завершаете цикл только тогда, когда не найдено ни одной допустимой команды, вы должны использовать else if
и сделать структуру примерно такой
if (command[0].Equals("moveto") == true)
{
}
else if (command[0].Equals("drawto") == true || command[0].Equals("draw") == true)
{
}
else if (command[0].Equals("circle") == true)
{
}
else
{
Console.WriteLine("While loop broken");
break;
}
Это сделает так, что вы попадете в While loop broken
раздел только в том случае, если ни одно из других «если» не совпадет.
Возможно, вы захотите использовать switch
оператор вместо «если» и «если». Это немного чище, имо.
Комментарии:
1. Спасибо, да, в этом есть смысл. Но он по-прежнему запускает только первую строку, а затем разрывает цикл. Я не понимаю, почему.
2. @JJWW Я добавил раздел об использовании
else if
в свой ответ.3. Извините, я новичок на этом сайте. Могу ли я опубликовать обновленный код в качестве комментария или мне следует отредактировать свой первоначальный вопрос?
4. @JJWW Я имел в виду обновить первоначальный вопрос. Но я не знаю, хорошая ли это идея, когда я думаю об этом. Оставить все как есть тоже нормально.
Ответ №5:
Хорошо, он работал из смеси разных ответов, которые содержатся в отредактированном коде вопроса. Но изменив его на for
цикл, используя for (lineno = 0; lineno < lines.Length; lineno )
обновленный рабочий код
private void run_button(object sender, EventArgs e)
{
int lineno = 0;
int loopline = 0;
int param = 0;
string commandinit = commandbox.Text.Trim().ToLower();
string[] lines = commandinit.Split('n');
for (lineno = 0; lineno < lines.Length; lineno )
{
string[] command = lines[lineno].Split(' ', ',');
if (command[0].Equals("moveto") == true)
{
if (!Int32.TryParse(command[1], out positionx)) ; //translate string to int
if (!Int32.TryParse(command[2], out positiony)) ;
Canvas.xPos = positionx;
Canvas.yPos = positiony;
}
else if (command[0].Equals("drawto") == true || command[0].Equals("draw") == true)
{
if (!Int32.TryParse(command[1], out positionx)) ; //translate string to int
if (!Int32.TryParse(command[2], out positiony)) ;
Canvas.toX = positionx;
Canvas.toY = positiony;
MyCanvas.DrawLine(Canvas.toX, Canvas.toY);
Refresh();//refresh display
Console.WriteLine("COMMAND - LINE DRAWN");
}
else if (command[0].Equals("circle") == true)
{
if (!Int32.TryParse(command[1], out positionx)) ;
Canvas.sizec = positionx;
MyCanvas.DrawCircle(Canvas.sizec);
Refresh();//refresh display
Console.WriteLine("COMMAND - DRAW CIRCLE");
}
else if (command[0].Equals("square") == true)
{
if (!Int32.TryParse(command[1], out positionshape)) ; //translate string to int
Canvas.sizes = positionshape;
MyCanvas.DrawSquare(Canvas.sizes);
Refresh();//refresh display
Console.WriteLine("COMMAND - SQUARE DRAWN");
}
else if (command[0].Equals("rectangle") == true || command[0].Equals("rect") == true) //what happens if draw rectangle command is used
{
if (!Int32.TryParse(command[1], out positionx)) ; //translate string to int
if (!Int32.TryParse(command[2], out positiony)) ;
Canvas.sizerx = positionx;
Canvas.sizery = positiony;
MyCanvas.DrawRect(Canvas.sizerx, Canvas.sizery);
Refresh();//refresh display
Console.WriteLine("COMMAND - DRAW RECTANGLE");
}
else if (command[0].Equals("colour") == true || command[0].Equals("col") == true || command[0].Equals("color") == true) //changes colour of the pen
{
if (command[1].Equals("red") == true || command[1].Equals("r") == true)
{
Canvas.P1.Color = System.Drawing.Color.Red;
}
else if (command[1].Equals("blue") == true || command[1].Equals("blu") == true)
{
Canvas.P1.Color = System.Drawing.Color.Blue;
}
else if (command[1].Equals("black") == true || command[1].Equals("bla") == true)
{
Canvas.P1.Color = System.Drawing.Color.Black;
}
else if (command[1].Equals("green") == true || command[1].Equals("g") == true)
{
Canvas.P1.Color = System.Drawing.Color.Green;
}
else if (command[1].Equals("yellow") == true || command[1].Equals("yel") == true || command[1].Equals("y") == true)
{
Canvas.P1.Color = System.Drawing.Color.Yellow;
}
}
else if (command[0].Equals("loop") == true)
{
loopline = lineno;
}
else if (command[0].Equals("loop") == true)
{
loopline = lineno;
}
else
{
Console.WriteLine("While loop broken");
break;
}
}
}
Спасибо за всю вашу помощь