gpt4 book ai didi

c - 来自 fgets() 的段错误

转载 作者:行者123 更新时间:2023-12-04 12:26:02 25 4
gpt4 key购买 nike

我在一个文本文件中有一个 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'; 以便在我以某种方式使用 printf 时删除 trayling '\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 文件描述符(更可能是它的指针)被更改,导致 fgets 中的 sigsev

  • 一个确保您阅读 50 个或更少 URL 的方法很容易被阅读,同时添加作为第一条指令

    while ( fgets ( buf, 100, fin ) != NULL )
    {
    if (informatii.intrari >= 50) {
    printf("URLs overflow...!\n");
    break;
    }
  • informatii.intrari 是否在 while 之前的某处初始化为 0

  • 顺便说一下常数50的名字

    #define MAX_URLS  50

    并在程序中使用 MAX_URLS 而不是 50。

  • 此外,您可以将

    informatii.intrari++;

    行在 while 的末尾,因此在循环。

  • 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/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com