我在一个文本文件中有一个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;
}`


如果我在使用printf时使用此buf [ strlen (buf) - 1 ] = '\0';来删除托盘'\ n',则不打印字符串中的第一个字符(例如,如果我有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文件描述符(更可能是其指针)被更改,从而导致fget中出现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 ++;

在while的最后一行,因此在循环中使用[informatii.intrari]代替[informatii.intrari - 1]
并且buf+(strchr ( buf , '/' )-buf)strchr ( buf , '/'),因为strchr在buf内部返回了一个指针。 (并且由于同一strchr被使用了两次,而buf同时没有变化,因此您应该将其返回值放在char *pos = strchr(buf, '/');变量中,并改用pos,以避免重复调用strchr。

关于c - 来自fgets()的段错误,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/14421389/

10-13 23:12