自动换行功能
大家好,我正在用 C++ 编写一个自动换行函数来格式化控制台文本。 我的问题是 A) 我不完全理解 std::string::iterators 的作用,或者 B) 我的迭代器之一没有正确设置。 任何人都可以阐明此代码失败的原因吗?
顺便说一句:抱歉,如果这涉及到太多细节。 我不确定大多数程序员(我是“新手”)是否在他们的机器上安装了 C++ 编译器。
std::string wordWrap(std::string sentence, int width)
{
//this iterator is used to optimize code; could use array indice
//iterates through sentence till end
std::string::iterator it = sentence.begin();
//this iterator = it when you reach a space; will place a newline here
//if you reach width;
std::string::iterator lastSpace = sentence.begin();
int distanceToWidth = 0;
while (it != sentence.end())
{
while (it != sentence.end() && distanceToWidth < width)
{
if (*it == ' ')
{
lastSpace = it;
}
distanceToWidth++;
it++;
}
distanceToLength = 0;
*lastSpace = '\n';
//skip the space
if (it != sentence.end())
{
it++;
}
}
return sentence;
}
我没有得到正确的输出。 假设我这样称呼它:
std::cout << wordWrap("a b c abcde abcdef longword shtwd", 5) << std::endl << std::endl;
std::cout << wordWrap("this is a sentence of massive proportions", 4) << std::endl;
我得到的输出不令人满意:
a b
c
abcde
abcdef
longword
shtwd
//yes I get his, instead of this
his is
a
sentence
of
massive
proportions
Press any key to continue . . .
我的问题是,我在不适当的时候得到换行符。 我经常收到换行符,而且我没有看到任何明显的错误来解释为什么会这样。 我希望独立的人(我在这个算法上花了几个小时,没有得到正确的结果是相当令人沮丧的)可以看看它。 另外,有什么明显的优化技巧吗?
Hey guys, I'm writing a word wrap function to format console text in C++. My problem is either A) I don't understand exactly what std::string::iterators do, or B) one of my iterators is not being set properly. Can anyone shed some light on the reason this code fails?
by the way: sorry if this goes into too much detail. I'm not sure if most programmers (I'm a "newbie") have a C++ compiler installed on their machine.
std::string wordWrap(std::string sentence, int width)
{
//this iterator is used to optimize code; could use array indice
//iterates through sentence till end
std::string::iterator it = sentence.begin();
//this iterator = it when you reach a space; will place a newline here
//if you reach width;
std::string::iterator lastSpace = sentence.begin();
int distanceToWidth = 0;
while (it != sentence.end())
{
while (it != sentence.end() && distanceToWidth < width)
{
if (*it == ' ')
{
lastSpace = it;
}
distanceToWidth++;
it++;
}
distanceToLength = 0;
*lastSpace = '\n';
//skip the space
if (it != sentence.end())
{
it++;
}
}
return sentence;
}
I'm not getting correct output. Assuming I called it like this:
std::cout << wordWrap("a b c abcde abcdef longword shtwd", 5) << std::endl << std::endl;
std::cout << wordWrap("this is a sentence of massive proportions", 4) << std::endl;
I get unsatisfying output of this:
a b
c
abcde
abcdef
longword
shtwd
//yes I get his, instead of this
his is
a
sentence
of
massive
proportions
Press any key to continue . . .
My problem is that I'm am getting newlines when inappropiate. I am getting newlines too often, and I don't see any obvious error as to why that is. I was hoping someone independent (I've spent a few hours on this algorithm, and to not have the right results is quite frusturating) of the problem could look at it. Also, any obvious optimization tips?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
问题是单词 this 有 4 个字符,而您要换行为 4 个字符。 所以它试图在将lastSpace 设置为合理的值之前进行换行。
从单步执行代码的角度来看:
ETC
因此,我们输出一个额外的换行符,而不是“this”中的“t”
来修复它......好吧......你可以弄清楚
The problem is that the word this is 4 characters, and you are wrapping at four characters. So it is trying to wrap before it has set lastSpace to something reasonable.
Look at it from the point of stepping through the code:
ETC
Thus we output an extra newline instead of the "t" in "this"
about fixing it... well... you can figure it out
lastSpace
迭代器从sentence
的第一个字符开始:当到达“this is a...”的第五个字符(空格)时,内部 while 循环退出(因为
distanceToWidth == width
),在识别出当前字符是空格之前。 然后在lastSpace
位置插入换行符,该位置仍然指向字符串的第一个字符。 这样“this”的“t”就丢失了。接下来
distanceToWidth
重置为零,并附加另一个width
字符,尽管该行没有在当前位置分割,但之前的一些字符(在lastSpace
代码>)。 因此这一行最终可能包含比预期更多的字符。 在示例中,“is”仍然与“this”在同一行,但应换行到下一行。您可能需要:
<=
以便检查正确的宽度,lastSpace
初始化为字符串的第一个字符。 可能更好:distanceToWidth
The
lastSpace
iterator starts on the first character ofsentence
:When you reach the fifth character of "this is a..." (the space), the inner while loop exits (because
distanceToWidth == width
), before it is recognized that the current character is a space. Then a newline is inserted in positionlastSpace
, which still points to the first character of the string. This way the "t" of "this" is lost.Next
distanceToWidth
is reset to zero and anotherwidth
characters are appended, although the line was not split at the current position, but some characters before (atlastSpace
). So this line can end up containing more characters than expected. In the example, "is" is still on the same line as "this" while it should be wrapped to the next line.You probably need to:
<=
so that the correct width is checkedlastSpace
to the first character of the string. Probably better:distanceToWidth
after inserting a line break从代码显示的内容来看,您的输出是正确的。 你错的是算法。 使用调试器来找出实际发生的情况。
Your output is correct from what your code shows. What you got wrong is the algorithm. Use a debugger to find out what actually happens.
更新:这是我的最新代码,显示正确的输出。 如果您再次阅读本文,请发表评论。 很抱歉格式错误,但在每行前面添加四个空格很麻烦,而且现在是凌晨 1:45。
Update: here is my latest code, showing correct output. Please comment if you read this again. Sorry for bad formatting, but it's a hassle to add four spaces in front of each line and it is 1:45 AM.