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
toNULL
since you set it in thefor
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);
}
精彩评论