C - Как записать содержимое указателя связанного списка в текстовый файл - PullRequest
0 голосов
/ 25 января 2010

У меня есть программа, которая имеет массив указателей, таких как:

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

Но я так понимаю, это не так просто. Может кто-нибудь показать мне, как распечатать это в текстовом файле ...

Спасибо

Ответы [ 5 ]

2 голосов
/ 25 января 2010

Используйте функцию 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(...) и fwrite(...) коде выше, и понял, что он прав. При выполнении двоичной записи связанного списка ссылки на адреса памяти в связном списке будут недействительными при чтении в следующий раз. Спасибо paxdiablo !

2 голосов
/ 25 января 2010

Я бы сделал пару вещей для вашей функции 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 голосов
/ 25 января 2010

Вы не можете использовать функцию 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 голос
/ 25 января 2010

Вы пытаетесь распечатать результат list_print (), который является недействительным.

Вам нужно написать новую версию функции list_print, которая принимает ФАЙЛ * и список, и заменить printf там на fprintf

Чтобы сохранить общий код, вы можете скопировать свой оригинал примерно так:

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

void list_print (INTLIST * list) {
   list_fprint(stdout, list);
}
1 голос
/ 25 января 2010

list_print необходимо использовать fprintf, иначе его вывод получится стандартным, а не в файл.

Это означает, что вам нужно передать ofp в качестве параметра list_print

также, fprintf (..., list_print ()) не имеет смысла, поскольку list_ ничего не возвращает. просто вызовите list_print в этом цикле.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...