我试图制作一个带有段落的功能,并显示每个单词的第一个字母。程序在我运行它的前几次运行正常,但在后续实例中,在函数执行后停止工作。这是代码:
//program that returns the first letter of each word in a paragraph
#include <iostream>
#include <string>
using namespace std;
void firstLetter(string, ostream&);
int main()
{
string paragraph;
cout<<"Enter a paragraph."<<endl;
getline(cin, paragraph);
firstLetter(paragraph, cout);
return 0;
}
void firstLetter(string words, ostream& out)
{
for(int i= 0; i < words.length(); i++){
out<<words[i++]<<" ";
while(words[i] != ' '){
i++;
}
}
}
我已经尝试删除.exe文件并重建项目,但它只是在几次运行后才会再次运行。知道为什么会这样吗?
答案 0 :(得分:3)
循环是问题。
for(int i= 0; i < words.length(); i++){
out<<words[i++]<<" ";
while(words[i] != ' '){
i++;
}
}
您在增量表达式i
)中递增i++
,但您也在out <<...
表达式中递增它。您的while循环可以访问此处的无效数据,因为您在上一次检查for循环后再次递增,以及每个跳过的字母。迟早,您在这里访问无效数据,导致未定义的行为,甚至是分段错误。
我希望你只想跳过最后一个字符(最后一个字就是这种情况),只想跳过非空格。这需要在while循环中进行另一次检查:
while(i < words.length() && words[i] != ' '){
i++;
}
像多个空格,破折号(如果你不想输出它)和其他花哨的排版东西仍然有问题...但我希望你不需要考虑这些情况。
答案 1 :(得分:2)
您需要检查i
循环中words
的大小是否超过while
。
while(i < words.length() && words[i] != ' '){
i++;
}
答案 2 :(得分:0)
同意leemes。 认为你有'你好,世界' 打印应该是'h w',然后是错误。因为没有''后'世界',导致while循环永远不会结束(并且到某个地方无效),相反,你有一个'\ 0'。 我建议你检查'\ 0'并返回你的功能。 喜欢:
while(words[i] != ' ' && words[i] != '\0')
{
i++;
}
(我猜你遇到的好案例应该是那些最后有空格的案例。)
答案 3 :(得分:0)
问题是当我超出字符串的边界时,内部循环是无穷无尽的。
void firstLetter(string words, ostream& out)
{
for(size_t i= 0, len = words.length(); ; i++){ // i < words.length() removed, it is checked in the inner loop
out<<words[i]<<" ";
while(words[i] != ' '){
if( i == len-1 ) return;
i++;
}
}
}
以下是我个人更喜欢使用的替代方案:
#include <sstream>
void firstLetter2(string words, ostream& out)
{
istringstream iss(words);
while( ! iss.eof() )
{
string sWord;
iss >> sWord >> ws;
out<<sWord[0]<<' ';
}
}