Write a program that determines where to add periods to a decimal string so that the resulting string is a valid IP address. There may be more than one valid IP address corresponding to a string, in which case you should print all possibilities. 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. There are also seven other possible IP addresses for this string.
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. 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
.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.octet
is terminated with a null character. octet
meet the condition, they are concatenated into an ip address string.*ptr
is a 2-d array which grows on the fly. *ptr
is modified within the generate()
function, a pointer to ans
is passed to the function.cnt
is also passed by address. It is not recommended to use a global address as long as there are alternatives.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.