当前位置: 首页 > 知识库问答 >
问题:

使用指向字符的指针并编写用于分隔文本单词的函数

陆耀
2023-03-14

我想写一个函数,它将把一个指向char的指针和一个int(扫描开始索引)作为输入,并返回它之后的第一个单词。这个代码有什么问题?没有字返回。创建了从何处包含分隔符之一的问题。涂鸦字符。


char *setWord(char string[], int *n) {
    char word[20] = "\0";
    string += *n;
    while (*string == ','||*string == '\t' || *string == '\n'
    || *string == ' '|| *string == '.' || *string == '!' || *string == '?') {
        string++;
       (*n)++;
    }
    int i = 0;
    while (*string != ',' && *string != '\t'
                     && *string != '\n' && *string != ' ' &&
                     *string != '.' && *string != '!' &&
                     *string != '?') {
        word[i] = *string;
        string++;
        (*n)++;
        i++;
    }
    char *words = word;


    return words;
}

共有2个答案

孟安民
2023-03-14

您希望从函数返回一个C字符串([指向]以null结尾的字符数组的指针)。问题是数组不是C中的第一类对象,所以只能传递和返回指针。任何自动数组都将在声明它的块的末尾达到其生命周期的终点。因此,如果您很好地将word构建成一个自动数组,并返回指向它的指针(当前代码所做的),那么当函数返回时只留下一个悬空的指针,数组就会被破坏。

有两种可能的方法,每种方法都有其优缺点:

>

它可以是递归的和线程安全的。简单地说,您必须记录调用者将负责释放内存块,以及它应该如何完成:如果您使用malloc删除[]如果您使用new[]

使用静态记忆

一个快速解决方法是写:

static char word[20];

静态数组将持续到程序结束,因此您可以在调用者中安全地使用它,不需要清理。但是在多线程程序中,静态数组将在所有线程之间共享,因此您必须确保只有一个线程在同一时间使用它,并且当您想要使用它时,另一个线程没有更改它。长话短说:如果该函数预计将在多线程程序中使用,请不要使用该函数。

鄢禄
2023-03-14

如注释中所述,由于返回了指向局部变量(words)的指针,因此没有UB。最初,循环中还有n,而不是(n*),后者也是UB。您需要在代码中进行错误检查,但以下操作仍然有效,并且仍然坚持使用char*(无错误检查):

#include <string>
#include <iostream>

char *setWord( char string[], int *n ) {
    char word[20] = { 0 };
    string += *n;
    while ( *string == ',' || *string == '\t' || *string == '\n' || *string == ' ' || *string == '.' || *string == '!' || *string == '?' ) {
        string++;
        ( *n )++;
    }
    int i = 0;
    while ( *string != ',' && *string != '\t' && *string != '\n' && *string != ' ' && *string != '.' && *string != '!' && *string != '?' ) {
        word[i++] += *string;
        string++;
        ( *n )++;
    }

    std::cout << word;
    char *words = new char[i + 1];
    strncpy( words, word, I + 1 );

    return words;
}

int main() {
    char str[] = "hello world!";
    int n = 5;
    char *word = setWord( str, &n );

    delete[] word;

    return 0;
}

使用std::字符串,可以进行(无错误检查):

std::string setWord( std::string string, int *n ) { // copy on purpose
    int start = *n;
    *n = string.length();
    size_t end = string.find_last_of( ",\t\n .!?" );
    string = string.substr( string.find_first_not_of( ",\t\n .!?", start ) );
    if ( end != std::string::npos ) {
        string = string.substr( 0, string.find_last_of( ",\t\n .!?" ) ); // because it's not end
        *n = (int)end;
    }
    std::cout << string;
    return string;
}
 类似资料:
  • 主要内容:到底使用字符数组还是字符串常量C语言中没有特定的字符串类型,我们通常是将字符串放在一个字符数组中,这在《 C语言字符数组和字符串》中已经进行了详细讲解,这里不妨再来演示一下: 运行结果: https://www.xnip.cn https://www.xnip.cn 字符数组归根结底还是一个数组,上节讲到的关于 指针和数组的规则同样也适用于字符数组。更改上面的代码,使用指针的方式来输出字符串: 运行结果: https://ww

  • 一个函数总是占用一段连续的内存区域,函数名在表达式中有时也会被转换为该函数所在内存区域的首地址,这和数组名非常类似。我们可以把函数的这个首地址(或称入口地址)赋予一个 指针变量,使指针变量指向函数所在的内存区域,然后通过指针变量就可以找到并调用该函数。这种指针就是 函数指针。 函数指针的定义形式为: returnType (*pointerName)(param list); returnType

  • 问题内容: 有没有机会从以字符串表示的函数名称中获取指向函数的指针?例如,这需要将某些函数作为参数发送给另一个函数。您知道某种元编程。 问题答案: Go函数是一等值。您无需恢复动态语言中的技巧。 操场 输出: 如果函数的选择取决于某些仅在运行时已知的值,则可以使用映射:

  • 我使用的是BennyBox频道上的ECS的一个修改版本(代码可以在这里找到),它在大多数情况下都能正常工作。但是,当我向组件添加std::string时,程序在退出时中止(当ECS类的析构函数被调用时),并显示消息:

  • 在下面的结构中,数组与指向字符的指针相比有什么好处: 或 我看到的一个优点是,使用更容易区分“未提供字符串”和“提供空字符串”,而且它比数组占用更少的空间。 此外,在这两种情况下,我可以初始化: 另一方面,我不能轻易地在上使用,它必须是分配内存上的有效指针。 那么,还有什么好处呢?

  • 本文向大家介绍C语言 函数指针(指向函数的指针)详解,包括了C语言 函数指针(指向函数的指针)详解的使用技巧和注意事项,需要的朋友参考一下 一个函数总是占用一段连续的内存区域,函数名在表达式中有时也会被转换为该函数所在内存区域的首地址,这和数组名非常类似。我们可以把函数的这个首地址(或称入口地址)赋予一个指针变量,使指针变量指向函数所在的内存区域,然后通过指针变量就可以找到并调用该函数。这种指针就