[英]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);
}
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.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
。 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
ip
is divided into an array octet
, each of length i, j, k and l.ip
被分成一个数组octet
,每个长度为 i、j、k 和 l。octet
is terminated with a null character. octet
中的每个子字符串都以空字符结尾。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
是一个动态增长的二维数组。*ptr
is modified within the generate()
function, a pointer to ans
is passed to the function.*ptr
的值在generate()
函数中被修改,指向ans
的指针被传递给该函数。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.