【问题标题】:Need to know how to parse words by space in c. Also need to know if I am allocating memory correctly?需要知道如何在c中按空格解析单词。还需要知道我是否正确分配内存?
【发布时间】:2019-03-07 03:08:11
【问题描述】:

我正在用 c 编写一个程序,它从文本文件中读取文本,然后从文件中随机选择单词,如果单词大于或等于 6,它会将单词附加在一起,删除空格,最后打印新词。 (我正在使用 linux 上的重定向“

Example input: "cheese and crackers"

New word should be: cheesecrackers

代码如下:

int main (void)
{
    int ch;
    char *ptrChFromFile;
    int strSize = 1;
    int i;
    int numberOfWords = 1;

    ptrChFromFile = malloc (sizeof (char));

    if (ptrChFromFile == NULL) {
        puts ("COULDN'T ALLOICATE MEMORY");
        exit (EXIT_FAILURE);
    }

    while ((ch = getchar ()) != EOF) {
        ptrChFromFile =
            realloc (ptrChFromFile, (strSize + 1) * sizeof (char));

        if (ptrChFromFile == NULL) {
            puts ("failed to allocate memory");
            exit (EXIT_FAILURE);
        }

        if (ch == ' ') {
            numberOfWords++;
        }

        ptrChFromFile[strSize] = ch;
        strSize++;
    }

    ptrChFromFile[strSize] = 0;

    char **ptrWords = malloc (sizeof (char *) * strSize);


    for (i = 0; i < strSize; i++) {
        if (ptrChFromFile[i] != ' ') {
            ptrWords[i] = &ptrChFromFile[i];
        }
        else {
            ptrWords[i] = 0;
        }
    }

    free (ptrChFromFile);
    free (ptrWords);
    return 0;
}

我正在努力解决的问题是:

1) 我是否为指针分配了正确的内存大小?

2) 如何在不使用 string.h 库中的任何特殊方法(如 strtok)的情况下按空格解析每个单词。那么如何将这些单词存储在指针 *ptrWords 中?

所以 ptrWords 应该是这样的:


奶酪 |和 |饼干

 0        1      2

然后我想循环遍历ptrWords,检查指针中每个单词的长度是否大于等于6。如果将它们存储在指针 ptrOutputWord 中。

那么 ptrOutputWord 应该如下所示:


奶酪 |饼干

 0        1      

最后,我想将 ptrOutputWord 中的值打印为一个不带空格的单词。

我试图解释我想要做什么。感谢任何可以提前提供帮助的人。

编辑:我更改了代码以仅反映应在字符中读取的部分,并在每次读入新字符时将指针的大小重新分配一,但未分配正确数量的内存.

【问题讨论】:

  • 1) 不,您没有正确分配内存。您正在分配一个内存 charsizeof(char) 应该很清楚。 2)听起来这就是你的任务要求你弄清楚的。如果我们为您这样做,您的讲师可能会不高兴。
  • 不清楚你初始化strSize,所以增加它是可疑的。你像愤怒一样泄漏内存,因为你总是使用malloc() 而从不使用realloc()。一次添加一个字符很慢;将分配的内存量加倍,并密切关注它。 ptrChFromFile = &amp;ch; strSize ++; ptrChFromFile = (char*)malloc(strSize * sizeof(char)+1); 的代码由于各种原因严重损坏。
  • 输出的第二行中的数字应该是什么意思?合并单词后,没有第二个单词,只有一个更长的单词。否则,您问题顶部的示例不正确。
  • 您只调用一次rand。要连接一些单词,您应该添加一些机制来选择多个单词并以某种方式确定要选择多少个随机单词
  • 一般提示:第一件事!拆分您的问题:1. 从文件中读取,2. 分隔单词,3. 存储单词,4. 选择随机单词,5. 检查长度并添加到新单词。 6. 重复 4&5 直到达到某个限制 7. 打印输出。仅当其中一个步骤对您有效时,才继续执行下一步。

标签: c pointers malloc tokenize dynamic-arrays


【解决方案1】:

你有几个问题:

#include <stdio.h>
#include <time.h>

为什么是这个标题?

#include <stdlib.h>

int main()
{
  char ch, *ptrChFromFile; 
  int strSize;

这个变量需要有一个有用的起始值。

  ptrWordsFromFile = (char*)malloc(sizeof(char));

无需投射。

  if(ptrChFromFile == NULL)
  {
     puts("COULDN'T ALLOICATE MEMORY");
     exit(EXIT_FAILURE);
  }

  while((ch = getchar()) != EOF)

getchar 返回和 int,而不是 char

  {
    ptrChFromFile  = (char*)realloc(ptrChFromFile, strSize * sizeof(char)+1);

我们需要比以前多一个字符并为0 提供额外的空间。 您应该将 +2(而不是 +1)添加到元素数量:(strSize+2) * sizeof(&lt;any type&gt;)

通常您不应将realloc 的结果直接分配给同一个指针。万一失败,您将丢失旧的指针值。再说一遍:不需要演员表。

    if(ptrChFromFile == NULL)
      {puts("failed to alloicate memory");}

如果失败,您将无法继续!同上退出程序

    *ptrChFromFile = ch;

您将字符放在扩大缓冲区的开头。你应该在最后添加。

    strSize++;
  }

现在您在内存中有一堆字符,但字符串没有终止。

  free(ptrChFromFile);
  return 0;
}

修复后是这样的:

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

int main(void)
{
  int ch;
  char *ptrChFromFile; 
  int strSize = 0;

  ptrWordsFromFile = malloc(sizeof(char));

  if (ptrChFromFile == NULL)
  {
     puts("COULDN'T ALLOICATE MEMORY");
     exit(EXIT_FAILURE);
  }

  while ((ch = getchar()) != EOF)
  {
    ptrChFromFile = realloc(ptrChFromFile, (strSize+2) * sizeof(char));

    if (ptrChFromFile == NULL)
    {
      puts("failed to allocate memory");
      exit(EXIT_FAILURE);
    }

    ptrChFromFile[strSize] = ch;
    strSize++;
  }
  ptrChFromFile[strSize] = 0;

  // Now add detection and storing of separate words
  // (You might omit storing words that are too short)
  // Select random words and add together.

  free(ptrChFromFile);
  return 0;
}

【讨论】:

  • 感谢您为我将其分解为多个部分。我什至没有想过要从后面添加角色。一个很好的解释。谢谢你。现在我必须有另一个指针来存储单独的单词。是否可以在 c 中将单词存储在指针中,以使第一个单词(不是字符)位于索引零处?因此,当我从指针中选择一个随机单词时,我可以这样说: ptrOutputWord = ptrWords[randomIndex] 如果 randomIndex 为 0,它将 ptrWords 中的第一个单词存储到 ptrOutputWord。
  • 对于你的单词你需要使用双指针:char **words = malloc(sizeof(char*)*num_words); 然后words[i]可以保存第i个单词的地址,从0开始。你不需要为你的单词分配新的内存字。您可以使用初始内存并将指针存储到该区域。不要忘记终止每个单词。如果您遇到困难,我建议继续采用这种方法并提出另一个问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-09-01
  • 2017-05-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-10-31
  • 1970-01-01
相关资源
最近更新 更多