簡體   English   中英

來自fgets()的分段錯誤

[英]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 , '/') ,因為strchrbuf中返回一個指針。 (並且由於同時使用兩次strchrbuf在此期間沒有改變,你應該將它的返回值放在char *pos = strchr(buf, '/');變量中,並使用pos代替,以避免反復打電話給strchr

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM