Проблема с разделением строк

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

    CR1A = String1.indexOf(13);  // находит местоположение первого
    String1A = String1.substring(0, CR1A + 2 );   // захватывает первую строку данных
    CR1B = String1.indexOf(13, CR1A + 2 ); // находит местоположение секунды,
    String1B = String1.substring(CR1A , CR1B + 2 ); // захватывает вторую строку данных
    CR1C = String1.indexOf(13, CR1B + 2 );
    String1C = String1.substring(CR1B , CR1C + 2 );
    CR1D = String1.indexOf(13, CR1C + 2 );
    String1D = String1.substring(CR1C , CR1D + 2 );
    CR1E = String1.indexOf(13, CR1D + 2 );
    String1E = String1.substring(CR1D , CR1E + 2 );
    CR1F = String1.indexOf(13, CR1E + 2 );
    String1F = String1.substring(CR1E , CR1F + 2 );

    strID = (String1A.substring(0, 2));
    if (strID == "$G") {
      File dataFile = SD.open("GPS1.txt", FILE_WRITE);
      // если файл доступен, пишем в него:

      strID = (String1A.substring(0, 5));
      if (strID == "$GPGG") {
        dataFile.print(dt);
        dataFile.print(" ");
        dataFile.print(tm);
        dataFile.print(msec);
        dataFile.print(",");
        dataFile.print(String1A);
        String1A = "";
      }

      strID = (String1D.substring(4, 6));
      if (strID == "TG" || "DA" || "LL" || "NS" || "RS") {
        dataFile.print(String1B);
        String1B = "";
      }
      strID = (String1C.substring(4, 6));
      if (strID == "TG" || "DA" || "LL" || "NS" || "RS") {
        dataFile.print(String1C);
        String1C = "";
      }
      strID = (String1D.substring(4, 6));
      if (strID == "TG" || "DA" || "LL" || "NS" || "RS") {
        dataFile.print(String1D);
        String1D = "";
      }
      strID = (String1E.substring(4, 6));
      if (strID == "TG" || "DA" || "LL" || "NS" || "RS") {
        dataFile.print(String1E);
        String1E = "";
      }
      strID = (String1F.substring(4, 6));
      if (strID == "TG" || "DA" || "LL" || "NS" || "RS") {
        dataFile.print(String1F);
        String1F = "";
      }
      dataFile.close();
    }

ИЗМЕНИТЬ:

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

#include <TimerOne.h>
#define RxTimeOut 5

/*
  ** MEGA MINI **
  ** MOSI - pin 51
  ** MISO - pin 50
  ** CLK - pin 52
  ** CS - pin 53 (for MKRZero SD: SDCARD_SS_PIN)
  ** SDA - pin 20
  ** SCL - pin 21
*/
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <EEPROM.h>
#include "math.h"
#include <SPI.h>
#include <SD.h>
#include "RTClib.h"
#define DS1307_CTRL_ID 0x68
unsigned long int ticks = 0;
RTC_DS1307 rtc;
bool flag = false;
String GPSmessage = "";
const int chipSelect = 53;
String dataString = "";
//Строка dataString1 = "";
//Строка dataString2 = "";
//Строка dataString3 = "";
bool stringComplete = false;
bool string1Complete = false;
bool string2Complete = false;
bool string3Complete = false;
String strID = "";

unsigned long msec;
const long interval = 500;



#define SCREEN_WIDTH 128 // Ширина OLED-дисплея в пикселях
#define SCREEN_HEIGHT 64 // Высота OLED-дисплея в пикселях

#define OLED_RESET     4 // Номер вывода сброса (или -1, если используется общий вывод сброса Arduino)
#define SCREEN_ADDRESS 0x3C ///< См. спецификацию для адреса; 0x3D для 128x64, 0x3C для 128x32


Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);

unsigned long CurrentBaudRate = 9600;

unsigned long x = 0;

int Up = 3;
int Dn = 4;
int Mnu = 5;


String String1;
String inputString1 = "";         // строка для хранения входящих данных
boolean NewDataFlag1 = 0;
unsigned int Serial1TimeOut = 0;

