user3458225
user3458225

Reputation:

print data in an array of structs recursively

I need to print the data in an array of structs recursively like so,

index, numberOfChildern, child[0]...child[numberOfChildern-1] 

The catch is that for every child, I need to print index, numberOfChildern, child[0]...child[numberOfChildern-1] as well.

typedef struct node point;
typedef point **pointsList;

The struct:

struct node{
  int index; //the order in the instance file
  int x;//x coord
  int y;//y coord
  int parent;//parent in tree when added
  int numChildern;//has val 0 -- 8 maybe, but doesn't matter the way I wrote it
  int *child;    
};

All values in every struct is set properly, This is a incomplete method I began writing to complete the task.

void printStringOfChildern(pointsList list, point *point, int fileNum){


if(point->numChildern == 0)
    return;

  //print the index
  char index[calcNumberOfDigitsInAInt(point->index)+3];
  sprintf(index, "%d", point->index);
  strcat(index, ", ");
  print(index, fileNum);

  //print the number of childern
  char chidern[calcNumberOfDigitsInAInt(point->numChildern)+3];
  sprintf(chidern, "%d", point->numChildern);
  strcat(chidern, ", ");
  print(chidern, fileNum);

  //print the childern
  for(int i=0; i<point->numChildern; i++){
    char child[calcNumberOfDigitsInAInt(point->child[i])+3];

//was child[i] now point->child[i]
    sprintf(child, "%d", point->child[i]);
    strcat(child, ", ");
    print(child, fileNum);

    //print out other childern and their data if there is any
    int numChildern = numberOfChildern(list, point -> index);
    if(numChildern > 0){
      printStringOfChildern(list, list[point->child[i]], fileNum);

    }

  }

}

You'll notice the above code is awful and incomplete, but it shows the use of my printing functions

The if else block below is how I print to the output, which could be terminal a file or a series of files. The print functions and this if else block have been tested, and proven to work. inOutType is a global variable, and so is outputFileName. fileIndex is only used in the case of printing to multiple files and in the case of printing to multiple files this method will be called for however many files there are. This is the print function

if(inOutType == 1 || inOutType == 2){
printLineToOutPut(output, outputFileName, inOutType);

}else{
    printToAInstanceFile(output, fileIndex);

  }

All I've done in the edits is update the sample, and write this

Output format:



index, numberOfChildern, child[i]. If child[i] has children then index, numberOfChildern, indexOf(child[i]), numberOfChildernOf(child[i]), child[i]OfChild[i]..... 

The method is executed like so

for(int j=0; j<maxNumberOfPoints; j++)
        printStringOfChildern(listOfListOfPoints[i], listOfListOfPoints[i][j], i);

Upvotes: 0

Views: 197

Answers (1)

Jonathan Leffler
Jonathan Leffler

Reputation: 754590

In the absence of a clear example of what the output should look like, here's a version of the code shown. Note that I simply create buffers that are 32 characters long rather than spending time calculating exactly how long they must be. That's not a lot of memory and yet plenty for the task at hand. Also, there was no data — I've invented some:

Index 0:  3 children
    Index 1: 0 children
    Index 2: 2 children
        Index 4: 0 children
        Index 5: 0 children
    Index 3: 0 children

There's no need for any other data; the x, y and parent members of the structure in the question aren't used — eliminating the irrelevant is a part of creating an MCVE (Minimal, Complete, Verifiable Example).

I've ignored the 'fileNum' argument; the printing occurs simply and solely to standard output. It is easy enough to reinstate printing to a file if you need it. I've also used a notation inspired by JSON to report the data, enclosing arrays in […] and single points except for the top of the hierarchy inside {…}.

#include <stdio.h>
#include <string.h>

typedef struct node point;
typedef point **pointsList;

struct node
{
    int index; // the order in the instance file
    // int x;//x coord
    // int y;//y coord
    // int parent;//parent in tree when added
    int numChildren;// has val 0 -- 8 maybe, but doesn't matter the way I wrote it
    int *child;
};

static inline void print(const char *str)
{
    printf("%s", str);
}

static void printStringOfChildren(pointsList list, point *point)
{
    // print the index
    char index[32];
    sprintf(index, "%d", point->index);
    strcat(index, ", ");
    print(index);

    // print the number of children
    char children[32];
    sprintf(children, "%d", point->numChildren);
    strcat(children, ", ");
    print(children);

    // print the children
    print("[");
    for (int i = 0; i < point->numChildren; i++)
    {
        if (i > 0)
            print(",");
        print(" { ");
        printStringOfChildren(list, list[point->child[i]]);
        print(" }");
    }
    if (point->numChildren > 0)
        print(" ");
    print("]");
}

int main(void)
{
    point *list[] =
    {
        &(point){ 0, 3, (int[]){ 1, 2, 3 } },
        &(point){ 1, 0, 0 },
        &(point){ 2, 2, (int[]){ 4, 5 } },
        &(point){ 3, 0, 0 },
        &(point){ 4, 0, 0 },
        &(point){ 5, 0, 0 },
    };
    printStringOfChildren(list, list[0]);
    putchar('\n');

    return 0;
}

Output:

0, 3, [ { 1, 0, [] }, { 2, 2, [ { 4, 0, [] }, { 5, 0, [] } ] }, { 3, 0, [] } ]

There are many other ways to do the output. The whole business with sprintf() and strcat() is bogus — you could perfectly well use printf() in my scenario, or fprintf() in a more general case, to format the data, reducing the size of the program still more.

Upvotes: 1

Related Questions