我在文本文件中有一个url列表,我正在尝试将它们保存在主机和页面的结构中。我遇到了这个代码的问题。它返回 sigsegv 。有什么想法吗?
char buf[100];
.......
while ( fgets ( buf, 100, fin ) != NULL )
{
buf [ strlen (buf) - 1 ] = '\0';
informatii.intrari++;
informatii.urluri[informatii.intrari-1].status=-1;
printf("BUFFER: %s\n", buf);
if( strncmp ("http://",buf,7) == 0 )
memmove (buf, buf+7, strlen (buf));
if( strncmp("https://",buf,8) == 0 )
memmove (buf, buf+8, strlen (buf));
printf("BUFFER: %s\n", buf);
if ( strchr ( buf , '/' ) == NULL)
{
strcpy ( informatii.urluri [ informatii.intrari - 1 ].host, buf);
strcpy ( informatii.urluri [ informatii.intrari - 1 ].page, "/");
}
else
{
memmove ( informatii.urluri [ informatii.intrari - 1 ].page,
buf+(strchr ( buf , '/' )-buf),
strlen(buf) );
}
memset(buf , 0 , 100 );
}
编辑来自OP评论的结构
struct urlinfo
{
unsigned short status;
char* serror;
char host[100];
char page[100];
};
struct informati
{
int intrari;
int time;
char* email;
struct urlinfo urluri[50];
} informatii;
结束编辑
编辑:在你的一些建议之后,我设法让它发挥作用,但有一些我不明白的事情。 这是最终的代码。
`struct urlinfo
{
unsigned short status;
char* serror;
char host[100];
char page[100];
};
struct informati
{
int intrari;
int time;
char* email;
struct urlinfo urluri [MAX_URLS];
}informatii;
int configurare(char* fisier)//citim si memoram fisierul de configurare
{
FILE* fin;
char buf[100];
char* temp;
int i;
if((fin = fopen(fisier,"r")) == NULL)//verificam fisierul de intrare
{
printf("Eroare la fisierul de configurare.Se va folosi fisierul default configurare.txt.\n");
fin = fopen("configurare.txt","r");
}
informatii.intrari = 0;
informatii.time = 30;
informatii.email = NULL;`
while ( fgets ( buf, 100, fin ) != NULL )
{
//buf [ strlen (buf) - 1 ] = '\0';
if (informatii.intrari >= 50) {
printf("URLs overflow...!\n");
break;}
informatii.urluri[ informatii.intrari ].status=-1;
informatii.urluri[ informatii.intrari ].serror= NULL;
if( strncmp ("http://",buf,7) == 0 )
memmove (buf, buf+7, strlen (buf) );
if( strncmp("https://",buf,8) == 0 )
memmove (buf, buf+8, strlen (buf) );
temp = strchr ( buf , '/' );
if ( temp == NULL)
{
memcpy ( informatii.urluri [ informatii.intrari ].host, buf,strlen(buf)+1);
strncpy ( informatii.urluri [ informatii.intrari ].page, "/\0",2);
}
else
{
memcpy ( informatii.urluri [ informatii.intrari ].host, buf,strlen(buf)-strlen(temp));
memmove ( informatii.urluri [ informatii.intrari ].page, temp, strlen(temp));
}
informatii.intrari++;
memset(buf , '\0' , 100 );
}
}
fclose(fin);
return 0;
}`
如果我使用这个buf [ strlen (buf) - 1 ] = '\0';
来删除trayling'\ n',当我使用printf时,字符串中的第一个字符不会打印出来(例如,如果我有printf(“Buf%s”, buf)它将打印“uf”然后打印buf字符串。
如果尝试再次使用if( strncmp ("http://",buf,7) == 0 )
memmove (buf, buf+7, strlen (buf) -7 );
我有一个错误的返回字符串,字符串末尾的某些字母将被复制到字符串中的'\ n'字符之后。
答案 0 :(得分:0)
除了WhozCraig的相关评论( buf 在其空间之外阅读)之外,我没有看到任何方法来阻止循环存储超过50个URL。如果读取的URL超过50个,则 urluri 数组会溢出并且堆可能已损坏。其结果可能是 fin 文件描述符(更可能是它的指针)被改变,导致 fgets 中的 sigsev 。
您可以轻松确保阅读50个或更少的网址,然后将其添加为第一条指令
while ( fgets ( buf, 100, fin ) != NULL )
{
if (informatii.intrari >= 50) {
printf("URLs overflow...!\n");
break;
}
在之前的某个地方informatii.intrari
初始化为0
吗?
顺便说一句,你可以抓住机会命名常数50
#define MAX_URLS 50
并在程序中使用MAX_URLS
而不是50。
另外,你可以把
informatii.intrari ++;
在 while 的末尾,因此在循环中使用[informatii.intrari]
代替[informatii.intrari - 1]
。
buf+(strchr ( buf , '/' )-buf)
是strchr ( buf , '/')
,因为 strchr 会在 buf 中返回一个指针。 (并且因为同时使用 strchr 两次而 buf 没有改变,所以你应该将它的返回值放在char *pos = strchr(buf, '/');
变量中,并使用 pos ,以避免重复调用 strchr 。