C 链表解析中的分段错误
我有一个程序,可以解析和RSS提要到一个链接列表中C 链表解析中的分段错误,c,parsing,segmentation-fault,C,Parsing,Segmentation Fault,我有一个程序,可以解析和RSS提要到一个链接列表中 #include"util.h" #include<stdio.h> #include<stdlib.h> #include<sys/stat.h> #include<string.h> void parse_tc(){ struct node *head = NULL; char *bytes = 0; struct stat st; stat("techc
#include"util.h"
#include<stdio.h>
#include<stdlib.h>
#include<sys/stat.h>
#include<string.h>
void parse_tc(){
struct node *head = NULL;
char *bytes = 0;
struct stat st;
stat("techcrunch.txt", &st);
int size = st.st_size;
FILE *f = fopen("techcrunch.txt", "rb");
bytes = (char*)malloc(size + 1);
size_t nread = fread(bytes,1,size,f);
bytes[nread] = 0;
fclose(f);
struct node *temp = (struct node*)malloc(sizeof(struct node));
temp->position = 1;
printf("%d. ", temp->position);
char *a = title_parser_tc(bytes,temp);
head = temp;
for(int i = 2; i<21; i++){
temp = (struct node*)malloc(sizeof(struct node));
temp->position = i;
printf("%d. ", temp->position);
a = title_parser_tc(a, temp);
struct node* temp1 = head;
while(temp1->link != NULL)
{
temp1 = temp1->link;
}
temp1->link = temp;
}
free(bytes);
int holder = 0;
int check = 0;
do {
printf("Enter a number: ");
scanf("%d", &holder);
if(holder<1 || holder > 20){
puts("Invalid input");
check = 1;
}
else{
check = 0;
}
} while(check);
get_feed(holder, head);
}
char* title_parser_tc(char *bytes, struct node *temp){
char *ptr = strstr(bytes, "<title>");
if (ptr) {
ptr += 7;
char *ptr2 = strstr(ptr, "</title>");
if (ptr2) {
char* output = malloc(ptr2 - ptr + 1);
memcpy(output, ptr, ptr2 - ptr);
output[ptr2 - ptr] = 0;
if(strcmp(output,"TechCrunch")!=0){
temp->title = output;
puts(temp->title);
temp->link = NULL;free(output);
char *load = pubdate_parser_tc(ptr2, temp);
return load;
}
else{
char *load = title_parser_tc(ptr2, temp);
free(output);
return load;
}
}
}
return NULL;
}
char* pubdate_parser_tc(char *bytes, struct node *temp){
char *ptr = strstr(bytes, "<pubDate>");
if (ptr) {
ptr += 9;
char *ptr2 = strstr(ptr, "</pubDate>");
if (ptr2) {
char* output = malloc(ptr2 - ptr + 1);
memcpy(output, ptr, ptr2 - ptr);
output[ptr2 - ptr] = 0;
temp->pubdate = output;
free(output);
char *load = description_parser_tc(ptr2, temp);
return load;
}
}
return NULL;
}
char* description_parser_tc(char *bytes, struct node *temp){
char *ptr = strstr(bytes, "<description>");
if (ptr) {
ptr += 13;
char *ptr2 = strstr(ptr, "</description>");
if (ptr2){
char* output = malloc(ptr2 - ptr + 1);
memcpy(output, ptr, ptr2 - ptr);
output[ptr2 - ptr] = 0;
description_cleaner_tc(output, temp);
free(output);
char *load = url_parser_tc(ptr2, temp);
return load;
}
}
return NULL;
}
void description_cleaner_tc(char *bytes, struct node *temp){
char *ptr = strstr(bytes, "&nbsp;");
if (ptr) {
ptr += 10;
char *ptr2 = strstr(ptr, "<a ");
if (ptr2) {
char* output = malloc(ptr2 - ptr + 1);
memcpy(output, ptr, ptr2 - ptr);
output[ptr2 - ptr] = 0;
temp->description = output;
puts(temp->description);
free(output);
}
}
}
char* url_parser_tc(char *bytes, struct node *temp){
char *ptr = strstr(bytes, "href");
if (ptr) {
ptr += 6;
char *ptr2 = strstr(ptr, ">");
if (ptr2) {
char* output = (char*)malloc(ptr2 - ptr);
memcpy(output, ptr, ptr2 - ptr - 1);
output[ptr2 - ptr - 1] = 0;
temp->url = output;
puts(temp->pubdate);
puts(temp->url);
puts("");
free(output);
return ptr2;
}
}
return NULL;
}
#包括“util.h”
#包括
#包括
#包括
#包括
void parse_tc(){
结构节点*head=NULL;
字符*字节=0;
结构统计;
stat(“techcrunch.txt”和&st);
int size=st.st\u size;
文件*f=fopen(“techcrunch.txt”、“rb”);
字节=(字符*)malloc(大小+1);
size\u t nread=fread(字节,1,大小,f);
字节[nread]=0;
fclose(f);
结构节点*temp=(结构节点*)malloc(sizeof(结构节点));
温度->位置=1;
printf(“%d.”,温度->位置);
char*a=标题\u解析器\u tc(字节,临时);
压头=温度;
对于(int i=2;i位置=i;
printf(“%d.”,温度->位置);
a=标题\u解析器\u tc(a,临时);
结构节点*temp1=头部;
while(temp1->link!=NULL)
{
temp1=temp1->link;
}
temp1->link=temp;
}
空闲(字节);
int holder=0;
整数检查=0;
做{
printf(“输入一个数字:”);
scanf(“%d”、&holder);
if(支架20){
puts(“无效输入”);
检查=1;
}
否则{
检查=0;
}
}while(检查);
获取_进给(支架、头部);
}
char*title\u parser\u tc(char*字节,结构节点*temp){
char*ptr=strstrstr(字节,“”);
如果(ptr){
ptr+=7;
char*ptr2=strstrstr(ptr,“”);
如果(ptr2){
char*output=malloc(ptr2-ptr+1);
memcpy(输出、ptr、ptr2-ptr);
输出[ptr2-ptr]=0;
如果(strcmp(输出,“TechCrunch”)!=0){
温度->标题=输出;
放置(临时->标题);
临时->链接=空;自由(输出);
char*load=pubdate\u parser\u tc(ptr2,temp);
返回载荷;
}
否则{
char*load=标题\u解析器\u tc(ptr2,temp);
自由(输出);
返回载荷;
}
}
}
返回NULL;
}
char*pubdate\u解析器\u tc(char*字节,结构节点*temp){
char*ptr=strstrstr(字节,“”);
如果(ptr){
ptr+=9;
char*ptr2=strstrstr(ptr,“”);
如果(ptr2){
char*output=malloc(ptr2-ptr+1);
memcpy(输出、ptr、ptr2-ptr);
输出[ptr2-ptr]=0;
temp->pubdate=输出;
自由(输出);
char*load=描述\u解析器\u tc(ptr2,temp);
返回载荷;
}
}
返回NULL;
}
char*说明\u解析器\u tc(char*字节,结构节点*temp){
char*ptr=strstrstr(字节,“”);
如果(ptr){
ptr+=13;
char*ptr2=strstrstr(ptr,“”);
如果(ptr2){
char*output=malloc(ptr2-ptr+1);
memcpy(输出、ptr、ptr2-ptr);
输出[ptr2-ptr]=0;
说明\u清洁剂\u tc(输出、温度);
自由(输出);
char*load=url\u解析器\u tc(ptr2,temp);
返回载荷;
}
}
返回NULL;
}
void description\u cleaner\u tc(字符*字节,结构节点*临时){
char*ptr=strstrstr(字节,”);
如果(ptr){
ptr+=10;
char*ptr2=strstrstr(ptr,“a”);
如果(ptr2){
char*output=malloc(ptr2-ptr+1);
memcpy(输出、ptr、ptr2-ptr);
输出[ptr2-ptr]=0;
温度->说明=输出;
放置(临时->说明);
自由(输出);
}
}
}
char*url\u解析器\u tc(char*字节,结构节点*temp){
char*ptr=strstrstr(字节,“href”);
如果(ptr){
ptr+=6;
char*ptr2=strstrstr(ptr,“”);
如果(ptr2){
字符*输出=(字符*)malloc(ptr2-ptr);
memcpy(输出,ptr,ptr2-ptr-1);
输出[ptr2-ptr-1]=0;
temp->url=输出;
放置(临时->发布日期);
放置(临时->url);
认沽权(“”);
自由(输出);
返回ptr2;
}
}
返回NULL;
}
我的问题是,对于这个文件textcrunch.txt
,我的程序在parse_tc()
的第10个循环中出现了一个分段错误。该程序适用于另一个文件,但这个文件给了我一个错误。有解决方案吗
代码基本上是为要分析的不同字符串重复的相同函数。分段错误通常意味着取消对空指针(或指向未初始化内存的指针)的引用。如果使用GCC或Clang,则可以使用
-g
标志重新编译,并通过gdb
运行结果程序:
gdb --args ....
r
bt
第一行启动gdb,按照通常的运行方式提供您的命令。
r
启动运行,bt
从程序因分段错误而停止的点开始提供回溯。至少这会提供出现问题的代码位置。您可以使用print语句或添加一些def开始进一步调试ensive coding there.Hmmmchar*ptr=strstrstr(bytes,“href”);…ptr+=6;
。为什么是6?如果程序可以为另一个文件工作,但此文件给我一个错误
,那么您需要提供一个有效文件的内容和一个无效文件的内容,以便我们可以自己尝试。否则,我们可能会选择一个有效的文件。(int i=2;i如果您的程序接收到格式错误的HTML或跨多行的标记,会发生什么情况?我还将使您的标记为常量,并将它们转换为strlen()