Данные из строки

Тема в разделе "Arduino & Shields", создана пользователем avgaz, 5 июл 2015.

  1. avgaz

    avgaz Нерд

    Здравствуйте, есть Ethernet шилд нужно взять данные из Get запроса вернее из url к примеру урл 192.168.0.56/?time=3000
    нежно получить данные после =
    Имеется для примера такой код
    Код (Text):
        #include <SPI.h>
        #include <Ethernet.h>
        byte mac[] = {
          0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED
        };
        IPAddress ip(192, 168, 0, 56);

        EthernetServer server(80);
        String readString;
        void setup() {
          Serial.begin(9600);
          while (!Serial) {
            ;
          }
          pinMode(11,OUTPUT);
          Ethernet.begin(mac, ip);
          server.begin();
          Serial.print("server is at ");
          Serial.println(Ethernet.localIP());
        }


        void loop() {
          EthernetClient client = server.available();
          if (client) {
            while (client.connected()) {
              if (client.available()) {
                char c = client.read();
                if (readString.length() < 100) {
                  readString += c;
                }
                if (c == '\n') {
                // Serial.println(readString); //print to serial monitor for debuging

                  client.println("HTTP/1.1 200 OK"); //send new page
                  client.println("Content-Type: text/html");
                  client.println();
                  client.print(readString);

                  delay(1);
                  client.stop();
                  readString="";
             

                }
              }
            }
          }
        }
     
    где readString возвращает строку с get запросом она выглядит так GET /?time=3000 HTTP/1.1 1
    вот вопрос как из этой строки получить данные которые после = и до HTTP/1.1 1 что бы дальше уже обработать из к примеру записать в епром??
     
  2. geher

    geher Гуру

    Код (Text):

       String S="";
       // определяем позицию символа '=' в строке  и добавляем единицу,
       // чтобы указывало на первый символ после '='
       int first=readString.indexOf('=')+1;
       if (first>0) { // если символ '=' в строке был
        // отрезаем first-1 символов в начале и девять символов  в конце
        // ("TTP/1.1 1", чтобы третий параметр указывл на H)
         S = readString,substring(readString,first,readString,length()-9);
       }
      // В S искомая часть строки
     
    Можно, конечно, улучшить обработку строки на случай наличия мусора после "HTTP/1.1 1".
    Для этого надо последовательно, двигаясь с конца строки, сравнивать либо подстроку (readString,substring(from)) c "HTTP/1.1 1" (readString,substring(from).startsWith("HTTP/1.1 1")), либо символ строки readString.indexOf(i) c очередным символом из "HTTP/1.1 1", двигаясь также с хвоста, и начиная счет символов заново при несовпадении.
     
    avgaz нравится это.
  3. avgaz

    avgaz Нерд

    Извиняюсь за лаймеркий воросы но у меня лезут ошибки при этом коде
    error: 'length' was not declared in this scope
    error: 'substring' was not declared in this scope
     
  4. geher

    geher Гуру

    Плоды теоретического программирования - опечатки.
    Запятые вместо точки, лишний раз вклинилось "readString," в одном месте, неправильно число символов во фрагменте с "HTTP" подсчитал.

    Правильнее так:
    Код (Text):

      String S="";
       // определяем позицию символа '=' в строке  и добавляем единицу,
       // чтобы указывало на первый символ после '='
       int first=readString.indexOf('=')+1;
       if (first>0) { // если символ '=' в строке был
        // отрезаем first-1 символов в начале и 11 символов  в конце
        // "HTTP/1.1 1", чтобы третий параметр указывaл на пробел перед H (полагаю, что пробел тоже не нужен)
         S = readString.substring(first,readString.length()-11);
       }
      // В S искомая часть строки
     
    Надеюсь, больше опечаток не осталось.
     
  5. avgaz

    avgaz Нерд

    Да так нормально, ошибок нет, но есть одна проблема добавляет ноль конец то есть если значение скажем time=3000 то выдает 30000
    И ещё такой момент, а нельзя привязать значение к time= то есть допустим у меня не только может быть time=3000 но и к примеру start=10 и тд то есть урл может быть различный для разных параметров а приязки как такой нет и ещё такой момент к примеру такой урл сразу с несколькими параметрами 192.168.0.56/?time=3000&start=100&stop=50
    как их все получить?
     
  6. geher

    geher Гуру

    Насчет лишнего нуля непонятно. Неоткуда ему вроде взяться на этой части кода.
    А с параметрами просто. Надо просто анализировать строку, начиная с первого символа.
    Примерно так:
    Код (Text):

    String timeString; stopString
    for (int i=0;i<readString.length();){
       if (readString.substring(i).startsWith("time=")) {
           // вытаскиваем значение параметра time
          i+=5; пропускаем "time="
          int j=i; // запоминаем начало числа
         // проходим цифры после time=
          while((i<readString.length())&&((readString.indexOf(i)>=0x30)||(readString.indexOf(i)<=0x39))) {
               ++i;
           }
           timeString=readString.substring(j,i);
       } else
       if (readString.substring(i).startsWith("stop=")) {
           // аналогично
           ...
       }
      else
      ... и т.д.
       ++i;
    }
     
     
  7. avgaz

    avgaz Нерд

    Попробовал вот так из вашего примера с time=
    Код (Text):

      String timeString;
    for (int i=0;i<readString.length();){
      if (readString.substring(i).startsWith("time=")) {
      // вытаскиваем значение параметра time
      i+=5;// пропускаем "time="
      int j=i; // запоминаем начало числа
      // проходим цифры после time=
      while((i<readString.length())&&((readString.indexOf(i)>=0x30)||(readString.indexOf(i)<=0x39))) {
      ++i;
      }
      timeString=readString.substring(j,i);
      }
    }
     
    и шилд перестает отвечать, походу в цикл уходит
     
  8. geher

    geher Гуру

    Опять некоторое количество опечаток и потерь.
    При использовании чужого кода полезен все-таки критический подход к написанному, особенно если оно чисто теоретическое, на железе не проверенное, да еще писано наспех.
    Мои опечатки :
    || в условии проверки на цифру вместо && (цифра должна удовлетворять обоим ограничениям)
    indexOf вместо charAt (логично сравнивать с кодами наибольшей и наименьшей цифр символ в текущей позиции в строке, а не позицию символа, имеющего код, равным номеру текущей позиции, короче говоря, был бред, порожденный случайной заменой одной функции на другую).

    Ваша потеря - ++i; в конце цикла, что приводило к "зависанию" в виде топтания цикла на одном месте, поскольку i не увеличивалось в случаях, когда в текущей позиции нет "time=".

    Итого после исправлений:
    Код (Text):

      String timeString;
      for (int i=0;i<readString.length();){
         if (readString.substring(i).startsWith("time=")) {
            // вытаскиваем значение параметра time
            i+=5;// пропускаем "time="
            int j=i; // запоминаем начало числа
            // проходим цифры после time=
            while((i<readString.length())&&((readString.charAt(i)>=0x30)&&(readString.charAt(i)<=0x39))) {
               ++i;
            }
            timeString=readString.substring(j,i);
         }
         ++i;
      }  
     
     
  9. avgaz

    avgaz Нерд

    Спасибо большое, вроде всё отлично.