我正在做一个创建一个浏览互联网的机器人的项目。
我必须用C编写代码,现在我专注于选择要去的地址(从文件中的列表中选择)。这可以正常工作,但是当我显示机器人选择的地址时,有些被截断为24个字符并以“!”结尾。这使代码无法使用长地址。有没有人知道它可能会来到哪里?
该计划:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>
#include <math.h>
int main() {
FILE* file = fopen("test.txt", "r+");
char *line = NULL;
char *tab[1023];
int tailleTab = 0;
line = malloc(sizeof(*line));
if(line == NULL)
return(EXIT_FAILURE);
while((fgets(line, 1023, file)) != NULL ) {
if(line[0] != '#' && line[0] != '\n') {
tab[tailleTab] = line;
line = malloc(sizeof(*line));
tailleTab++;
}
}
srand(time(NULL));
int n = rand()%tailleTab;
printf("\n%d = %.32s\n", n, tab[n]);
printf("%s\n", tab[n]);
fclose(file);
}
选择地址的文件:
www.google.com
www.wikipedia.org
www.dahunicorn.xyz
www.cloudimperiumgames.com
www.robertspaceindustries.com
www.candybox2.net
www.42.com
www.1337.com
答案 0 :(得分:1)
主要问题是:
line = malloc(sizeof(*line));
这只会将单个字符分配给line
。表达式*line
是char
,表示您分配sizeof(char)
字节,sizeof(char)
定义为始终为1
。
这意味着您对fgets
的调用将写出已分配内存的界限,您将有未定义的行为。
没有理由动态地实际分配line
。而是将其创建为数组,然后在strdup
数组中保存时使用tab
。要么是这个,要么分配更多的内存(1023
是一个很好的数字,因为你传递给fgets
的数量。)
答案 1 :(得分:0)
正如在另一个答案中已经解释的那样,使用以下代码:
line = malloc(sizeof(*line));
您在堆上使用malloc
一个char
进行分配,因为表达式*line
等同于char
(因为line
被声明为char *
)。
我会使用命名常量来简化你的代码,而不是通过代码传播的{em>魔术数(如1023
)(并且使其更难维护),此外只需为其预留空间堆栈上的临时line
缓冲区,而不是在堆上动态分配它,例如:
/* Instead of: line = malloc(sizeof(*line)); */
#define LINE_MAX_SIZE 1024
char line[LINE_MAX_SIZE];
还要考虑做:
#define TAB_MAX_ITEMS /* 1023 or whatever */
char* tab[TAB_MAX_ITEMS];
在while
循环中,请考虑使用LINE_MAX_SIZE
代替幻数1023
:
while ((fgets(line, LINE_MAX_SIZE, file)) != NULL ) {
您可能还想在tab
数组中的索引中添加一个检查,以避免缓冲区溢出:
if (tailleTab >= TAB_MAX_ITEMS) {
/* Index out of range */
...
}
/* tailleTab is a valid index.
* Deep-copy the line read in the temporary buffer
* and save a pointer to the copy into the tab array.
*/
tab[tailleTab] = strdup(line);
在生产代码中,您还应该遍历存储在tab
数组中的指针,并在它们上调用free
以释放堆上分配的内存。