简体   繁体   English

解析4个单字节的ip地址字符串

[英]parsing ip adress string in 4 single bytes

I'm programming on a MCU with C and I need to parse a null-terminated string which contains an IP address into 4 single bytes. 我在使用C编程的MCU上进行编程,我需要解析一个以空字符结尾的字符串,该字符串包含4个单字节的IP地址。 I made an example with C++: 我用C ++做了一个例子:

#include <iostream>
int main()
{
    char *str = "192.168.0.1\0";
    while (*str != '\0')
    {
            if (*str == '.')
            {
                    *str++;
                    std::cout << std::endl;
            }
            std::cout << *str;
            *str++;
    }
    std::cout << std::endl;
    return 0;
}

This code prints 192, 168, 0 and 1 each byte in a new line. 此代码在新行中打印192,168,0和1每个字节。 Now I need each byte in a single char, like char byte1, byte2, byte3 and byte4 where byte1 contains 1 and byte4 contains 192... or in a struct IP_ADDR and return that struct then, but I dont know how to do it in C. :( 现在我需要一个char中的每个字节,比如char byte1,byte2,byte3和byte4,其中byte1包含1,byte4包含192 ...或者在结构IP_ADDR中然后返回该结构,但我不知道如何在C。 :(

You can do it character-by-character, as does the C++ version in your question. 你可以逐个字符地完成它,就像你问题中的C ++版本一样。

/* ERROR CHECKING MISSING */
#include <ctype.h>
#include <stdio.h>
int main(void) {
    char *str = "192.168.0.1", *str2;
    unsigned char value[4] = {0};
    size_t index = 0;

    str2 = str; /* save the pointer */
    while (*str) {
        if (isdigit((unsigned char)*str)) {
            value[index] *= 10;
            value[index] += *str - '0';
        } else {
            index++;
        }
        str++;
    }
    printf("values in \"%s\": %d %d %d %d\n", str2,
              value[0], value[1], value[2], value[3]);
    return 0;
}
for(int i = 0, r = 0; i < 4; str += r + 1, i++) {
  sscanf(str, "%d%n", &b[i], &r);
}

or 要么

 sscanf(str, "%d.%d.%d.%d", b, b + 1, b + 2, b + 3);

I'd like to provide more strict version for parsing ipv4 address 我想为解析ipv4地址提供更严格的版本

typedef struct ipv4_type {
    uint8_t data[4];
} ipv4;

ipv4_error ipv4_parse ( const uint8_t * string, uint8_t string_length, ipv4 * result )
{
    bool at_least_one_symbol = false;
    uint8_t symbol, string_index = 0, result_index = 0;
    uint16_t data = 0;
    while ( string_index < string_length ) {
        symbol = string[string_index];
        if ( isdigit ( symbol ) != 0 ) {
            symbol -= '0';
            data   = data * 10 + symbol;
            if ( data > UINT8_MAX ) {
                // 127.0.0.256
                return ERROR_IPV4_DATA_OVERFLOW;
            }
            at_least_one_symbol = true;
        } else if ( symbol == '.' ) {
            if ( result_index < 3 ) {
                if ( at_least_one_symbol ) {
                    result->data[result_index] = data;
                    data = 0;
                    result_index ++;
                    at_least_one_symbol = false;
                } else {
                    // 127.0..1
                    return ERROR_IPV4_NO_SYMBOL;
                }
            } else {
                // 127.0.0.1.2
                return ERROR_IPV4_INPUT_OVERFLOW;
            }
        } else {
            // 127.*
            return ERROR_IPV4_INVALID_SYMBOL;
        }
        string_index ++;
    }
    if ( result_index == 3 ) {
        if ( at_least_one_symbol ) {
            result->data[result_index] = data;
            return 0;
        } else {
            // 127.0.0.
            return ERROR_IPV4_NOT_ENOUGH_INPUT;
        }
    } else {
        // result_index will be always less than 3
        // 127.0
        return ERROR_IPV4_NOT_ENOUGH_INPUT;
    }
}

a nice way to do this in C is to use the string tokenizer. 在C中执行此操作的一种好方法是使用字符串标记生成器。 In the example code below the bytes are saved in the bytes array and are also printed with the printf function. 在下面的示例代码中,字节保存在bytes数组中,并且还使用printf函数打印。 Hope it helps 希望能帮助到你

#include <string.h>

int main()
{
    char str[] = "192.168.0.1";
    unsigned char bytes[4];
    int i = 0;

    char* buff = malloc(10);
    buff = strtok(str,".");
    while (buff != NULL)
    {
       //if you want to print its value
       printf("%s\n",buff);
       //and also if you want to save each byte
       bytes[i] = (unsigned char)atoi(buff);
       buff = strtok(NULL,".");
       i++;
    }
    free(buff);
    return 0;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM