Ubuntu下C语言读取DNS文件对应IP时出现段错误的问题问询
问题:C程序在Ubuntu下触发Segmentation fault,Windows下运行正常
我在名为DNS.txt的文本文件中存储了若干网站名称及其对应的随机IP地址,用C语言编写了程序查找特定网站的对应IP。程序在Windows下运行正常,但在Ubuntu执行时抛出错误:
Segmentation fault (core dumped)
我的实现逻辑是逐字符检查网站是否存在,找到后将读取指针停在网站最后一个字符处,跳过一个字符后把剩余字符存入ip数组。程序代码如下:
#include<stdio.h> #include<stdlib.h> #include<string.h> int main() { // Write C code here FILE* ptr = fopen("DNS.txt","r"); int found=0, i=0; char website[20] = "google.com"; char ip[30]; char temp; while ((temp=fgetc(ptr)) != EOF){ if (temp == website[i]){ i++; if (i==strlen(website)){ found = 1; break; } } else i=0; } if (found){ i=0; temp = fgetc(ptr); temp=fgetc(ptr); while (temp != '\n'){ ip[i++]=temp; temp=fgetc(ptr); } ip[i] = '\0'; printf("%s",ip); } else{ printf("Ip address not found"); } return 0; }
DNS.txt文件内容如下:
google.com-1234.45.6 youtube.com-5738.292.22 github.com-2374.2342.2
文件与程序存放在同一目录下。
问题原因分析
- 未检查文件打开状态:
fopen在Ubuntu下若无法找到文件(比如权限问题、路径匹配问题)会返回NULL,后续直接用fgetc(ptr)操作空指针会触发段错误。Windows下的文件系统特性可能掩盖了这个问题,但Ubuntu对空指针操作的检查更严格。 - EOF处理逻辑缺失:找到网站后,若后续读取直接到文件末尾(比如文件格式异常),
while (temp != '\n')会进入无限循环,导致ip数组越界写入,触发段错误。 fgetc返回值类型错误:fgetc返回int类型(包含EOF的-1),用char存储会导致EOF判断失效(无符号char会把-1转为255),进而引发错误的循环逻辑。- 换行符差异:Windows换行是
\r\n,Ubuntu是\n,原代码中连续两次调用fgetc跳过字符的逻辑,在Ubuntu下可能跳过了IP的起始字符,甚至直接读到EOF。
修复后的代码
#include<stdio.h> #include<stdlib.h> #include<string.h> int main() { FILE* ptr = fopen("DNS.txt","r"); // 检查文件是否成功打开 if (!ptr) { perror("Failed to open file"); return EXIT_FAILURE; } int found = 0, i = 0; char website[20] = "google.com"; char ip[30]; int website_len = strlen(website); int c; // 用int存储fgetc返回值,兼容EOF判断 while ((c = fgetc(ptr)) != EOF) { if ((char)c == website[i]) { i++; if (i == website_len) { found = 1; break; } } else { i = 0; } } if (found) { i = 0; // 跳过分隔符'-',先检查是否到文件末尾 if ((c = fgetc(ptr)) == EOF) { printf("Invalid file format\n"); fclose(ptr); return EXIT_FAILURE; } // 读取IP直到换行或EOF,同时防止数组越界 while ((c = fgetc(ptr)) != EOF && (char)c != '\n') { if (i < sizeof(ip)-1) { ip[i++] = (char)c; } else { printf("IP exceeds maximum length\n"); break; } } ip[i] = '\0'; printf("%s\n", ip); } else { printf("IP address not found\n"); } fclose(ptr); // 关闭文件,避免资源泄漏 return EXIT_SUCCESS; }
关键修复点
- 添加文件打开校验:判断
ptr是否为NULL,用perror输出具体错误原因,避免空指针操作。 - 正确存储
fgetc返回值:用int类型存储返回值,确保EOF判断准确。 - 处理边界情况:读取IP前检查是否到文件末尾,避免无限循环;写入
ip数组时限制索引范围,防止越界。 - 规范文件操作:程序结束前关闭打开的文件,避免资源泄漏。
内容的提问来源于stack exchange,提问作者Dhanaseelan V
相关产品推荐
相关产品推荐

