[英]Segmentation Fault from fgets()
我在文本文件中有一個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評論的EDIT結構
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'字符后面。
除了WhozCraig的相關評論( buf在其空間外閱讀)之外,我沒有看到任何方法來阻止循環存儲超過50個URL。 如果讀取的URL超過50個,則urluri數組會溢出並且堆可能已損壞。 結果可能是fin文件描述符(更可能是它的指針)被改變,導致fgets中的sigsev 。
您可以輕松確保讀取50個或更少的URL,並將其作為第一條指令添加
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 ++;
線在同時結束,因此利用[informatii.intrari]
代替[informatii.intrari - 1]
中循環。
而且buf+(strchr ( buf , '/' )-buf)
是strchr ( buf , '/')
,因為strchr在buf中返回一個指針。 (並且由於同時使用兩次strchr而buf在此期間沒有改變,你應該將它的返回值放在char *pos = strchr(buf, '/');
變量中,並使用pos代替,以避免反復打電話給strchr 。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.