0

我正在尝试制作一个函数,该函数需要一个段落并显示每个单词的第一个字母。该程序在我运行它的前几次运行良好,但在随后的实例中,在函数执行后停止工作。这是代码:

//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 文件并重建项目,但它只是在运行几次后就不再工作了。知道为什么会这样吗?

4

4 回答 4

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++;
    }

多个空格、破折号(如果你不想输出它)和其他花哨的印刷内容仍然存在问题......但我希望你不需要考虑这些情况。

于 2013-01-05T02:15:26.497 回答
2

您需要检查i是否没有超过循环words中的大小。while

while(i < words.length() && words[i] != ' '){
    i++;
}
于 2013-01-05T02:25:11.540 回答
0

问题是当 i 超出字符串的范围时,内部循环是无限的。

  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]<<' ';
        }
    }
于 2013-01-05T02:33:15.153 回答
0

同意李梅。认为你有“你好,世界”,打印应该是“h w”,然后是错误。因为'world'之后没有'',导致while循环永远不会结束(并到达无效的地方),相反,你有一个'\0'。我建议你检查 '\0' 并返回你的函数。喜欢 :

while(words[i] != ' ' && words[i] != '\0') 
{
i++;
}

(我猜你遇到的优秀案例应该是那些最后有空间的案例。)

于 2013-01-05T02:23:22.757 回答