String String2;
String inputString2 = "";         // строка для хранения входящих данных
boolean NewDataFlag2 = 0;
unsigned int Serial2TimeOut = 0;

String String3;
String inputString3 = "";         // строка для хранения входящих данных
boolean NewDataFlag3 = 0;
unsigned int Serial3TimeOut = 0;

void timerIsr()
{
  serial1Event();
  serial2Event();
  serial3Event();


  if (Serial1TimeOut > 0)Serial1TimeOut--;
  if (Serial1TimeOut == 0 && NewDataFlag1 == 1)
  {
    String1 = inputString1;
    inputString1 = "";
    NewDataFlag1 = 0;
  }

  if (Serial2TimeOut > 0)Serial2TimeOut--;
  if (Serial2TimeOut == 0 && NewDataFlag2 == 1)
  {
    String2 = inputString2;
    inputString2 = "";
    NewDataFlag2 = 0;
  }

  if (Serial3TimeOut > 0)Serial3TimeOut--;
  if (Serial3TimeOut == 0 && NewDataFlag3 == 1)
  {
    String3 = inputString3;
    inputString3 = "";
    NewDataFlag3 = 0;
  }

}


void setup() {

  Timer1.initialize(5000); // Время события таймера
  Timer1.attachInterrupt( timerIsr );

  Serial.println("Sonay di nathli");


  //======================================== SD-карта ===== ================================================== //
  // Serial.println("Инициализация SD-карты...");

  // смотрим, нет ли карты:
  if (!SD.begin(chipSelect)) {
    // Serial.println("Сбой карты или ее отсутствие");
    // больше ничего не делаем:
    return;
  }
  // Serial.println("SD-карта готова");

  //=============================================== ====== RTC ========================================== ==//
  if (!rtc.begin())
  {
    // Serial.println("Не удалось найти RTC");
    Serial.flush();
    abort();
  }

  if (!rtc.isrunning()) {
    // Serial.println("RTC НЕ запущен, установим время!");
    rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
  }

  //=============================================== Выбор скорости OLED ============================================== =====//
  pinMode(Up, INPUT_PULLUP);
  pinMode(Dn, INPUT_PULLUP);
  pinMode(Mnu, INPUT_PULLUP);

  unsigned char bdindx = EEPROM.read(0);
  if (bdindx > 3) bdindx = 0;
  if (bdindx == 0) CurrentBaudRate = 4800;
  if (bdindx == 1) CurrentBaudRate = 9600;
  if (bdindx == 2) CurrentBaudRate = 19200;
  if (bdindx == 3) CurrentBaudRate = 115200;
  delay (500);

  while (!Serial) { }// ждем подключения последовательного порта
  pinMode(LED_BUILTIN, OUTPUT);
  Serial.begin(CurrentBaudRate);
  Serial1.begin(CurrentBaudRate);
  Serial2.begin(CurrentBaudRate);
  Serial3.begin(CurrentBaudRate);
  Serial.println(CurrentBaudRate);
  delay (1000);

  display.begin(SSD1306_SWITCHCAPVCC, SCREEN_ADDRESS);
  display.clearDisplay();
  display.setTextSize(1);             // Обычный масштаб пикселя 1:1
  display.setTextColor(SSD1306_WHITE);        // Рисуем белый текст
  display.display();

}

String String1A, String1B, String1C, String1D, String1E, String1F;
String String2A, String2B, String2C, String2D, String2E, String2F;
String String3A, String3B, String3C, String3D, String3E, String3F;
int CR1A, CR1B, CR1C, CR1D, CR1E, CR1F;
int CR2A, CR2B, CR2C, CR2D, CR2E, CR2F;
int CR3A, CR3B, CR3C, CR3D, CR3E, CR3F;


// =========================================== Отображение скорости передачи данных экран (позиция) ===========================================//

void DrawBaudRate(unsigned long BdRt)
{
  unsigned char Xoffset = 0;
  if (BdRt >= 0 && BdRt < 10000) Xoffset = 37;
  if (BdRt >= 10000 && BdRt < 100000) Xoffset = 30;
  if (BdRt >= 100000 ) Xoffset = 25;
  // display.drawRect(0,0,128,64,SSD1306_WHITE);
  // display.setTextSize(2);
  // display.setCursor(15,10);
  // display.println("Скорость передачи");
  // display.setTextSize(2);
  // display.setCursor(15,10);
  // display.println(tm);
  // display.setCursor(Xoffset,37);// 6 цифр
  // display.println(BdRt);
  // дисплей.дисплей();
  // delay(10);
}

