【问题标题】:How to make Interactive program in BST ? C Lang如何在 BST 中制作交互式程序? C朗
【发布时间】:2017-12-07 06:41:09
【问题描述】:

我需要打开并读取多个文本文件,这些文本文件的存储方式类似于二叉搜索树的构造。
注意:在用户输入之前,它们都需要打开并存储它们的内容。

我确实需要一些建议,因为我再也看不到我的错误了。

但是,我真正不明白的是,如何让它互动
当我按'A'时,它需要从左节点和对面读取文本。

输出结构:

------------------\n
\n
标题\n
file1 // 文件存在 - 'A'
file2 // 文件为空/非空 - 'B'\n
文字\n
\n
您的选择 (A/B):\n

这是程序输出在开头的样子: terminal

结构的元素

typedef struct _Elements_
{
  char* title_;
  struct _Elements_* left;
  struct _Elements_* right;
  char* text_;
} Elements;

//前向初始化存在

int main (int argc, char* argv[])
{
  char returned_value;
  Elements element;

  if (argc != 2)
  {
    printf("Usage: ./ass2 [file-name]\n");
    return 1;
  }

  returned_value = openFile(&element, argv[1]);

  while(returned_value != ('A' || 'B'))
  {
    repeatEntry(returned_value); // Function to scan the value
  }

  // Tricky part! Read from left ???
  if(returned_value == 'A')
  {
    printf("%s",element.left->text_);
  }
  else
  {
    printf("%s",element.right->text_);
  }

  return 0;
}

//这里我要初始化节点元素

// 对于每一个malloc,我都要确保它成功

Elements* newNode(Elements* element)
{
  Elements* newNode = (Elements*)malloc(sizeof(Elements));
  if(newNode == NULL)
  {
    printf("[ERR] Out of memory.\n");
     return (void*)2; // void* - to avoid warning of different type?
  }
  newNode->title_ = NULL;
  newNode->left = NULL;
  newNode->right = NULL;
  newNode->text_ = NULL;

  return newNode;
}

//打开文件的函数

char openFile(Elements* element, char* input)
{
  // Create new memory if tree is empty
  if(element == NULL)
  {
    return newNode(element);
  }
  FILE* file_open = fopen(input, "r");
  if (file_open == NULL)
  {
    printf("[ERR] Could not read file %s.\n", input);
    return 3;
  }

  // Local variables to handle the parsing file ?
  char line[80];
  int lenght_of_the_line; // Was just for me
  int line_number = 0; // this also

  // Do i really need local variables beside struct ? 
  char* title_local = NULL;
  char* first_file = NULL;
  char* second_file = NULL;
  char* text_local = NULL;

  while(fgets(line, 80, file_open))
  {
    lenght_of_the_line = strlen(line);
    //printf("%d ", lenght_of_the_line);
    //printf("%s ", line);

    // Get title
    if((line[lenght_of_the_line - 1] == '\n') && (line_number == 0))
    {

      title_local = (char*)malloc(lenght_of_the_line * (sizeof(char)) + 1);
      if(title_local == NULL)
      {
        printf("[ERR] Out of memory.\n");
        return 2;
      }
      strcpy(title_local, line);
      printf("%s ", element->title_ = title_local);
      printf("\n");
    }

    // Get 1st file name
    else if( (line[lenght_of_the_line - 1] == '\n') && (line_number == 1) )
    {
      if( (line[lenght_of_the_line - 5] == '.') &&
          (line[lenght_of_the_line - 4] == 't') &&
          (line[lenght_of_the_line - 3] == 'x') &&
          (line[lenght_of_the_line - 2] == 't') )
      {
        // Allocate enough memory for first file name
        first_file = (char*)malloc(lenght_of_the_line * (sizeof(char)) + 1);
        if(first_file == NULL)
        {
          printf("[ERR] Out of memory.\n");
          return 2;
        }
        strcpy(first_file, line);

         //name of file to open and store to left node
         //Seems to work, since I got no error
        openFile(element->left, first_file);
      }
    }

    // Get 2nd file name
    else if( (line[lenght_of_the_line - 1] == '\n') && (line_number == 2) )
    {
      if( (line[lenght_of_the_line - 5] == '.') &&
          (line[lenght_of_the_line - 4] == 't') &&
          (line[lenght_of_the_line - 3] == 'x') &&
          (line[lenght_of_the_line - 2] == 't') )
      {
        second_file = (char*)malloc(lenght_of_the_line * (sizeof(char)) + 1);
        if(second_file == NULL)
        {
          printf("[ERR] Out of memory.\n");
          return 2;
        }
        strcpy(second_file, line);
        openFile(element->right, second_file);
      }
    }
    else
    {
      text_local = (char*)malloc(lenght_of_the_line * (sizeof(char)) + 1);
      if(text_local == NULL)
        {
          printf("[ERR] Out of memory.\n");
          return 2;
        }
      strcpy(text_local, line);
      element->text_ = text_local;
      printf("%s", element->text_);
    }

    // Increase line number for 1
    line_number++;
  }
  //free(line);

  fclose(file_open);
  printf("\n");
  printf("Your choice (A/B)? ");
  char user_input;
  scanf("%c", &user_input);

  // DONT FORGET TO FREE THE MEMORY !

  return user_input;
}

