Разбор, хранение и чтение строк в C - PullRequest
0 голосов
/ 24 октября 2011

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

Сначала я запустил его в консоли, и все заработало как положено. Функции для команд тестирования в main () следующие:

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    //$GPSACP: 200949.000,4603.9172N,01429.5821E,1.0,337.8,3,53.82,0.36,0.19,231011,06


    char *get_substring(size_t start, size_t stop, const char *src, char *dst, size_t size)
    {
        int count = stop - start;
       if ( count >= --size )
       {
          count = size;
       }
       sprintf(dst, "%.*s", count, src + start);
       return dst;
    }

    void get_separator_position(char *input_string, int *separators_array, int separators_count)
    {
        //10 separators
        char *separator = ",";
        char *current_string = input_string;
        int current = 0;
        char *found;
        int pos;
        int cur_pos = 0;
        for(current = 0; current < separators_count; current++)
        {
                found = strstr(current_string, separator);
                if(found != NULL)
                {
                     pos = found - current_string;
                     cur_pos += pos;
                     separators_array[current] = cur_pos + current;
                     current_string = &input_string[cur_pos + 1 + current];


                }
                else
                {
                    //printf("Not found!\n");
                }
        }
    }

    void parse_nmea_string(char *nmea_string, char *utc, char *latitude, char *longitude, char *hdop, char *altitude, char *fix, char *cog, char *spkm, char *spkn, char *date, char *nsat)
    {
         //10 separators "," in NMEA sentence
         int separators_array[10];
         get_separator_position(nmea_string, &separators_array[0], 10);
         int length = strlen(nmea_string);
         utc = get_substring(9, separators_array[0] + 1, nmea_string, utc, sizeof(char) * (separators_array[0] - 9 + 1));
         latitude = get_substring(separators_array[0] + 1, separators_array[1], nmea_string, latitude, sizeof(char) * (separators_array[1] - separators_array[0]));
         longitude = get_substring(separators_array[1] + 1, separators_array[2], nmea_string, longitude, sizeof(char) * (separators_array[2] - separators_array[1]));
         hdop = get_substring(separators_array[2] + 1, separators_array[3], nmea_string, hdop, sizeof(char) * (separators_array[3] - separators_array[2]));
         altitude = get_substring(separators_array[3] + 1, separators_array[4], nmea_string, altitude, sizeof(char) * (separators_array[4] - separators_array[3]));
         fix = get_substring(separators_array[4] + 1, separators_array[5], nmea_string, fix, sizeof(char) * (separators_array[5] - separators_array[4]));
         cog = get_substring(separators_array[5] + 1, separators_array[6], nmea_string, cog, sizeof(char) * (separators_array[6] - separators_array[5]));
         spkm = get_substring(separators_array[6] + 1, separators_array[7], nmea_string, spkm, sizeof(char) * (separators_array[7] - separators_array[6]));
         spkn = get_substring(separators_array[7] + 1, separators_array[8], nmea_string, spkn, sizeof(char) * (separators_array[8] - separators_array[7]));
         date = get_substring(separators_array[8] + 1, separators_array[9], nmea_string, date, sizeof(char) * (separators_array[9] - separators_array[8]));
         nsat = get_substring(separators_array[9] + 1, length, nmea_string, nsat, sizeof(char) * (length - separators_array[9]));
    }

    int main(int argc, char *argv[])
    {


static const char text[] = "$GPSACP: 200949.000,4603.9172N,01429.5821E,1.0,337.8,3,53.82,0.36,0.19,231011,06";
    char utc[20];
      char latitude[30];
      char longitude[20];
      char hdop[20];
      char altitude[20];
      char fix[20];
      char cog[20];
      char spkm[20];
      char spkn[20];
      char date[20];
      char nsat[20];
      printf("Separator %d at position %d\n", pos, separators_array[pos]);
      parse_nmea_string(text, utc, latitude, longitude, hdop, altitude, fix, cog, spkm, spkn, date, nsat);
      printf("UTC: %s\n", utc);
      system("PAUSE");  
      return 0;
    }

Этот код работает нормально, и результат теста равен

UTC: 200949.000

Затем я попытался использовать вышеуказанную функцию в проекте микроконтроллера и записать значения массива, используя существующую функцию debug_str (), которая выглядит следующим образом:

// Debug function prints string msg to UART1 (to PC) 
void debug_str(const char* msg)
{
#ifdef debug
    putchar1(0x24);   //$
    while(*msg) 
    {
       putchar1(*msg++);    
    }
    putchar1(0x0D); //Carriage Return
#endif
}

Таким образом, комбинируя функции синтаксического анализа с существующим кодом, я попытался записать значения массива следующим образом:

char UTC[15];
char latitude[15]; 
char longitude[15];
char hdop[6];
char altitude[9];
char fix[5];
char cog[10];
char spkm[8];
char spkn[8];
char date[10];
char nsat[6];

static const char nmea_test[] = "$GPSACP: 200949.000,4603.9172N,01429.5821E,1.0,337.8,3,53.82,0.36,0.19,231011,06";
    ...

    parse_nmea_string(nmea_test, UTC, latitude, longitude, hdop, altitude, fix, cog, spkm, spkn, date, nsat); 
    debug_str(latitude);

Но таким образом вывод был неверным.

Выход:

$*s

Кто-нибудь знает, в чем проблема и как правильно сохранить и записать на выход параметры, которые анализируются из строки nmea_test?

Спасибо!

Ответы [ 2 ]

0 голосов
/ 24 октября 2011

Теперь это работает.Функции get_substring и get_separator_positions пришлось изменить следующим образом:

char *get_substring(unsigned int start, unsigned int stop, const char *src, char *dst, unsigned int size)
{
    int count = stop - start;
    if ( count >= --size )
    {
      count = size;
    }
  // sprintf(dst, "%.*s", count, src + start); - this line was replaced by the following two lines (the microcontroller does not support strdup so strncpy had to be used)

    strncpy(dst, &src[start], size);
    dst[size] = '\n';
   return dst;
}


//char input_string[] = "$GPSACP: 200949.000,4603.9172N,01429.5821E,1.0,337.8,3,53.82,0.36,0.19,231011,06";

void get_separator_position(char *input_string, int *separators_array, int separators_count)
{
    //10 separators
    char separator[] = ",";//char *separator = "," didn't work
    char *current_string = input_string;
    int current = 0;
    char *found;
    int pos;
    int cur_pos = 0;

    //char tmp_pos[10];

    for(current = 0; current < separators_count; current++)
    {
            found = strstr(current_string, separator);
            if(found != NULL)
            {
                 debug_str("found!");
                 //debug_str(found);
                 pos = found - current_string;

//                 itoa(pos,tmp_pos);
//                 debug_str(tmp_pos);
                 cur_pos += pos;

                 separators_array[current] = cur_pos + current;
                 current_string = &input_string[cur_pos + 1 + current];
            }
            else
            {
                debug_str("Not found!");
            }
    }
}
0 голосов
/ 24 октября 2011

Вы должны понимать разницу между массивами и указателями в C. Прочитайте любой хороший учебник C об этом.

Ваша get_substring функция не делает то, что вы ожидаете. Он не выделяет никакой строки для своего результата.

Вы можете рассмотреть возможность использования strdup внутри get_substring и принять соглашение, согласно которому вызывающая сторона должна free получить результат.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...