我必须编写一个C程序,输出文本的字数,并在下一行输出以元音或辅音开头和结尾的单词。
例如:
input
La bacalaureat la proba de Informatica a fost un subiect cu un sir de caractere
output
15
bacalaureat Informatica a fost subiect sir
这是我的程序:
#include <iostream>
#include <string.h>
using namespace std;
int main()
{
int c = 0;
char sir[100], copie[100];
cin.get(sir, 100);
strcpy(copie, sir);
char* pch = strtok(sir, " ");
while (pch != NULL)
{
c++;
pch = strtok(NULL, " ");
}
cout << c << endl;
char* pch2 = strtok(copie, " ");
while (pch2 != NULL)
{
if ((strchr("aeiouAEIOU", pch2[0]) && strchr("aeiouAEIOU", pch2[strlen(pch2)-1])) || (strchr("aeiouAEIOU", pch2[0] == NULL) && strchr("aeiouAEIOU", pch2[strlen(pch2)-1] == NULL)))
{
cout << pch2<<" ";
}
pch2 = strtok(NULL, " ");
}
}
但它给了我意想不到的输出。我得到:
15
La bacalaureat la proba de Informatica a fost un subiect cu un sir de caractere
我不明白为什么。这显然是因为如果,但在我看来还可以。
你能帮我修一下程序吗?我不明白发生了什么事。谢谢
if语句中使用的此子表达式
strchr("aeiouAEIOU", pch2[0] == NULL) && strchr("aeiouAEIOU", pch2[strlen(pch2)-1] == NULL)
是错误的。
必须有
strchr("aeiouAEIOU", pch2[0] ) == NULL && strchr("aeiouAEIOU", pch2[strlen(pch2)-1] ) == NULL
你可以用下面的方式编写更简单的if语句
if ( ( strchr( "aeiouAEIOU", pch2[0] ) == NULL ) ==
( strchr( "aeiouAEIOU", pch2[strlen(pch2)-1] ) == NULL ) )
但在任何情况下,创建源字符串的副本并使用strtok
都不是一个好方法。
最好使用标准的C函数strspn
和strcspn
来提取字符串中的单词而不更改它
可以将满足条件的单词存储在向量中。
这是一个示范节目。
#include <iostream>
#include <utility>
#include <vector>
#include <cstring>
#include <cctype>
int main()
{
const char *s = "La bacalaureat la proba de Informatica "
"a fost un subiect cu un sir de caractere";
const char *vowels = "aeiou";
const char *delim = " t";
std::vector<std::pair<const char *, const char *>> v;
size_t n = 0;
for ( const char *p = s; *p != ' '; )
{
p += std::strspn( p, delim );
const char *q = p;
if ( *q )
{
++n;
p += std::strcspn( p, delim );
char c1 = std::tolower( ( unsigned char )q[0] );
char c2 = std::tolower( ( unsigned char )p[-1] );
if ( ( std::strchr( vowels, c1 ) == nullptr ) ==
( std::strchr( vowels, c2 ) == NULL ) )
v.emplace_back( q, p );
}
}
std::cout << n << 'n';
for ( const auto &p : v ) std::cout.write( p.first, p.second - p.first ) << ' ';
std::cout << 'n';
return 0;
}
其输出为
15
bacalaureat Informatica a fost subiect sir
以下是使用strchr
但使用std::istringstream
分解单词的程序版本:
#include <iostream>
#include <string>
#include <cstring>
#include <sstream>
#include <vector>
bool isvowel(char ch)
{
return strchr("aeiouAEIOU",ch)?true:false;
}
bool isconsonant(char ch)
{
return !isvowel(ch);
}
int main()
{
std::vector<std::string> sVect;
int word_count = 0;
std::string test = "La bacalaureat la proba de Informatica a fost un subiect cu un sir de caractere";
std::istringstream strm(test);
std::string word;
while (strm >> word)
{
++word_count;
if ( (isvowel(word.front()) && isvowel(word.back())) ||
(isconsonant(word.front()) && isconsonant(word.back())))
sVect.push_back(word);
}
std::cout << word_count << "n";
for (auto& s : sVect)
std::cout << s << " ";
}
输出:
15
bacalaureat Informatica a fost subiect sir
注意,元音或辅音的测试被放在不同的函数中,这样比较更容易。
还要注意使用std::string
类的front()
和back()
可以轻松地获得每个单词的第一个和最后一个字符,而不是在比较中重复调用strlen
。