【问题标题】:Function to search a text document for a word in C用 C 语言在文本文档中搜索单词的函数
【发布时间】:2021-04-01 13:08:57
【问题描述】:

我编写了这个函数来搜索一个文本文件(目前只是说“立方体”)中的一个单词,然后调用相应的函数。但是,我收到“错误:未找到功能”。消息。

谁能帮我找出我的问题?

void read(){
    const char cube[4] = "cube";
    const char cone[4] = "cone";
    const char sphere[6] = "sphere";
    const char cylinder[8] = "cylinder";

    char line[1024] ;
    FILE* fp = fopen("instructions.txt", "r") ;
    while (fgets(line , sizeof(line) , fp )!= NULL)
    {
        if (strstr(line , cube)!= NULL){
            void cube();
        }
        else if (strstr(line , cone)!= NULL){
            void cone();
        }
        else if (strstr(line , sphere)!= NULL){
            void sphere();
        }
        else if (strstr(line , cylinder)!= NULL){
            void cylinder();
        }
        else {
            printf("Error: No Function Found./n");
        }
    }
    fclose(fp);
    free(line);
    return;
}

【问题讨论】:

  • const char cube[4] = "cube" 不是字符串。它不是空终止的。使用const char cube[] = "cube" 并让编译器正确确定大小。 (提示:至少应为 5)
  • OT : free(line); 非常错误。
  • @alexandrahowes 好的,但仍然需要进行此检查,因为如果您不这样做并且fopen 函数失败,您就麻烦了。
  • 不...不,你不是。你根本没有给他们打电话。
  • 正如 Lundin 在回答中指出的那样,如果你删除函数原型,你现在有 cube 是一个字符数组,显然不能像函数一样调用它。

标签: c if-statement fopen strstr


【解决方案1】:
const char cube[4] = "cube";
strstr("foobar", cube);  /* undefined behavior */

在上面,cube 不是一个以 null 结尾的字符串,所以当strstr 尝试读取数组的边界时会导致未定义的行为。您需要 5 个字符来存储 4 个字符的字符串。避免这个错误的最好方法是使用:

const char cube[] = "cube";

或 const char *cube = "立方体";

另外,您调用函数cube 的尝试也失败了。

if (strstr(line , cube)!= NULL){
    void cube_f();  /* Declare a function, using a non-standard compiler extension */
    cube_f();   /* Call the function */
}

但请注意,您有名称冲突,cube 不能既是函数名称又是局部变量。我为名称添加了后缀以防止名称冲突。如果之前为您定义了cube,您可能应该改为更改局部变量的名称。

【讨论】:

  • void cube(); 不会做你认为的那样。它不调用函数。
【解决方案2】:

你可能想要这个:

void read() {
    const char cube_str[] = "cube"; // let the compiler determine the length
    const char cone_str[] = "cone"; // which also ensures the strings are NUL terminated
    const char sphere_str[] = "sphere";
    const char cylinder_str[] = "cylinder";

    char line[1024] ;
    FILE* fp = fopen("instructions.txt", "r") ;
    if (fp == NULL)  // check for error
    {
       // display error message and abort
    }
    while (fgets(line , sizeof(line) , fp ) != NULL)
    {
        if (strstr(line , cube_str)!= NULL){
            cube();    // call function instead of declaring it
                       // void cube();  is just a declaration, it 
                       // doesn't call the funtion
        }
        else if (strstr(line , cone_str)!= NULL){
            cone();
        }
        else if (strstr(line , sphere_str)!= NULL){
            sphere();
        }
        else if (strstr(line , cylinder_str)!= NULL){
            cylinder();
        }
        else {
            printf("Error: No Function Found./n");
        }
    }

    fclose(fp);
    // remove this line:  free(line);
    // you can only free pointers returned by malloc and friends
    return;
}

【讨论】:

  • 例如,当函数被称为 cube() 时,我收到一条错误消息。它说“被调用的对象‘立方体’不是函数或函数指针”
