如何用fscanf获取指定URL的PageRank?排查代码段错误
从PageRank文件中获取指定URL的PageRank值
需求说明
我有一个名为pageRankList.txt的文件,每行内容按URL、出站链接数、PageRank值的顺序排列,示例内容如下:
url23 4 0.0405449 url31 3 0.0371111 url22 5 0.0300785 url34 4 0.0288782 url21 2 0.0247087 url11 3 0.0235192 url32 2 0.0227647
需要实现一个函数,输入指定URL后返回对应的PageRank值。我自己写了一段代码,但运行时出现未知地址的段错误(SEGV),无法定位原因,代码如下:
static double getPageRank(char *url) { double pageRank = 0; FILE *fp = fopen("pageRankList.txt", "r"); char str[1000]; int counter = 0; while (fscanf(fp, " %98s", str) != EOF) { if (strcmp(url, str) == 0) { counter++; continue; } if (counter == 2) { pageRank = atof(str); printf("%f ", pageRank); break; } } fclose(fp); return pageRank; }
问题分析
你的代码出现段错误及逻辑问题的原因如下:
- 未检查文件打开状态:如果
pageRankList.txt不存在、路径错误或无读取权限,fopen会返回NULL,后续调用fscanf操作空指针会直接触发段错误。 - 逻辑错误:代码逐个读取文件中的每个字符串(token),找到目标URL后仅将
counter加1,但后续读取的出站链接数字符串不会触发counter增长,永远无法满足counter == 2的条件,导致循环要么持续到文件结束,要么在过程中出现异常。 - 语法错误:
printf中的换行符写法错误(printf("%f ", pageRank);),会导致编译或运行时问题。
正确实现方案
直接按照文件每行的三个字段格式读取,逻辑更清晰且避免错误,代码如下:
static double getPageRank(char *url) { double pageRank = 0.0; // 打开文件并检查是否成功 FILE *fp = fopen("pageRankList.txt", "r"); if (!fp) { fprintf(stderr, "无法打开pageRankList.txt文件\n"); return pageRank; } char currentUrl[100]; int outLinks; double currentPR; // 按格式读取每行的三个字段,成功读取3个字段时进入循环 while (fscanf(fp, "%s %d %lf", currentUrl, &outLinks, ¤tPR) == 3) { // 匹配目标URL if (strcmp(url, currentUrl) == 0) { pageRank = currentPR; break; // 找到后立即退出循环,提升效率 } } fclose(fp); return pageRank; }
方案优势
- 空指针防护:检查
fopen的返回值,避免空指针操作导致的段错误。 - 逻辑清晰:直接对应文件的每行格式读取三个字段,无需手动计数token,避免逻辑混乱。
- 效率更高:找到目标URL后立即退出循环,无需遍历整个文件。
内容的提问来源于stack exchange,提问作者FreeAntiVirus
相关产品推荐
相关产品推荐

