简体   繁体   English

从给定字符串生成所有 IP 地址

[英]Generate all ip addresses from given string

Write a program that determines where to add periods to a decimal string so that the resulting string is a valid IP address.编写一个程序,确定在十进制字符串中添加句点的位置,以便生成的字符串是有效的 IP 地址。 There may be more than one valid IP address corresponding to a string, in which case you should print all possibilities.可能有多个有效的 IP 地址对应于一个字符串,在这种情况下,您应该打印所有可能性。 Additionally your program must validate that neither group must not exceed 255. For example: If the mangled string is “19216811” then two corresponding IP addresses are 192.168.1.1 and 192.216.81.1.此外,您的程序必须验证两个组都不得超过 255。例如:如果损坏的字符串是“19216811”,那么两个对应的 IP 地址是 192.168.1.1 和 192.216.81.1。 There are also seven other possible IP addresses for this string.此字符串还有其他七个可能的 IP 地址。

My program is causin segmentationn fault我的程序导致分段错误

My Code:我的代码:

#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);
}
  • As the input string str contains a trailing newline character, strlen(str) is larger than the intended value.由于输入字符串str包含尾随换行符,因此strlen(str)大于预期值。 You need to chop the newline character off.您需要切断换行符。
  • Your is_valid_part() function is very close but you need to change part[0] != 0 to part[0] != '0' to examine the leading 0 .您的is_valid_part()函数非常接近,但您需要将part[0] != 0更改为part[0] != '0'以检查前导0
  • If you want to create a list of ip addresses at runtime, you need to allocate memory area with malloc/realloc and free the area after use.如果你想在运行时创建一个ip地址列表,你需要用malloc/realloc分配内存区域,并在使用后释放该区域。

Then would you please try the following:那么请您尝试以下方法:

#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);
}

Output:输出:

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
  • Integer values i, j, k and l are generated such that each value is between 1 and 3 inclusive and the sum equals to strlen(ip).整数值 i、j、k 和 l 的生成使得每个值都介于 1 和 3 之间,并且总和等于 strlen(ip)。
  • Then the string ip is divided into an array octet , each of length i, j, k and l.然后字符串ip被分成一个数组octet ,每个长度为 i、j、k 和 l。
  • Each substring in octet is terminated with a null character. octet中的每个子字符串都以空字符结尾。
  • If every elements of octet meet the condition, they are concatenated into an ip address string.如果octet的每个元素都满足条件,则将它们连接成一个 IP 地址字符串。
  • *ptr is a 2-d array which grows on the fly. *ptr是一个动态增长的二维数组。
  • As the value of *ptr is modified within the generate() function, a pointer to ans is passed to the function.由于*ptr的值在generate()函数中被修改,指向ans的指针被传递给该函数。
  • The counter cnt is also passed by address.计数器cnt也是按地址传递的。 It is not recommended to use a global address as long as there are alternatives.只要有替代方案,不建议使用全局地址。

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

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