简体   繁体   中英

The last character is not printed to a file

I am trying to figure out why using C function strtok is not working properly for me. Here's the problem: I have a file which contains two types of information: headers and text descriptions. Each line in the file is either a header or part of a text description. A header starts with '>'. The description text follows the header and can span multiple lines. At the end of the text there is an empty line which separates the description from the next header. My aim is to write two separate files: one contains the headers on each line and the other contains the corresponding description on a line by itself. To implement the codes in C, I used fgets to read the file one line at a time into dynamically allocated memory. In order to write the description text on one single line, I used `strtok to get rid of any new line characters exists in the text.

My code is working properly for the header files. However, for the descriptions file, I noticed that the last character of the text is not printed out to the file even though it is printed to the stdout.

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);

}

As mentioned in the comments:

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

Second line should be:

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

Or, you could do this:

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

Other possible issues :
Without an input file it is not possible to know for certain what strtok() is doing, but here is a guess based on what you have described:

In these two lines :

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

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

if the string contained in data2 has any embedded spaces, s will only contain the segment occurring before that space. And because you are only calling it once before line gets refreshed:

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

only one token (the very first segment) will be read.

Not always, but Normally , strtok() is called in a loop:

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
}

But, as I said above, you are calling it only once on that string before the content of the string is changed. It is possible then, that the segment not printing has simply not yet been tokenized by strtok() .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM