c - 在结构体中存储标记

标签 c struct token

很抱歉提出了重复的问题,但我对 C 编程非常陌生,无法全神贯注于如何将相同内容上的先前答案实现到我自己的代码中。

我要从磁盘或标准输入上的文件中读取文本,对单词进行排序,然后向用户提供单词出现的列表(出现次数最多的单词位于顶部,然后按降序排列)。

我目前坚持以一种合适的方式存储我的标记化单词,以便以后能够对它们进行计数和排序。我决定使用结构。

我编写了一个测试文件,其中使用 stdin 中的 fgets 为其提供数据。

这是代码:

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

int main(int argc, char const *argv[])
{
    struct words
    {
        char word[500];
        unsigned int count;
    };

    int size = 500;
    char *buffer;
    char token;
    struct words w;

    #ifdef DEBUG
    printf("--!DEBUG INFO!-- \n Right before the 4-loop now\n--!DEBUG INFO!--\n");
    #endif
    for (int i = 0; i < 10; ++i)
    {
        printf("Please enter word\n");
        fgets(buffer, size, stdin);
        #ifdef DEBUG
        printf("--!DEBUG INFO!-- \n %c\n--!DEBUG INFO!--\n", buffer);
        #endif
        token = strtok(buffer[i], "\n");
        strcpy(w.word[i], token);
        #ifdef DEBUG
        printf("--!DEBUG INFO!-- \n %c\n--!DEBUG INFO!--\n", w.word[i]);
        #endif
    }

    for (int i = 0; i < 10; ++i)
    {
        printf("%c\n", w.word[i]);
    }
    return 0;
}

编译时我收到一大堆警告消息,其中大多数都说明了类似的内容:

incompatible pointer to integer conversion assigning to 'char' from
      'char *'; dereference with * [-Wint-conversion]
                token = strtok(buffer[i], "\n");

但是该程序确实会编译并运行,直到我给它数据并按回车键。之后,它因段错误而崩溃:11 消息

./tok_struct 
--!DEBUG INFO!-- 
 Right before the 4-loop now
--!DEBUG INFO!--
Please enter word
Test 
Segmentation fault: 11

我非常感谢您能得到的任何帮助!

最佳答案

一方面,缓冲区需要分配一个大小,看起来它只是 代码中未初始化的指针。

一旦你执行了 fgets(buffer,...) 你就进入了未定义的行为领域,如果 buffer 没有指向可以存储输入的地方。

所以首先将 buffer 声明为数组

char buffer[512]; // or whatever size you deem is appropriate

然后将该行读入缓冲区(您可以检查行长度并在用户未输入任何内容时退出循环,而不是使用 for 循环)

while (fgets(buffer,sizeof(line),stdin) != NULL)
{
  char* token = strtok(buffer, "\n"); 
  if (token != NULL)
  {
   // in order to get a pointer to the rest of the words you 
   // need to call strtok multiple times and with another 
   // separator since one can assume that there is space between
   // the words e.g.  char* token = strtok(buffer, " \n"); 
   // and to process all words in the line:
   // for (char* token = strtok(buffer, " \n";
   //       token != NULL; 
   //       token = strtok(NULL, " \n"))
   // {
   //  .. here you store your tokens
   // }
  }
}

要存储 token ,您不能拥有现有的结构 char word[500] 只是一个字符数组,因此在其中进行索引 数组并将其作为 strcpy 的目标是没有意义的。

相反,您需要有一个结构数组。

struct words w[200]; // or how many words you are expected to handle

现在,对于您找到的每个单词,您需要查看数组,如果它是 已经存在,如果是,则增加计数器,否则复制到单词中并设置 计数器为 1。您应该初始化数组以确保其设置为 0。跟踪数组中有多少个单词,例如wordsFound

int wordsFound = 0;
for (char* token = strtok(buffer, " \n"; token != NULL; token = strtok(NULL, " \n"))
{
  ...
}

最后一点:strtok 会修改传递给它的参数,因此您无法存储返回的指针。您要么需要像上面那样复制它,要么需要分配空间然后复制到它。

通常情况下,不会有一个单词数组,而是一个单词链接列表,只要找到一个新单词,它就会增长,当然这个例子可以扩展以进行更好的查找等,但我想这不是你的目前的目标。

关于c - 在结构体中存储标记,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48668223/

相关文章:

node.js - 如何针对 firebase 验证身份验证 token ?

r - Quanteda:用字典中的引理替换标记的最快方法?

c - 如何在 c 中将数据从一个管道重定向到另一个管道?

将闪存中的 const 结构复制到 RAM 中的 "normal"结构

c++ - std::unordered_map 作为结构成员具有地址 0

c++ - 在 C++ 中通过 UDP 套接字发送结构、 float 和整数

Java 字符串索引超出范围 '}' 标记未包含/正确打印

c - 如何生成一个介于 -32000 和 32000 之间的随机均匀分布数

c - 使用 C 中的 Enter 键停止用户输入

c - 为什么我的 if 语句不起作用