![](/img/trans.png)
[英]Function that return a list of IP addresses for a given IP adress and subnetmask
[英]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
。那么請您嘗試以下方法:
#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
ip
被分成一個數組octet
,每個長度為 i、j、k 和 l。octet
中的每個子字符串都以空字符結尾。octet
的每個元素都滿足條件,則將它們連接成一個 IP 地址字符串。*ptr
是一個動態增長的二維數組。*ptr
的值在generate()
函數中被修改,指向ans
的指針被傳遞給該函數。cnt
也是按地址傳遞的。 只要有替代方案,不建議使用全局地址。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.