Я хоть убей не могу заставить это работать, и я знаю, что это будет что-то глупое. Этот код запускается по нажатию кнопки. Я хочу, чтобы он запускался и читал несколько строк из ввода RichTextBox и запускал ...

c#
0
JJWW 8 Июл 2021 в 12:20

5 ответов

Лучший ответ

Я запустил код здесь, и он не выполняет «только первую строку». Цикл while пытается продолжить работу. Однако вы увеличиваете значение переменной lineno в два раза Например, для команды "drawto": когда вы выполняете проход в drawto, если (что верно), вы увеличиваете lineno. Затем вы переходите к circle, который ничего не делает, и в конце вы делаете loopline = lineno (что нормально), но затем вы снова делаете lineno++, и это пропускает строку.

В конечном итоге вы перейдете «за границы массива». Я бы изменил его с цикла while на цикл for (поскольку вы уже знаете, сколько строк вы выполняете).

for (lineno = 0; lineno < lines.Length; lineno++){ ... }

Что происходит с вашим кодом? Остановится, выдаст исключение или просто закроется?

Изменить: я бы также подумал о том, чтобы сделать else if вместо нескольких операторов if. Edit2: ваш оператор else будет запускаться КАЖДЫЙ РАЗ, когда команда НЕ является "кругом", и прервет цикл (я удалил else из своего кода ранее для тестирования ... извините). Обратите внимание на предложения if/else от @Hans Killian. - Я тоже новичок на этом сайте, поэтому все еще учусь отвечать ..

0
Dan 8 Июл 2021 в 10:00

Хорошо, он работал из смеси разных ответов, которые находятся в отредактированном коде из вопроса. Но изменив его на цикл 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;                    
                }

            }

                        
        }

Спасибо за вашу помощь

0
JJWW 8 Июл 2021 в 10:11

Ваша индексация, когда вы проверяете, какую команду содержит строка, неверна. Вы используете 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 только в том случае, если ни одно из других условий if не совпало.

Возможно, вы захотите использовать оператор switch вместо ifs и elses. Это немного чище, имо.

0
Hans Kilian 8 Июл 2021 в 09:51

Выражение if (command[lineno].Equals("circle") == true) должно быть else if (command[lineno].Equals("circle") == true) в дополнение к тому, что предложил @Hans Killian.

0
vish 8 Июл 2021 в 09:37

Некоторые предложения:

  • 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 && b){c}.

Как насчет этого кода, вырезанного для начала?


    string commandinit = "MoveTo 1 2\r\nDraw 1 2\r\n";
    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;
            }
        }
    }

1
r2d2 8 Июл 2021 в 10:00