首先,一些建议
我知道您将此函数作为练习,但作为 C++,我想警告您,new char*[count] 之类的东西是不好的做法,这就是为什么 std::vector 或 @987654327 @ 已创建。
您似乎对动态分配的工作原理感到困惑。 语句char* nstr = new char; 将只在堆内存中创建一个字节 (char),并且不能保证与它相邻。这意味着++nstr 是一个“无效”操作,我的意思是,它使nstr 指向分配的字节之后的下一个字节,这可能是一些随机的无效位置。
您的代码中还有很多其他危险操作,例如多次调用new(保留内存)并且在您不再使用保留的内存时不调用delete内存(又名内存泄漏)。话虽如此,我强烈建议您学习这个主题,例如从ISO C++ FAQ on memory management 开始。
另外,在深入研究指针和动态分配之前,您应该更熟悉语句和流控制。我这样说是因为我看到了一些明显的误解,比如:
while (*current) {
if (!*current) break;
...
}
if 语句中的检查肯定是假的,因为while 检查在它之前执行,并保证相反的条件为真。这意味着这个if 永远不会被评估为真,它完全没用。
另外一点是:不要将你的函数命名为与标准库相同。 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 sn-p。
// 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 和其他可能通过这里的人的健康回答。让我知道我是否应该以不同的方式回答。