我是新来的,这是我的第一个问题,所以不要太苛刻:]
我试图反驳一个句子,即每个单词分开。 问题在于我无法达到第二个单词,甚至达不到单个单词的结尾。有什么问题?
char* reverse(char* string)
{
int i = 0;
char str[80];
while (*string)
str[i++] = *string++;
str[i] = '\0'; //null char in the end
char temp;
int wStart = 0, wEnd = 0, ending = 0; //wordStart, wordEnd, sentence ending
while (str[ending]) /*@@@@This part just won't stop@@@@*/
{
//skip spaces
while (str[wStart] == ' ')
wStart++; //wStart - word start
//for each word
wEnd = wStart;
while (str[wEnd] != ' ' && str[wEnd])
wEnd++; //wEnd - word ending
ending = wEnd; //for sentence ending
for (int k = 0; k < (wStart + wEnd) / 2; k++) //reverse
{
temp = str[wStart];
str[wStart++] = str[wEnd];
str[wEnd--] = temp;
}
}
return str;
}
答案 0 :(得分:2)
您的代码对于C ++来说有点单一,因为它实际上并没有使用许多常见且方便的C ++工具。在您的情况下,您可以受益于
std::string
负责维护足够大的缓冲区来容纳你的字符串数据。std::istringstream
可以轻松地将字符串拆分为空格。std::reverse
可以反转一系列项目。这是使用这些功能的替代版本:
#include <algorithm>
#include <iostream>
#include <iterator>
#include <sstream>
#include <vector>
std::string reverse( const std::string &s )
{
// Split the string on spaces by iterating over the stream
// elements and inserting them into the 'words' vector'.
std::vector<std::string> words;
std::istringstream stream( s );
std::copy(
std::istream_iterator<std::string>( stream ),
std::istream_iterator<std::string>(),
std::back_inserter( words )
);
// Reverse the words in the vector.
std::reverse( words.begin(), words.end() );
// Join the words again (inserting one space between two words)
std::ostringstream result;
std::copy(
words.begin(),
words.end(),
std::ostream_iterator<std::string>( result, " " )
);
return result.str();
}
答案 1 :(得分:1)
在第一个单词结尾处,经过它后,str [wEnd]是一个空格, 当你指定ending = wEnd时,你会记住这个索引。 立即,你反转单词中的字符。在那时候, str [结束]不是空格,因为你在空格中包含了空格 字母颠倒了。
取决于是否有额外的 在其余输入中的单词之间的空格,执行从这一点开始变化,但它最终以 你在字符串上反转以null终结符结束的单词 因为你结束了在那个空终结符上增加wEnd的循环 把它包括在最后的单词反转中。
下一次迭代走了 输入字符串的初始化部分和执行是从那里确定的,因为,哎呀,谁知道该数组中的内容(str是堆栈分配的,所以它不管怎么样?此时堆栈占用的内存)。
除此之外,除了在反转循环中,你不会更新wStart, 并且它永远不会一直向前移动(参见循环退出条件),所以来想一想,你永远不会超越第一个单词。假设已经修复,你仍然会遇到我最初概述的问题。
所有这些都假设你没有发送超过80个字符的这个函数,并以这种方式打破它。
哦,正如其中一条评论中所提到的那样,你将返回堆栈分配的本地存储,这也不会带来任何好处。
答案 2 :(得分:0)
在C ++中,如果可以,请使用std::string
代替char*
。
char[80]
,则 string
存在溢出风险;它应该动态分配。最好使用std::string
;否则使用new
/ new[]
。如果您打算使用C,那么malloc
。
cmbasnett还指出,如果以你的方式声明/分配它,你实际上不能返回str
(并获得预期的结果)。传统上,你传入char* destination
并且根本不在函数中分配任何东西。
将忽略这一点,我误读了while循环。ending
设为wEnd + 1
; wEnd
指向有问题的字符串的最后一个非空字符(最终,如果它正常工作),所以为了让str[ending]
突破循环,你必须增加一次才能获得对于null char。
您似乎需要使用((wEnd - wStart) + 1)
,而不是(wStart + wEnd)
。虽然在这种情况下你应该使用while(wEnd > wStart)
而不是for
循环。
你也应该在离开循环之前设置wStart = ending;
或其他东西,否则它会被卡在第一个单词上。