// =============================================== == Выбор скорости передачи данных ========================================== =============//
unsigned long SelectBaudRate(unsigned long BdRt)
{
  unsigned char BdRtIndx = 0;
  unsigned int FlashCnt = 0;

  if (BdRt == 4800) BdRtIndx = 0;
  if (BdRt == 9600) BdRtIndx = 1;
  if (BdRt == 19200) BdRtIndx = 2;
  if (BdRt == 115200) BdRtIndx = 3;

  unsigned char Xoffset = 0;
  if (BdRt >= 0 && BdRt < 10000) Xoffset = 37;
  if (BdRt >= 10000 && BdRt < 100000) Xoffset = 30;
  if (BdRt >= 100000 ) Xoffset = 25;
  display.drawRect(0, 0, 128, 64, SSD1306_WHITE);
  display.setTextSize(1);
  display.setCursor(15, 10); display.println("Select Baudrate");
  display.setCursor(15, 20); display.println("by Up/Dn Buttons");
  display.setTextSize(2);
  display.setCursor(Xoffset, 37); // 6 цифр
  display.println(BdRt);
  display.display();
  delay(10);

  while (digitalRead(Mnu) == 0) delay(10);
  delay(100);


  while (digitalRead(Mnu) == 1)
  {
    delay(10);
    FlashCnt++;

    if (digitalRead(Up) == 0)
    {
      if (BdRtIndx < 3) BdRtIndx++;
    }


    if (digitalRead(Dn) == 0)
    {
      if (BdRtIndx > 0) BdRtIndx--;
    }

    if (BdRtIndx == 0) BdRt = 4800;
    if (BdRtIndx == 1) BdRt = 9600;
    if (BdRtIndx == 2) BdRt = 19200;
    if (BdRtIndx == 3) BdRt = 115200;

    if (BdRt >= 0 && BdRt < 10000) Xoffset = 37;
    if (BdRt >= 10000 && BdRt < 100000) Xoffset = 30;
    if (BdRt >= 100000 ) Xoffset = 25;
    display.clearDisplay();
    display.drawRect(0, 0, 128, 64, SSD1306_WHITE);
    display.setTextSize(1);
    display.setCursor(15, 10); display.println("Select Baudrate");
    display.setCursor(15, 20); display.println("by Up/Dn Buttons");
    display.setTextSize(2);
    display.setCursor(Xoffset, 37); // 6 цифр
    if (FlashCnt > 1) display.println(BdRt);
    if (FlashCnt > 2) FlashCnt = 0;
    display.display();
    delay(250);

    //пока(digitalRead(Up)==0 || digitalRead(Dn)==0) delay(10);
  }
  while (digitalRead(Mnu) == 0) delay(10);

  display.clearDisplay();
  display.drawRect(0, 0, 128, 64, SSD1306_WHITE);
  display.setTextSize(2);
  display.setCursor(20, 10); display.println("Saving");
  display.setCursor(20, 35); display.println("Changes");
  display.display();
  delay(2000);

  EEPROM.write(0, BdRtIndx);


  return (BdRt);


}

//=============================================== === OLED, показывающий время =========================================== ===//
char Time[]     = "  :  :  ";
byte i, second, minute, hour;

void DS3231_display() {
  // Преобразование BCD в десятичное число
  second = (second >> 4) * 10 + (second & 0x0F);
  minute = (minute >> 4) * 10 + (minute & 0x0F);
  hour   = (hour >> 4)   * 10 + (hour & 0x0F);
  // Конец преобразования

  Time[7]     = second % 10 + 48;
  Time[6]     = second / 10 + 48;
  Time[4]     = minute % 10 + 48;
  Time[3]     = minute / 10 + 48;
  Time[1]     = hour   % 10 + 48;
  Time[0]     = hour   / 10 + 48;
  display.drawRect(0, 0, 128, 64, SSD1306_WHITE);
  draw_text(16, 25, Time, 2);                         // Отображение времени
}

