为什么代码打印所有第一个索引?

时间:2013-01-27 15:18:44

标签: c++ string file

我正在尝试编写一个程序,将文本文件中的单词转换为pig Latin。我得到了代替文本文件的单词的代码,但我现在很困难,试图解决它们。当我运行此代码时,它始终打印所有单词的第一个索引,而不是与if语句匹配的单词

void wordpro(string sent)
{
  string word;

  istringstream iss(sent, istringstream::in);
  while (iss>> word)
  if (word[0] == 'a'||'e'||'i'||'o'||'u'||'A'||'E'||'I'||'O'||'U')
  {
    cout<< word[0] <<endl;
    }
}

2 个答案:

答案 0 :(得分:10)

if (word[0] == 'a'||'e'||'i'||'o'||'u'||'A'||'E'||'I'||'O'||'U')

这不是||在C ++中的工作方式。但意味着上述操作会导致编译错误。不,从编译器的角度来看,这是正确的;唯一的问题是它不会做你打算它做的事情!相反,条件将始终为true。这就是为什么它打印代码中所有单词的第一个字符。

要获得您的意图,您必须将||写为:

if (word[0] == 'a'|| word[0] == 'e'|| word[0] ==  'i' || ... so on)

也就是说,你必须分别比较每个角色。这肯定是令人恼火的。


C ++ 11已经为您节省了时间,因此您可以将std::any_of用作:

//C++11 only

std::string const v = "aeiouAEIOU";
if (std::any_of(v.begin(), v.end(), [](char c){ return word[0] == c;}) 

或者您可以将std::find用作:

//C++03 and C++11 both

if ( std::find(v.begin(), v.end(), word[0]) != v.end() )

比前一个略短。而且,这也适用于C ++ 03!


或者您可以将std::count用作:

//C++03 and C++11 both

if ( std::count(v.begin(), v.end(), word[0]) ) 

甚至更短。


或者您可以将std::string::find用作:

//C++03 and C++11 both

if ( v.find(word[0]) != std::string::npos)

这是最短的!


阅读文档,了解每个人的真实情况,以及为什么它适用于您的案例:

希望有所帮助。

答案 1 :(得分:0)

使用大量word[0] == 'a' || word[0] == 'e' || ...的上述建议是正确的解决方案来“修复”你所写的内容,就像你对单个if语句所做的那样。

你可以这样做:

 switch(word[0])
 {
    case 'a':
    case 'e':
    case 'i':
    ... /// you'll have to fill the rest in yourself. 
        cout << word[0]; 
        break; 
 } 

或者你可以使用老式的C风格strchr

if (strchr("aeiouAEIOU", word[0]) != NULL)
{
    cout << word[0];
}

也可能有其他六种解决方案。这一切都取决于你喜欢什么样的“风格”。我可能会把开关作为我的第一选择。