字符串解析,存储和读取C语言

时间:2011-10-24 11:09:51

标签: c arrays pointers

我写了一个函数来解析一个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 :(得分:0)

你应该理解C中数组和指针之间的区别。 阅读任何关于此的优秀C教科书。

您的get_substring功能无法达到您的预期效果。它没有为其结果分配任何字符串。

您可以考虑在strdup中使用get_substring,并采用调用者应该free结果的约定。

答案 1 :(得分:0)

现在它有效。函数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!");
            }
    }
}