最后一个字符不会打印到文件中

时间:2014-11-25 14:32:15

标签: c

我想弄清楚为什么使用C函数strtok对我不起作用。这是问题所在: 我有一个文件,其中包含两种类型的信息:标题和文本说明。文件中的每一行都是标题或文本描述的一部分。标头以“>”开头。描述文本在标题后面,可以跨越多行。在文本的末尾有一个空行,用于将描述与下一个标题分开。我的目标是编写两个单独的文件:一个包含每行的标题,另一个包含一行的相应描述。为了在C中实现代码,我使用fgets一次一行地将文件读入动态分配的内存。为了在一行中编写描述文本,我使用`strtok来删除文本中存在的任何新行字符。

我的代码适用于头文件。但是,对于描述文件,我注意到文本的最后一个字符未打印到文件,即使它已打印到标准输出。

FILE *headerFile = fopen("Headers", "w"); //to write headers
FILE *desFile = fopen("Descriptions", "w"); //to write descriptions

FILE *pfile = fopen("Data","r");

if ( pfile != NULL )
{

  int numOfHeaders =0;

  char **data1 = NULL; //an array to hold a header line
  char **data2 = NULL; //an array to hold a description line 
  char line[700] ; //maximum size for the line

  while (fgets(line, sizeof line, pfile ))
  {

      if(line[0] =='>') //It is a header
      {
          data1 = realloc(data1,(numOfHeaders +1)* sizeof(*data1));
          data1[numOfHeaders]= malloc(strlen(line)+1);
          strcpy(data1[numOfHeaders],line);

          fprintf(headerFile, "%s",line);//writes the header

          if(numOfHeaders >0)
            fprintf(desFile, "\n");//writes a new line in the desc file

          numOfHeaders++;              
      }

      //it is not a header and not an empty line
      if(line[0] != '>' && strlen(line)>2)
      {
          data2 = realloc(data2,(numOfHeaders +1)* sizeof(*data2));
          data2[numOfHeaders]= malloc(strlen(line)+1);

          char *s  = strtok(line, "\n ");              
          strcpy(data2[numOfHeaders],s);

          fprintf(desFile, "%s",data2[numOfHeaders]);              
          printf(desFile, "%s",data2[numOfHeaders]);
       }

  } //end-while
  fclose(desFile);
  fclose(headerFile);
  fclose(pfile );

  printf("There are %d headers in the file.\n",numOfHeaders);

}

1 个答案:

答案 0 :(得分:0)

如评论中所述:

  fprintf(desFile, "%s",data2[numOfHeaders]);  //okay            
  printf(desFile, "%s",data2[numOfHeaders]);  //wrong  

第二行应该是:

  printf("%s",data2[numOfHeaders]);  //okay

或者,你可以这样做:

  sprintf(buffer, "%s",data2[numOfHeaders]);
  fprintf(desFile, buffer);
  printf(buffer);    

其他可能的问题
如果没有输入文件,就无法确定strtok()正在做什么,但这是根据您所描述的内容进行的猜测:

在这两行中

  data2[numOfHeaders]= malloc(strlen(line)+1);

  char *s  = strtok(line, "\n ");          

如果data2中包含的字符串包含任何嵌入空格, s 将仅包含在该空格之前出现的段。并且因为您只是在 刷新之前只调用一次:

while (fgets(line, sizeof line, pfile ))  

只会读取一个令牌(第一个段)。

并非总是如此,但 通常 ,在循环中调用strtok()

char *s = {0};
s= strtok(stringToParse, "\n ");//make initial call before entering loop
while(s)//ALWAYS test to see if s contains new content, else NULL
{
    //do something with s
    strcpy(data2[numOfHeaders],s);
    //get next token from string
    s = strtok(NULL, "\n ");//continue to tokenize string until s is null
}

但是,正如我上面所说,在字符串的内容发生变化之前,你只在该字符串上调用一次。那么,有可能strtok()尚未对尚未打印的段进行标记化。