void blink_parameter() {
  byte j = 1;
  while (j < 10 && digitalRead(Up) && digitalRead(Dn)) {
    j++;
    delay(25);
  }
}

byte edit(byte x_pos, byte y_pos, byte parameter) {
  char text[3];
  sprintf(text, "%02u", parameter);
  while (!digitalRead(Up));                     // Ждем, пока кнопка B1 не будет отпущена
  while (true) {
    while (!digitalRead(Dn)) {                  // Если нажата кнопка B2
      display.clearDisplay();
      parameter++;
      if (i == 0 && parameter > 23)                  // Если часы > 23 ==> часы = 0
        parameter = 0;
      if (i == 1 && parameter > 59)                  // Если минуты > 59 ==> минуты = 0
        parameter = 0;
      sprintf(text, "%02u", parameter);
      draw_text(x_pos, y_pos, text, 2);
      delay(200);                                    // Подождать 200 мс
    }
    display.drawRect(0, 0, 128, 64, SSD1306_WHITE);
    draw_text(x_pos, y_pos, "  ", 2);
    blink_parameter();
    draw_text(x_pos, y_pos, text, 2);
    blink_parameter();
    if (!digitalRead(Up)) {                     // Если нажата кнопка B1
      i++;                                           // Увеличение 'i' для следующего параметра
      // display.clearDisplay();

      return parameter;                              // Возвращаем значение параметра и выходим
    }
  }
}

void draw_text(byte x_pos, byte y_pos, char *text, byte text_size) {
  display.setCursor(x_pos, y_pos);
  display.setTextSize(text_size);
  display.print(text);
  display.display();
}

