我有一个程序,它有一个指针数组,如:
INTLIST* myArray[countOfRows];
每个myArray
指针指向链表,基本上它变成M * N矩阵。
例如:
3 2 1
2 1 0
1 9 8
因此myArray[0]
是包含3->2->1
的链接列表,myArray[1]
是包含2->1->0..
的链接列表,依此类推。我有一个打印矩阵的函数,基本上这样做:
for(int i = 0; i<countOfRows; i++)
list_print(myArray[i]);
然后我的list_print函数是这样的:
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");
}
这一切都很好,工作正常,(我知道我可以优化和清理,我保证会这样做)。现在我的下一个问题是我需要将此矩阵写入文本文件。所以我尝试了这个:
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]);
}
但我认为不是那么简单。任何人都可以告诉我如何将其打印到文本文件...
由于
答案 0 :(得分:2)
您无法使用printf
函数写入文件。您需要使用printf
替换所有fprintf
次来电,然后传递FILE
指针。
您可以将list_print
更改为接受FILE*
,以便将数据写入文件。根据这个计划的东西:
void list_print(FILE* fp, INTLIST* list)
{
/* ... rest of your code */
fprintf(fp, "%d ", temp->datum);
/* ... rest of your code */
}
答案 1 :(得分:2)
我会对你的list_print
函数做一些事情:
FILE*
变量,以便您指定文件的去向。temp
初始化为NULL
,因为无论如何都要在for
语句中设置它。这会给你类似的东西:
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");
}
要使用它打印到标准输出,只需使用:
list_print (stdout, list);
因为stdout
只是标准输出的FILE*
(如果您愿意,也可以使用stderr
)。如果要将其写入文件:
FILE *fp = fopen ("output_file.txt", "w");
if (fp == NULL) {
// Flag an error.
} else {
list_print (fp, list);
fclose (fp);
}
当特定列表不为空时,您还可以进行更改以消除每行末尾的无关空间。目前,列表(1,2,3)将打印为(_
个字符为空格):
1_2_3_
如果您将功能更改为:
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");
}
它将在最后摆脱那个无关紧要的空间。这是否真的是必要的是你做出的决定 - 我经常这样做是为了有一个特定的输出格式而不会使代码太过丑陋但是最后的空间可能不会给你带来任何麻烦
答案 2 :(得分:2)
使用fprintf
参数在list_print
函数中使用FILE *
函数,如示例所示:
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");
}
会这样做:
int main(){
FILE *fp;
fp = fopen("data.txt", "w");
for(i=0; i<fileLineCount; i++)
{
list_print(alist[i], fp);
}
fclose(fp);
}
或者
如果你希望将链表的二进制转储从内存保留到磁盘(这是解释它的简单方法),那就最好了:
for(i=0; i<fileLineCount; i++)
{
fwrite(alist[i], sizeof(alist[i]), 1, ofp);
}
然后从中读取,
for(i=0; i<fileLineCount; i++)
{
fread(&alist[i], sizeof(alist[i]), 1, ofp);
}
编辑:我对包含上述内容犹豫不决,但 paxdiablo 指出了我的fread(...)
和{{ 1}}上面的代码,并意识到他是对的。在对链表进行二进制写操作时,链接列表中的内存地址引用在下次读取时将无效。 谢谢paxdiablo !
答案 3 :(得分:1)
list_print
需要使用fprintf
或者它的输出将标准输出而不是文件。
这意味着您需要将ofp
作为参数传递给list_print
另外,fprintf(...,list_print())没有意义,因为list_does没有返回任何内容。 只需在该循环中调用list_print。
答案 4 :(得分:1)
您正在尝试打印出list_print()的结果,这是无效的。
您需要编写list_print函数的新版本,该函数接受FILE *和列表,并将printf
替换为fprintf
要保存公共代码,您可以通过以下内容复制原始代码:
void list_fprint (FILE * out, INTLIST * list) {
. . . // as described above
}
void list_print (INTLIST * list) {
list_fprint(stdout, list);
}