【解决方案3】:

基本上,它归结为:在编写 C 代码时,您不能冒险了解某事的作用或工作原理。您实际上必须知道您编写的每一行代码的作用。没有试错法的学习方式,因为有些事情可能看起来有效,而实际上它们是等待使您的程序崩溃的休眠错误。

我在您的代码中发现以下问题:

  • 没有#include 的库。我猜你是故意漏掉的。
  • void read() 空括号在 C 中是过时的风格(但在 C++ 中非常好)。在编写 C 代码时,您应该始终使用 void read (void)
  • cube[4] = "cube" C 中的字符串以空值结尾。你没有分配足够的空间。研究这个:How should character arrays be used as strings?
  • void cube(); 等等。我不知道你认为这是做什么的,调用一个函数?这不是你调用函数的方式。此外,由于您有一个名为cube 的局部范围变量,您会遇到命名冲突。所以函数必须使用不同的名称。
  • free(line); 不允许在未使用 malloc 分配的内存上使用 free。只需删除此行即可。
  • 在返回 void 的函数中,return; 不是必需的。

【讨论】:

  • 我已经包含了这些库,但这只是我程序中的一个功能; void 已被删除 - 这是一个错误(对不起!)我只是收到一个错误,说它不是函数或函数指针......
  • 我还删除了 4 等,因为我意识到这很愚蠢,我是 C 新手,在此过程中会犯一些错误..!自从我使用 malloc 以来,Free(line) 意外地留在那里。至于退货;指导 - 知道这非常有用,谢谢!
【解决方案4】:

所有 C 风格的字符串都必须以“\0”结尾。 对应的代码一定是这样的:

const char* cube= "cube";
const char* cone = "cone";
const char* sphere = "sphere";
const char* cylinder = "cylinder";

cube 是 const char 指针。 顺便说一句,“立方体”通常存储在程序的代码段或堆栈中,这取决于编译器。无论哪种方式,它都指向一个以 null 结尾的字符数组。

【讨论】:

  • 还有更多问题。
【解决方案5】:

其他人在您的示例中展示了一些语法错误,但没有人解决逻辑错误。您的代码(无语法错误)读取文件的每一行,并在该行包含某些子字符串时做出反应。

这意味着,如果一行文本包含单词“iconography”(原文如此),这将触发您的“锥形”处理逻辑。此外,如果一行包含单词“cube”和“cone”,那么只有你的多维数据集逻辑会触发。

要克服这个问题,您需要将行拆分为单个单词。您可以通过扫描空格并一次处理一个单词来完成此操作。

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

// warning, this code is untested, but should send you in the right direction

char *find_word(char *input)
{
    while (isspace(input) && *input != '\0')
    {
        input += sizeof(char);
    }
    return input;
}

char *find_whitespace(char *input)
{
    while (!isspace(input) && *input != '\0')
    {
        input += sizeof(char);
    }
    return input;
}

void process_word(char *word, size_t len)
{
    if (strncmp(start, "cube", len) == 0)
    {
        // do something
    }
    else if (strncmp(start, "cone", len) == 0)
    {
        // do something
    }
    else if (strncmp(start, "sphere", len) == 0)
    {
        // do something
    }
    else if (strncmp(start, "cylinder", len) == 0)
    {
        // do something
    }
}

int main(int argc, char *argv[])
{
    FILE *fp = fopen(argv[1]);
    char line[1024];

    while (fgets(line, sizeof(line), fp) != NULL)
    {
        char *cursor = line;
        while (*cursor != '\0')
        {
            char *start = find_word(line);
            char *end = find_whitespace(start);
            process_word(start, end - start);
            cursor = end;
        }
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-07-01
    • 1970-01-01
    • 2011-08-12
    • 1970-01-01
    • 1970-01-01
    • 2014-08-02
    • 1970-01-01
    相关资源
    最近更新 更多