簡體   English   中英

從給定字符串生成所有 IP 地址

[英]Generate all ip addresses from given string

編寫一個程序,確定在十進制字符串中添加句點的位置,以便生成的字符串是有效的 IP 地址。 可能有多個有效的 IP 地址對應於一個字符串,在這種情況下,您應該打印所有可能性。 此外,您的程序必須驗證兩個組都不得超過 255。例如:如果損壞的字符串是“19216811”,那么兩個對應的 IP 地址是 192.168.1.1 和 192.216.81.1。 此字符串還有其他七個可能的 IP 地址。

我的程序導致分段錯誤

我的代碼:

#include<stdio.h>
#include <string.h>
#include<stdbool.h>
#include<stdlib.h>


bool is_valid_part(char *part) {
  return (strlen(part)== 1) || (part[0] != 0 && atoi(part) <= 255);
}
int a =0;
int pos = 0;
void generate(char *ip, char **ans)
{
    int l = strlen(ip);
 
    // Check for string size
    if (l > 12 || l < 4) {
        printf("Not valid IP String");
        return;
    }
 
    char *check = ip;
 
    // Generating different combinations.
    for (int i = 1; i < l - 2; i++) {
        for (int j = i + 1; j < l - 1; j++) {
            for (int k = j + 1; k < l; k++) {
                check =  strncpy(check, ip, k); + '.'+ strncpy(check, ip + k, strlen(ip) - k - 1);
                check = strncpy(check, ip, j); + '.'+ strncpy(check, ip + j, strlen(ip) - j - 1);
                check= strncpy(check, ip, i); + '.'+ strncpy(check, ip + i, strlen(ip) - i - 1); 
                if (is_valid_part(check)) {
                    ans[pos++] = check;
                    printf("%s", check);
                }
                check = ip;
            }
        }
    }
}
int main(void){
    char str[32];
    fgets(str, 32, stdin);
    printf("%s",str);
    char **ans;
    generate(str, ans);
}
  • 由於輸入字符串str包含尾隨換行符,因此strlen(str)大於預期值。 您需要切斷換行符。
  • 您的is_valid_part()函數非常接近,但您需要將part[0] != 0更改為part[0] != '0'以檢查前導0
  • 如果你想在運行時創建一個ip地址列表,你需要用malloc/realloc分配內存區域,並在使用后釋放該區域。

那么請您嘗試以下方法:

#include <stdio.h>
#include <string.h>
#include <stdbool.h>
#include <stdlib.h>
#include <ctype.h>

bool is_valid_part(char *part) {
    return (strlen(part) == 1) || (part[0] != '0' && atoi(part) <= 255);
}

void generate(char *ip, char ***ptr, int *pos)
{
    int len = strlen(ip);
    char octet[4][4];
    char addr[16];

    // check for string size
    if (len > 12 || len < 4) {
        printf("The length must be between 4 and 12\n");
        return;
    }
    // check characters
    for (int i = 0; i < len; i++) {
        if (! isdigit(ip[i])) {
            printf("Invalid character: %c\n", ip[i]);
            return;
        }
    }

    // generating different combinations.
    for (int i = 1; i <= 3; i++) {
        for (int j = 1; j <= 3; j++) {
            for (int k = 1; k <= 3; k++) {
                int l = len - i - j - k;
                if (l < 1 || l > 3) continue;
                strncpy(octet[0], ip, i); *(octet[0] + i) = '\0';
                strncpy(octet[1], ip + i, j); *(octet[1] + j) = '\0';
                strncpy(octet[2], ip + i + j, k); *(octet[2] + k) = '\0';
                strncpy(octet[3], ip + i + j + k, l); *(octet[3] + l) = '\0';

                int fail = 0;
                for (int m = 0; m < 4; m++) {
                    if (! is_valid_part(octet[m])) fail = 1;
                }
                if (fail) continue;     // skip to next combination

                // generate a string of ip address
                strcpy(addr, octet[0]);
                for (int m = 1; m < 4; m++) {
                    strcat(addr, ".");
                    strcat(addr, octet[m]);
                }

//              printf("%s\n", addr);
                // allocate memory and append the string to the list
                *ptr = realloc(*ptr, (*pos + 1) * sizeof(char **));
                (*ptr)[*pos] = malloc(strlen(addr) + 1);
                strcpy((*ptr)[*pos], addr);
                (*pos)++;               // increment the count of ip addresses
            }
        }
    }
}

int main(void) {
    char str[BUFSIZ];
    printf("Enter a decimal string: ");
    fgets(str, BUFSIZ, stdin);
    char *p = rindex(str, '\n');        // trim the newline character
    if (p) *p = '\0';
    p = rindex(str, '\r');              // trim the carrage return character
    if (p) *p = '\0';

//  printf("%s\n", str);
    char **ans = NULL;                  // array of ip address strings
    int cnt = 0;                        // counter of the ip addresses
    generate(str, &ans, &cnt);

    // print the results
    for (int i = 0; i < cnt; i++) {
        printf("%s\n", ans[i]);
    }

    // free memory
    for (int i = 0; i < cnt; i++) {
        free(ans[i]);
    }
    free(ans);
}

輸出:

Enter a decimal string: 19216811
1.92.168.11
19.2.168.11
19.21.68.11
19.216.8.11
19.216.81.1
192.1.68.11
192.16.8.11
192.16.81.1
192.168.1.1
  • 整數值 i、j、k 和 l 的生成使得每個值都介於 1 和 3 之間,並且總和等於 strlen(ip)。
  • 然后字符串ip被分成一個數組octet ,每個長度為 i、j、k 和 l。
  • octet中的每個子字符串都以空字符結尾。
  • 如果octet的每個元素都滿足條件,則將它們連接成一個 IP 地址字符串。
  • *ptr是一個動態增長的二維數組。
  • 由於*ptr的值在generate()函數中被修改,指向ans的指針被傳遞給該函數。
  • 計數器cnt也是按地址傳遞的。 只要有替代方案,不建議使用全局地址。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM