gpt4 book ai didi

c++ - 使用字符指针拆分单词中的句子

转载 作者:行者123 更新时间:2023-11-27 23:54:33 25 4
gpt4 key购买 nike

我正在开发一个将句子拆分为 2D 指针的系统。

我不想使用任何类型的库或其他方式(如字符串),因为我想练习指针并学习它们。

char** sscanf(char* hstring)
{
int count = 0;
char* current = hstring;
while (*current)
{
if (*current == ' ')
{
count++;
}
while (*current == ' ')
{
current++;
}
if (*current)
break;
current++;
}
char** result = new char*[count];
current = hstring;
char* nstr = new char;
int c = 0, i = 0;
while (*current)
{
if (!*current) break;
cout << "t1";
if (*current == ' ')
{
*(++result) = nstr;

nstr = nullptr;
nstr = new char;
}
cout << "t2";
while (*current != '/0' && *current == ' ')
{
current++;
}
cout << "t3";
while (*current != '/0' && *current != ' ')
{
if (!*current) break;
*(++nstr) = *current;
current++;
}
cout << "t4";
*nstr = '/0';
cout << "t5";
}
return result;
}

但这很奇怪,有时会将我重定向到

static size_t __CLRCALL_OR_CDECL length(_In_z_ const _Elem * const _First) _NOEXCEPT // strengthened
{ // find length of null-terminated string
return (_CSTD strlen(_First));
}

错误:Acces Violation,其他时候,选择一条随机线并将其命名为 Acces Breakout(对不起,如果我拼错了)

我想从你这里得到的不是简单地修复我的代码,我想要一些解释,因为我想学习这些东西。

最佳答案

首先,一些建议

我知道您将此功能作为练习,但作为 C++,我想警告您 new char*[count] 之类的东西是不良做法 这就是创建 std::vectorstd::array 的原因。

您似乎对动态分配的工作原理感到困惑。 char* nstr = new char; 语句将只在堆内存中创建一个字节 (char),并且什么都没有保证与它相邻。这意味着 ++nstr 是一个“无效”操作,我的意思是,它使 nstr 指向分配的字节之后的下一个字节,这可能是一些随机无效的位置。

您的代码中还有很多其他危险操作,例如多次调用 new(保留内存)而不调用 delete 当你不再使用保留内存时(又名内存泄漏)。话虽如此,我强烈建议你研究这个主题,例如从 ISO C++ FAQ on memory management 开始。 .

此外,在深入研究指针和动态分配之前,您应该更熟悉语句和流控制。我这样说是因为我看到了一些明显的误解,例如:

while (*current) {
if (!*current) break;
...
}

if 语句中的检查肯定是假的,因为 while 检查就在它之前执行并保证相反的条件为真。这意味着这个 if 永远不会被评估为 true,它完全没有用。

另一点是:不要将您的函数命名为与标准库相同的sscanf 已被采用,请选择另一个(更有意义的)。这将为您将来省去一些麻烦;用于正确命名您自己的函数。

指导性解决方案

我心情很好,所以我将在这里完成一些步骤。无论如何,如果有人正在寻找优化且准备就绪的解决方案,请参阅 Split a String in C++ .

0。定义步骤

阅读您的代码,我可以猜出您需要的一些步骤:

char** split_string(char* sentence)
{
// Count the number of words in the sentence
// Allocate memory for the answer (a 2D buffer)
// Write each word in the output
}

与其尝试一下子把它们都弄好,不如一个一个地尝试? (注意函数和参数的名称,在我看来更清晰)。

1。数数

您可以从一个简单的 main() 开始,测试您的解决方案。这是我的(对不起,我不能只是适应你的)。对于那些优化上瘾的人来说,这不是一个优化的解决方案,而是一个简单的 OP 片段。

// I'll be using this header and namespace on the next snippets too.
#include <iostream>
using namespace std;

int main()
{
char sentence[] = " This is my sentence ";

int n_words = 0;
char *p = sentence;
bool was_space = true; // see logic below

// Reading the whole sentence
while (*p) {
// Check if it's a space and advance pointer
bool is_space = (*p++ == ' ');
if (was_space && !is_space)
n_words++; // count as word a 'rising edge'
was_space = is_space;
}

cout << n_words;
}

对其进行测试,确保您了解其工作原理。现在,您可以进入下一步。

2。分配缓冲区

好吧,你想为每个单词分配一个缓冲区,所以我们需要知道每个单词的大小(我不会讨论这是否是解决句子拆分问题的好方法......)。这不是在上一步中计算的,所以我们现在可能会这样做。

int main()
{
char sentence[] = " This is my sentence ";

///// Count the number of words in the sentence

int n_words = 0;
char *p = sentence;
bool was_space = true; // see logic below

// Reading the whole sentence
while (*p) {
// Check if it's a space and advance pointer
bool is_space = (*p++ == ' ');
if (was_space && !is_space)
n_words++; // count as word a 'rising edge'
was_space = is_space;
}

///// Allocate memory for the answer (a 2D buffer)

// This is more like C than C++, but you asked for it
char **words = new char*[n_words];
char *ini = sentence; // the initial char of each word

for (int i = 0; i < n_words; ++i) {
while (*ini == ' ') ini++; // search next non-space char
char *end = ini + 1; // pointer to the end of the word
while (*end && *end != ' ') end++; // search for \0 or space
int word_size = end - ini; // find out the word size by address offset
ini = end; // next for-loop iteration starts
// at the next word
words[i] = new char[word_size]; // a whole buffer for one word
cout << i << ": " << word_size << endl; // debugging
}

// Deleting it all, one buffer at a time
for (int i = 0; i < n_words; ++i) {
delete[] words[i]; // delete[] is the syntax to delete an array
}
}

请注意,我正在删除 main() 中分配的缓冲区。当您将此逻辑移动到您的函数时,此释放将由函数的调用者执行,因为它可能会在删除缓冲区之前使用缓冲区。

3。将每个单词分配给它的缓冲区

我想你明白了。分配单词并将逻辑移动到分离的函数。用 Minimal, Complete, and Verifiable example 更新您的问题如果您还有问题。

我知道这是一个问答论坛,但我认为这已经是对 OP 和可能通过此处的其他人的健康回答。如果我应该做出不同的回答,请告诉我。

关于c++ - 使用字符指针拆分单词中的句子,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43559794/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com