开发者

C - How to write linked list pointer contents to a text file

I have a program that has an array of pointers such as:

INTLIST* myArray[countOfRows];

each myArray pointer points to a linked list, basically it becomes an M*N matrix.

So for example:

3 2 1
2 1 0
1 9 8

So myArray[0] is a linked list with 3->2->1 and myArray[1] is a linked list with 2->1->0.. and so on. I have a function that prints the matrix which basically does this:

for(int i = 0; i<countOfRows; i++)
   list_print(myArray[i]);

And then my list_print function is like so:

 void list_print(INTLIST* list)
  { /* This function simply prints the linked list out */
     INTLIST* temp=NULL;  //temp pointer to head of list

     /* loops through each node of list printing its datum value */
     for(temp=list; temp!=NULL; temp=temp->next)
        {
           printf("%d ", temp->datum);         //print datum value
        }
     printf("\n");
  }

This is all great and working fine, (I know i could optimize and clean up and I promise to do so). Now my next question is I need to write this matrix out to a text file. So I tried this:

 char* outputFileName = "out.txt";
 FILE* ofp;

 ofp=fopen(outputFileName, "w");

 if(ofp == NULL) 
 {
    开发者_开发问答    printf("Cannot open writeable file!");
        return -1;
 }

 for(i=0; i<fileLineCount; i++)
  {
     fprintf(ofp, list_print(aList[i]);
  } 

But I take it its not that simple. Can anyone show me how to print this out to a text file...

Thanks


Use the fprintf function in your list_print function using a FILE * parameter as shown in the example:

void list_print(INTLIST* list, FILE *fp)
  { /* This function simply prints the linked list out */
     INTLIST* temp=NULL;  //temp pointer to head of list

     /* loops through each node of list printing its datum value */
     for(temp=list; temp!=NULL; temp=temp->;next)
        {
           fprintf(fp, "%d ", temp->datum);         //print datum value
        }
     fprintf(fp, "\n");
  }

Would be done like this:

int main(){
   FILE *fp;
   fp = fopen("data.txt", "w");
   for(i=0; i<fileLineCount; i++)
   {
      list_print(alist[i], fp);
   }
   fclose(fp);
}

Or

If you wish to retain the binary dump of the linked list from memory to disk (this is the simple way of explaining it), top off my head:

for(i=0; i<fileLineCount; i++)
{
     fwrite(alist[i], sizeof(alist[i]), 1, ofp);
}

Then when reading from it,

for(i=0; i<fileLineCount; i++)
{
     fread(&alist[i], sizeof(alist[i]), 1, ofp);
}

Edit: I was hesitant to include the above, but paxdiablo pointed out a flaw in my fread(...) and fwrite(...) code above, and realized he is right. When doing the binary write of the linked list, the memory addresses references in the linked-list will be invalid when read in the next time. Thanks paxdiablo!


You can't use printf function to write to file. You need to replace all printf calls with fprintf and pass the FILE pointer along of course.

You can change the list_print to accept FILE* so you can write your data to file. Something according to this scheme:

void list_print(FILE* fp, INTLIST* list)
{
    /* ... rest of your code */

    fprintf(fp, "%d ", temp->datum); 

    /* ... rest of your code */
}


There's a couple of things I would do to your list_print function:

  • pass a FILE* variable so you can specify where the file is to go.
  • not initialise temp to NULL since you set it in the for statement anyway.

That would give you something like:

void list_print(FILE *fOut, INTLIST* list) {
    INTLIST *temp;
    for (temp = list; temp != NULL; temp = temp->next)
        fprintf (fOut, "%d ", temp->datum);
    fprintf (fOut, "\n");
}

In order to use it to print to the standard output, just use:

list_print (stdout, list);

since stdout is simply a FILE* for standard output (and you can also use stderr if you wish). If you want to write it to a file:

FILE *fp = fopen ("output_file.txt", "w");
if (fp == NULL) {
    // Flag an error.
} else {
    list_print (fp, list);
    fclose (fp);
}

There's also a change you can make to get rid of the extraneous space at the end of each line when the particular list is not empty. At the moment, a list (1,2,3) will print as (the _ characters are spaces):

1_2_3_

If you change the function to be:

void list_print(FILE *fOut, INTLIST* list) {
    INTLIST *temp;
    char *sep = "";
    for (temp = list; temp != NULL; temp = temp->next) {
        fprintf (fOut, "%s%d", sep, temp->datum);
        sep = " ";
    }
    fprintf (fOut, "\n");
}

it will get rid of that extraneous space at the end. Whether this is actually necessary is a decision for you to make - I've often done this to have a specific output format without making the code too much uglier but it may well be that the space at the end doesn't cause you any trouble.


list_print needs to use fprintf or it's output will got to standard out rather than to the file.

Which means you need to pass ofp as a parameter to list_print

also, it makes no sense to fprintf(..., list_print()), since list_doesn't return anything. just call list_print in that loop.


You're trying to print out the result of list_print(), which is void.

You'll need to write a new version of your list_print function, which accepts a FILE* and a list, and replace printf there with fprintf

To save the common code, you could replicate your original by something like the following:

void list_fprint (FILE * out, INTLIST * list) {
   . . . // as described above
}

void list_print (INTLIST * list) {
   list_fprint(stdout, list);
}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