printf只显示24个字符的char *

时间:2016-10-18 09:33:46

标签: c string printf malloc

我正在做一个创建一个浏览互联网的机器人的项目。

我必须用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

2 个答案:

答案 0 :(得分:1)

主要问题是:

line = malloc(sizeof(*line));

这只会将单个字符分配给line。表达式*linechar,表示您分配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以释放堆上分配的内存。