【问题讨论】:

  • 是什么阻止您创建带有指向文件内容“字符串”的指针的 BST?您可以使用字符串指针的链接列表添加更多结构。对于未知长度的文本,使用 malloced 内存。
  • 您在问“我应该怎么做?”通过阅读概念,玩有关该问题的教程并从经过单独测试的小部件开始构建。第一个小文件读入 malloced 内存并从那里打印。然后引入 BST 链接到每个文件的第一部分。不要忽视用户输入的读入,许多陷阱在那里等着你。
  • 顺便说一句,我很确定这个while(returned_value != ('A' || 'B')) 没有达到你的预期。它将返回值与编译器用来表示true 的任何值进行比较。你的意思可能是while((returned_value != 'A') && (returned_value != 'B'))
  • @Yunnosch 它当时是一个,所以while((returned_value != 'A') || (returned_value != 'B')) 实际上是我需要的。会试试的。
  • ((returned_value != 'A') || (returned_value != 'B')) 绝对永远是正确的。我建议使用&&。想想任何东西怎么可能是“A”,同时又是“B”,这是摆脱循环的唯一方法。

标签: c memory struct binary-search-tree interactive


【解决方案1】:

这个

while(returned_value != ('A' || 'B'))

不符合您的预期。它将返回的值与编译器用来表示true 的任何值进行比较。
目前,您的循环可能看起来是一个无限循环,同时等待返回值与true 相同。

你需要

while((returned_value != 'A') && (returned_value != 'B'))

returned_value 与“A”或“B”相同时,这将退出循环。
这样就解决了无限循环问题,这可能是阻止您的文件 BST 交互的核心问题。

顺便说一下,为了方便用户,我建议也接受 'a' 或 'b'。

为避免每次输入后“重试”,请使用

scanf(" %c", &user_input);

开头有一个空格,用于忽略前导空格,包括每个输入的“A”或“B”后的换行符/回车符。

【讨论】:

  • 我们被指示只接受大写的 A 或 B。顺便说一句,为什么输出乘以插入元素的数量? Your choice (A/B): as //插入两个元素 -enter 显示:Your choice (A/B): Your choice (A/B):
  • 它可能对 A 或 B 之后的换行符/回车作出反应。您需要忽略它。
  • 试试scanf(" %c", &user_input);,注意开头的空格,它将忽略所有前导空格。
  • 祝项目的其余部分好运。我喜欢制作一个易于编辑的迷你文本冒险的想法。
猜你喜欢
  • 2012-02-20
  • 2020-07-01
  • 2014-10-30
  • 1970-01-01
  • 2016-04-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-11-24
相关资源
最近更新 更多