// This prints the searchresult from list
static void printResult(DocTable table, LinkedList list) {
  LLIter it = LLMakeIterator(list, 0);
  SearchResultPtr searchResult;
  do {
    LLIteratorGetPayload(it, (LLPayload_t*)&searchResult);
    printf("  %s (%d)\n", DTLookupDocID(table, searchResult->docid),
     searchResult->rank);
  } while (LLIteratorNext(it));
  LLIteratorFree(it);
  FreeLinkedList(list, free);
}
int main(int argc, char **argv) {
  if (argc != 2)
    Usage();

// Implement searchshell!  We're giving you very few hints
// on how to do it, so you'll need to figure out an appropriate
// decomposition into functions as well as implementing the
// functions.  There are several major tasks you need to build:
//
//  - crawl from a directory provided by argv[1] to produce and index
//  - prompt the user for a query and read the query from stdin, in a loop
//  - split a query into words (check out strtok_r)
//  - process a query against the index and print out the results
//
// When searchshell detects end-of-file on stdin (cntrl-D from the
// keyboard), searchshell should free all dynamically allocated
// memory and any other allocated resources and then exit.

  DocTable doctable;
  MemIndex index;
  int qlen, res;
  char *query[128];
  char *input = (char*) malloc(128);
  char *token;
  char *check;
  char *saveptr;
  LinkedList retlist;
  LLIter llit;
  SearchResult *sres;
  char *name;


  // crawls the directory
  printf("Indexing '%s'\n", argv[1]);
  // gets the doctable and inverted index table
  res = CrawlFileTree(argv[1], &doctable, &index);
  if (res == 0) {  // encounters error
    Usage();
  }

  while (1) {
    printf("enter query:\n");
    // when the user types control-D
    if (fgets(input, 128, stdin) == NULL) {
      printf("shutting down...\n");
      break;
    }
    qlen = 0;

    // gets the first token
    token = strtok_r(input, " ", &saveptr);
    // stores the token in the array
    while (token != NULL) {
      query[qlen] = token;
      qlen++;
      token = strtok_r(NULL, " ", &saveptr);
    }
    // changes \n to \0
    check = strchr(query[qlen - 1], '\n');
    if (check != NULL) {
      *check = '\0';
    }

    // gets the result linkedlist
    retlist = MIProcessQuery(index, query, qlen);
    if (retlist != NULL && NumElementsInLinkedList(retlist) != 0) {
      // iterates through the list and print
      llit = LLMakeIterator(retlist, 0);
      Verify333(llit != NULL);
      do {
        // prints the result from the iterator
        LLIteratorGetPayload(llit, (void **)&sres);
        name = DTLookupDocID(doctable, sres->docid);
        printf("  %s  (%d)\n", name, sres->rank);
      } while (LLIteratorNext(llit));

      LLIteratorFree(llit);  // free the iterator
      FreeLinkedList(retlist, free);  // free the linked list
    }
  }

  free(input);
  FreeDocTable(doctable);
  FreeMemIndex(index);
  return EXIT_SUCCESS;
}
Beispiel #3
0
int main(int argc, char **argv) {
  if (argc != 2)
    Usage();

  // Implement searchshell!  We're giving you very few hints
  // on how to do it, so you'll need to figure out an appropriate
  // decomposition into functions as well as implementing the
  // functions.  There are several major tasks you need to build:
  //
  //  - crawl from a directory provided by argv[1] to produce and index
  //  - prompt the user for a query and read the query from stdin, in a loop
  //  - split a query into words (check out strtok_r)
  //  - process a query against the index and print out the results
  char input[1024];
  char *token;
  char *saveptr;
  DocTable doctable;
  MemIndex index;
  LinkedList searchresult;
  LLIter llit;
  SearchResult *rs;

  printf("Indexing \'%s\'\n", argv[1]);
  // crawl from directory argv[1]
  if (CrawlFileTree(argv[1], &doctable, &index) == 0) {
    // terminate the program if crawl failed
    Usage();
  }

  Assert333(doctable != NULL);
  Assert333(index != NULL);

  while (1) {
    // ask for user input
    printf("enter query:\n");
    if (fgets(input, 1024, stdin) != NULL) {
      // malloc space in order to store tokens
      // split from user input
      char **query = (char **) malloc(512 * sizeof(char *));
      Assert333(query != NULL);

      uint8_t qlen = 0;
      char *str = input;
      // whenever we see the space in the input, split it
      // and store it into array
      while (1) {
        token = strtok_r(str, " ", &saveptr);
        // jump out of loop if there are no more tokens
        if (token == NULL)
          break;
        query[qlen] = token;
        qlen++;
        str = NULL;
      }

      // replace last token's '\n' by '\0' since fgets
      // also read '\n' into input
      char *p = strchr(query[qlen - 1], '\n');
      if (p)
        *p = '\0';

      // search for the documents that contains
      // all the words in the query
      searchresult = MIProcessQuery(index, query, qlen);
      if (searchresult != NULL) {
        llit = LLMakeIterator(searchresult, 0);
        Assert333(llit != NULL);

        // print out all the matching documents under
        // the directory argv[1] and the rank for the query
        do {
          LLIteratorGetPayload(llit, (void **) &rs);
          printf("  %s (%u)\n", DTLookupDocID(doctable, rs->docid), rs->rank);
        } while (LLIteratorNext(llit));

        LLIteratorFree(llit);
      }

      free(query);
    }
  }

  FreeDocTable(doctable);
  FreeMemIndex(index);

  return EXIT_SUCCESS;
}