首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >读取数组中的连续空格

读取数组中的连续空格
EN

Code Review用户
提问于 2019-02-24 11:48:54
回答 1查看 76关注 0票数 1

我正在编写一个函数,该函数读取字符串中的所有连续空格,将指针移动到下一个非空白字符,并返回包含它找到的空白的结构"token“。

主要功能被定义为

代码语言:javascript
复制
int match_ws(const char** p, struct token* tok)

其中,p指向要分析的字符串的开头,tok将在函数返回后包含结果。返回值要么是1(成功),要么是0。

match_ws开始分析作为第一个输入的字符串,并读取所有连续的空白空间,同时也推进指针。它存储它在struct中找到的所有空白(第二个输入)并返回1。如果没有找到任何空白,或者没有找到太多空白,则返回0而不修改tok

因此,如果输入是const char* p = " . +",那么在match_ws运行之后,tok结构将包含lexeme = " " ( p开头的四个空格,以及type = WS (“空格”的枚举类型)。如果输入是const char* p = ". ; )",则函数只返回0而不修改tok,因为**p不是空格(它是一个点)。

总的来说,这是解析器的一部分,match_ws是“消耗”所有空白空间的函数--与解析器无关。我相信这个函数的行为是正确的,但是由于我对C语言没有经验,所以我想了解一下如何处理内存分配、指针、指针指针、函数定义等问题。

总的来说,我的问题涉及指针的正确使用、指针到指针的正确使用、参数类型(函数定义)的良好选择以及内存管理。

我在评论中写了我的问题,但我不太习惯C中的内存管理和编码标准,所以我希望能对代码进行审查,并欢迎所有建议。

我还添加了一些样板代码,以便可以编译和执行文件。您可以猜到,它是较大代码的一部分,但我将其简化为一个最小的示例。

代码语言:javascript
复制
#include 
#include 

#define MAX_LINE 100

/*
 * Some boilerplate code
*/
enum token_type {
    WS, // white spaces
    Eof
};

struct token{
    char* lexeme;
    enum token_type type;
};

char consume(const char** p);

/*
 * Main function to work on.
 * Questions:
 * - char ws[MAX_LINE] or using malloc?
 * - is it OK to initialize char ws with "" ?
 * - Am I appending char into ws in a optimal way?
 * - is it OK to return int and modify input argument tok, or should create a new tok and return it?
 * - makes sense to have pointer-to-pointer as input? Else what?
*/
int match_ws(const char** p, struct token* tok) {
    /*
     * Find all consecutives blanks starting from position p
     * Modify the input struct token.
     * Return 1 if execution was successful, 0 otherwise.
    */
    if ( **p != ' ' &&
         **p != '\t' &&
         **p != '\r' &&
         **p != '\n')
    {
        printf("Bad call to whitespace!!");
        return 0;
    }
    int i = 0;
    char c;
    char ws[MAX_LINE] = "";
    do {
        if (i >= MAX_LINE) {
            printf("Found more than %d white spaces", MAX_LINE);
            return 0;
        }
        c = consume(p);
        printf("WHITESPACE : Current char is |%c|\n", c);
        ws[i++] = c;
    }
    // Here p has been already advanced by the call to consume fn
    while (**p == ' ' || **p == '\t' || **p == '\r' || **p == '\n');
    tok->lexeme = ws;
    tok->type = WS;
    return 1;
}

/*
 * More boilerplate code to compile
*/
const char* type2char (enum token_type t) {
    switch (t)
    {
        case WS: return "WS";
        default: return "UNK";
    }
}

void print_token(struct token* p) {
    printf("<%s, %s>\n", p->lexeme, type2char(p->type));
}

char consume(const char** p) {
    // Advances the pointer while reading the input
    char c = **p;
    (*p)++;
    return c;
}

/*
 * Main.
 * Questions:
 * - is it OK to pass arguments to match_ws via '&' notation?
 * - Makes sense to have const char* line? Or just char* ?
 * - Should tok be initialized somehow?
 * - Is there anything that has to be free() eventually?
*/
int main() {

    const char* line = "     +";
    struct token tok;
    match_ws(&line, &tok);
    print_token(&tok);
}
EN

回答 1

Code Review用户

发布于 2022-07-15 21:19:44

问题的回答

  • char ws[MAX_LINE]还是使用malloc

函数match_ws()应该返回指向struct token的指针。令牌应该由match_ws()函数分配,令牌的内容也应该使用malloc()来分配token->lexeme指向的字符串。现在,代码返回堆栈上一个变量的地址,这是不安全的,可能导致undefined行为 (UB)。

  • ws初始化char D19可以吗?

""初始化char数组是可以的。若要初始化单个字符,请使用单引号。

  • 我是否以最优的方式将char添加到ws中?

使用指针将是更理想的。

  • 返回int和修改输入参数tok可以吗?还是应该创建一个新的tok并返回它?

见第一个问题的答案。

  • 把指针对指针作为输入是有意义的吗?否则什么?

与其使用双指针,不如使用单个指针。当输入是双指针时,可能会损坏它。

  • 通过'&‘符号将参数传递给match_ws可以吗?

如果不想在函数中分配令牌,则使用&标记传递令牌参数是可以的,最好不使用&标记传递D56

  • 拥有const char*线有意义吗?还是只有char*

在这里使用const是合适的。

  • 应该以某种方式初始化tok吗?

C编程语言是一种非常不可原谅的编程语言:所有变量都应该初始化。

  • 有什么东西最终必须是free()的吗?

不是在目前的实现中。

--不要重新发明车轮

在C编程语言中,检查输入字符的值是非常常见的;为检查空格提供了一个函数,为检查字母数字字符提供了另一个函数。您需要做的是包括。这样做的好处是,当前代码可能遗漏了一些isspace()会找到的空白字符。

代码组织

函数原型在包含多个源文件的大型程序中非常有用,如果它们位于头文件中,则非常有用。在这样的单个文件程序中,最好将main()函数放在文件的底部,并以高于main()的适当顺序使用所有函数。请记住,编写的每一行代码都是另一行代码,bug可以在这一行代码中爬行。

票数 2
EN
页面原文内容由Code Review提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://codereview.stackexchange.com/questions/214162

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档