【问题标题】:Dynamic memory C动态内存 C
【发布时间】:2014-11-20 15:07:22
【问题描述】:

我的任务是创建一个程序,该程序从文件中读取所有单词并将这些单词从头到尾都相同(我的意思是 aha、oho、asdsa、assa 等)。并且任务需要使用动态内存(大学),但是我已经被困在这个地方好几天了,因为我找不到它为什么不想做我打算做的事情。我有 4 个单词在文件中。这 4 个 printfs 应该打印所有单词,但我的程序会打印第三个单词(null)和分段错误。我使用单面动态内存。 请解释为什么它不起作用,因为我自己做不到。先感谢您! 代码:

/*
 * Task: Write program, that finds all words from file which reads from beginning to end (lets call them mirror-type words)
 */

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

struct elements
{
        char str[255];
        struct elements *next;
};

/* Function checks if given word is mirror-type word */
int is_mirror(char str[255])
{
        int length = strlen(str);

        int to = (length % 2 == 1) ? (length - 1) / 2 : length / 2;

        int i = 0;
        while (i < to)
        {
                if (str[i] != str[length-i-1]) return 0;

                i++;
        }
        return 1;
};

int main()
{
        FILE *in;
        in = fopen("3_12.in", "r");
        if (in == NULL)
        {
                printf("Input file doesnt exist.\r\n");
                return 0;
        }

        char str[255];
        fscanf(in, "%s", str);

        struct elements *beginning, *element;

        element = (struct elements *) malloc(sizeof(struct elements));
        strcpy(element->str, str);

        beginning = element;

        do
        {
                fscanf(in, "%s", str);

                element->next = (struct elements *) malloc(sizeof(struct elements));
                strcpy(element->str, str);

                if (feof(in))
                {
                        element->next = NULL;
                        break;
                }
        }
        while(1);

        printf("%s\r\n", element->str);
        printf("%s\r\n", element->next->str);
        printf("%s\r\n", element->next->next->str);
        printf("%s\r\n", element->next->next->next->str);

        fclose(in);
}

【问题讨论】:

  • 显示输入和所需输出的示例。
  • 从不转换 malloc() 的结果
  • @MichaelWalz 还没有输出部分,因为我无法将整个信息放入动态数组中。
  • 你的意思是回文?
  • 看起来你的 while 循环永远不会通过第二个元素。如果我错了,请纠正我,但在某些时候你不应该说element = element-&gt;next 吗?

标签: c memory dynamic malloc


【解决方案1】:

查看您的代码,您似乎错过了循环中的一个步骤。您永远不会提前传递第二个单词,因为元素永远不会更新。

代码片段

do
{
    fscanf(in, "%s", str); //Get the string

    element->next = (struct elements *) malloc(sizeof(struct elements)); //Create a new element at the end of the list

    element = element->next; //Move forward to the newly created element

    strcpy(element->str, str); //Copy the read string into the newly create element's `str`

    //If we've hit the end of the file, put a null at the end of the list and break
    if (feof(in))
    {
            element->next = NULL;
            break;
    }
}
while(1);

看看这个page 它有一些关于链接 lsits 的重要信息(这是你正在使用的)。

编辑 1

我注意到我编写的原始代码有一个错误。设置str 的位置覆盖了原始元素的str 值。该代码永远不会创建一个长度超过 1 个元素的列表,并且一个元素将始终包含文件中的最后一个单词,后跟一个 null。

【讨论】:

    【解决方案2】:

    下面是两个单词的阅读方式。

    #include<stdio.h>
    #include<string.h>
    #include<stdlib.h>
    
    struct elements {
      char str[255];
      struct elements *next;
    };
    
    int main() {
      FILE *in;
      in = fopen("test.txt", "r");
      if (in == NULL) {
        printf("Input file doesnt exist.\r\n");
        return 0;
      }
    
      char str[255];
      fscanf(in, "%s", str);
    
      struct elements *beginning, *element;
    
      element = malloc(sizeof(struct elements));
      strcpy(element->str, str);
      element->next = NULL;
    
      beginning = element;
    
      do {
        fscanf(in, "%s", str);
        element = malloc(sizeof(struct elements));
        strcpy(element->str, str);
        element->next = NULL;
    
        beginning->next = element;
    
        if (feof(in)) {
          break;
        }
      } while (1);
    
      printf("%s\r\n", beginning->str);
      printf("%s\r\n", beginning->next->str);
    
    
      fclose(in);
      free(beginning->next);
      free(beginning);
    }
    

    test.txt

    aabb
    sam
    

    所以,您正在尝试构建一个链表。我在上面的示例中创建了一个节点,将读取的第一个单词设置为element-&gt;str,并将element-&gt;next 设置为NULL。

    然后我将beginning 设置为该节点。请注意,人们通常使用 head 而不是 beginning,因为它是列表的第一个节点。

    然后我对下一个单词做同样的事情,我将新节点作为列表的第二个节点插入。


    你看到你需要建立一个列表,因为它变得越来越大。我通过this 代码学会了如何做到这一点。


    Do not cast what malloc() returns.

    【讨论】:

      【解决方案3】:

      改变

      beginning = element;
      
      do
      {
              fscanf(in, "%s", str);
      
              element->next = (struct elements *) malloc(sizeof(struct elements));
              strcpy(element->str, str);
      
              if (feof(in))
              {
                      element->next = NULL;
                      break;
              }
      }
      while(1);
      
      printf("%s\r\n", element->str);
      printf("%s\r\n", element->next->str);
      printf("%s\r\n", element->next->next->str);
      printf("%s\r\n", element->next->next->next->str);
      

      beginning = element;
      
      while(EOF!=fscanf(in, "%s", str)){
          element->next = (struct elements *) malloc(sizeof(struct elements));
          element = element->next;
          strcpy(element->str, str);
      }
      element->next = NULL;
      
      printf("%s\n", beginning->str);
      printf("%s\n", beginning->next->str);
      printf("%s\n", beginning->next->next->str);
      printf("%s\n", beginning->next->next->next->str);
      

      并添加回文检查。

      【讨论】:

        猜你喜欢
        • 2013-09-30
        • 2011-10-12
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-12-07
        • 2015-06-27
        • 2021-02-28
        • 2015-12-13
        相关资源
        最近更新 更多