2

我正在使用 C 语言在 MCU 上编程,我需要将包含 IP 地址的以空字符结尾的字符串解析为 4 个单字节。我用 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;
}

此代码在新行中的每个字节打印 192、168、0 和 1。现在我需要单个 char 中的每个字节,例如 char byte1、byte2、byte3 和 byte4,其中 byte1 包含 1,byte4 包含 192... C。 :(

4

4 回答 4

4

您可以逐个字符地执行此操作,就像您问题中的 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;
}
于 2012-02-09T14:22:32.853 回答
2
for(int i = 0, r = 0; i < 4; str += r + 1, i++) {
  sscanf(str, "%d%n", &b[i], &r);
}

或者

 sscanf(str, "%d.%d.%d.%d", b, b + 1, b + 2, b + 3);
于 2012-02-09T13:24:12.117 回答
1

在 C 中执行此操作的一个好方法是使用字符串标记器。在下面的示例代码中,字节保存在字节数组中,并且还使用 printf 函数打印。希望能帮助到你

#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;
}
于 2012-02-09T13:31:40.487 回答
1

我想为解析 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;
    }
}
于 2014-12-30T10:35:30.347 回答