//---------------------------------------------
void loop() {

  // ======================================== Время редактирования и отображение на OLED = ==========================================//
  if (!digitalRead(Up)) {                       // Если нажата кнопка B1
    i = 0;
    while (!digitalRead(Up));                   // Дождаться отпускания кнопки B1

    hour   = edit(16, 25, hour);                     // Редактировать часы
    minute = edit(52, 25, minute);                   // Редактировать минуты

    // Преобразование десятичного числа в двоично-десятичное
    minute = ((minute / 10) << 4) + (minute % 10);
    hour = ((hour / 10) << 4) + (hour % 10);
    // Конец преобразования

    // Запись данных в DS3231 RTC
    Wire.beginTransmission(0x68);               // Запустить протокол I2C с адресом DS3231
    Wire.write(0);                              // Отправляем регистрационный адрес
    Wire.write(0);                              // Сбросить секунды и запустить осциллятор
    Wire.write(minute);                         // Запись минуты
    Wire.write(hour);                           // Запись часа
    Wire.endTransmission();                     // Остановить передачу и освободить шину I2C
    delay(200);                                 // Подождать 200 мс
  }

  Wire.beginTransmission(0x68);                 // Запустить протокол I2C с адресом DS3231
  Wire.write(0);                                // Отправляем регистрационный адрес
  Wire.endTransmission(false);                  // перезапуск I2C
  Wire.requestFrom(0x68, 7);                    // Запрос 7 байт от DS3231 и освобождение шины I2C в конце чтения
  second = Wire.read();                         // Чтение секунд из регистра 0
  minute = Wire.read();                         // Чтение минут из регистра 1
  hour   = Wire.read();                         // Чтение часа из регистра 2
  Wire.beginTransmission(0x68);                 // Запустить протокол I2C с адресом DS3231
  Wire.write(0x11);                             // Отправляем регистрационный адрес
  Wire.endTransmission(false);                  // перезапуск I2C
  Wire.requestFrom(0x68, 2);                    // Запросить 2 байта у DS3231 и освободить шину I2C в конце чтения
  DS3231_display();                             // Время показа & календарь

  delay(50);                                    // Подождем 50 мс

  { display.clearDisplay();
    if (digitalRead(Mnu) == 0) CurrentBaudRate = SelectBaudRate(CurrentBaudRate);
    // DrawBaudRate(CurrentBaudRate);
    delay(10);

    x++;
    if (x > 123456) x = 0;
  }

  // ======================================= Чтение даты и времени из RTC === =========================================//
  DateTime now = rtc.now();
  char dt[16];
  char tm[16];
  char buffer [16];
  uint8_t thisSec, thisMin, thisHour;
  thisSec = now.second();
  thisMin = now.minute();
  thisHour = now.hour();
  sprintf(dt, "%02d-%02d-%02d", now.year(), now.month(), now.day());
  sprintf(tm, "%02d%02d%02d", now.hour(), now.minute(), now.second());
  sprintf (buffer, "%02d:%02d:%02d", thisHour, thisMin, thisSec);
  msec = millis() % 1000; // ИСПОЛЬЗОВАТЬ ПОСЛЕДНИЕ 3 ЦИФРЫ МИЛЛИСА ARDUINO

  //SERIAL_PORT_1

// если (string1Complete)
  { Serial.print (String1);
// CR1A = String1.indexOf(13); // находит местоположение первого
// String1A = String1.substring(0, CR1A + 2); // захватывает первую строку данных
// CR1B = String1.indexOf(13, CR1A + 2); // находит местоположение секунды,
// String1B = String1.substring(CR1A, CR1B + 2); // захватывает вторую строку данных
// CR1C = String1.indexOf(13, CR1B + 2);
// String1C = String1.substring(CR1B, CR1C + 2);
// CR1D = String1.indexOf(13, CR1C + 2);
// String1D = String1.substring(CR1C, CR1D + 2);
// CR1E = String1.indexOf(13, CR1D + 2);
// String1E = String1.substring(CR1D, CR1E + 2);
// CR1F = String1.indexOf(13, CR1E + 2);
// String1F = String1.substring(CR1E, CR1F + 2);
//
// strID = (String1A.substring(0, 5));
// если (strID == "$GPGG") {
// Serial.println(String1);
// }
// strID = (String1B.substring(0, 5));
// если (strID == "$GPVT") {
// Serial.println(String1B);
// }
// strID = (String1C.substring(0, 5));
// если (strID == "$GPZD") {
// Serial.println(String1C);
// }
// strID = (String1D.substring(0, 5));
// если (strID == "$GPGL") {
// Serial.println(String1D);
// }
// strID = (String1E.substring(0, 5));
// если (strID == "$GPGN") {
// Serial.println(String1E);
// }
// strID = (String1F.substring(0, 5));
// если (strID == "$GPGR") {
// Serial.println(String1F);
// }
// strID = (String1.substring(0, 2));
// если (strID == "$") {
      File dataFile = SD.open("GPS1.txt", FILE_WRITE);
      // если файл доступен, пишем в него:

      strID = (String1A.substring(0, 5));
      if (strID == "$GPGG") {
        dataFile.print(dt);
        dataFile.print(" ");
        dataFile.print(tm);
        dataFile.print(msec);
        dataFile.print(",");
        dataFile.print(String1);
        Serial.print (String1);
        String1 = "";
        Serial.print (String1);
        dataFile.close();
      }
// }
// strID = (String1D.substring(4, 6));
// if (strID == "TG" || "DA" || "LL" || "NS" || "RS") {
// dataFile.print(String1B);
// String1B = "";
// }
// strID = (String1C.substring(4, 6));
// if (strID == "TG" || "DA" || "LL" || "NS" || "RS") {
// dataFile.print(String1C);
// String1C = "";
// }
// strID = (String1D.substring(4, 6));
// if (strID == "TG" || "DA" || "LL" || "NS" || "RS") {
// dataFile.print(String1D);
// String1D = "";
// }
// strID = (String1E.substring(4, 6));
// if (strID == "TG" || "DA" || "LL" || "NS" || "RS") {
// файл данных.print(String1E);
// String1E = "";
// }
// strID = (String1F.substring(4, 6));
// if (strID == "TG" || "DA" || "LL" || "NS" || "RS") {
// dataFile.print(String1F);
// String1F = "";
// }
      
// }
    else {
      File dataFile = SD.open("ES2.txt", FILE_WRITE);

      if (dataFile) {
        dataFile.print(dt);
        dataFile.print(" ");
        dataFile.print(tm);
        dataFile.print(msec);
        dataFile.print(",");
        dataFile.println(String1);
        Serial.print (String1);
// dataFile.println(String1B);
        String1A = "";
        String1B = "";
        dataFile.close();
      }
    }
// }
  string1Complete = false;
  }
  
}


//------------------------------------------------ -------------------------------------------------- ---------------

void serial1Event() {
  while (Serial1.available()) {
    char inChar1 = (char)Serial1.read();
    inputString1 += inChar1;
    Serial1TimeOut = RxTimeOut;
    NewDataFlag1 = 1;

    if (NewDataFlag1 == 1) {
      string1Complete = true;
    }

  }
}

, 👍0

Обсуждение

Вы никогда не проверяете, что indexOf() находит '\r'. Почему вы пытаетесь обрабатывать пять сообщений одновременно, а не одно за другим?, @Edgar Bonet

Предоставьте более подробное описание того, какие данные сообщения у вас есть в этой строке, какой ошибочный вывод вы получаете и где в коде это происходит., @chrisl

Если (strID == "TG" || "DA" || "LL" || "NS" ... то это бред, @SBF

Я предоставлю вам свою полную программу. На самом деле между предложениями нет задержки, поэтому, когда процессор записывает одно предложение на SD-карту, приходит 2-е сообщение, и большую часть времени он сохраняет глюк на SD-карте., @Omar Rai

Если вам интересно, "DA", "LL" и "NS" все [правдивы](https://en.wikipedia.org/wiki/Truth_value#Computing) в C++. Итак, упомянутая выше ерунда функционально эквивалентна if (true)., @timemage

@OmarRai, просто чтобы прояснить, вы хотите использовать ссылку «редактировать» под своим вопросом, чтобы добавить дополнительные детали к вопросу. Если вы хотите, чтобы люди задавали вам вопросы, вы хотите «Добавить комментарий». Единственный раз, когда вы собираетесь «Опубликовать свой ответ», это если вам удалось решить нашу собственную проблему., @timemage


1 ответ


1

Я не знаю, какое отношение “частоты” имеют к вашей проблеме, но я бы поспорил, что вы получите более надежные результаты, если справитесь с одной из них NMEA предложение за раз, вместо того, чтобы пытаться справиться с шестью из них сразу и надеяться получить правильные.

Ниже приведена функция, которая обрабатывает по одному полному предложению за раз. Он записывает предложение в SD-файл, если его тип относится к списку “интересных” типов, которые вы хотите отслеживать:

// Типы предложений, которые должны быть записаны.
const char monitoredTypes[6][4] = {
    "GGA", "VTG", "ZDA", "GLL", "GNS", "GRS"
};

// Обработайте полное, завершенное CRLF предложение NMEA.
void processSentence(String &sentence) {

    // Sanity check.
    if (sentence.substring(0, 3) != "$GP") {
        Serial.print("WARNING: invalid sentence: ");
        Serial.print(sentence);
        return;
    }

    // Record the sentence if it has an interesting type.
    String type = sentence.substring(3, 6);
    for (int i = 0; i < 6; i++) {
        if (type == monitoredTypes[i]) {
            File dataFile = SD.open("GPS1.txt", FILE_WRITE);
            if (type == "GGA") {  // этот тип кажется особенным
                dataFile.print(dt);
                dataFile.print(" ");
                dataFile.print(tm);
                dataFile.print(msec);
                dataFile.print(",");
            }
            dataFile.print(sentence);
            dataFile.close();
        }
    }
}

Способ его использования состоит в том, чтобы буферизировать входящие символы до тех пор, пока вы не получите полное предложение (обозначенное окончательным LF), а затем отправьте этот буфер в эту функцию:

String buffer;

void loop() {
    while (Serial.available() > 0) {
        char c = Serial.read();
        buffer += c;

        // В конце предложения обработайте и очистите буфер.
        if (c == '\n') {
            processSentence(buffer);
            buffer = "";
        }
    }
}

Обратите внимание, что для того, чтобы избавиться от строки, не потребуется слишком много работы класс и вместо этого используйте простые строки C. Простые строки гораздо более удобны для памяти.

,