我正在使用C ++进行一项任务,旨在向我们传授有关对象和OOP的更多信息。以下是我的代码。它的要点是,用户输入一些输入,程序计算元音或辅音的数量(由用户选择),输入的字符总数以及行尾的总数。
我有三个问题:
countChars
函数的输出无限打印,以及输出询问用户是否有我想提出更多意见。countChars
功能无法正确计算EOL。我认为这很可能是因为我对EOL不熟悉。我如何在条件声明中表示?如果我想说,"如果它的值为' 0'"我会说,if (variable == 0)
。如果某个东西是EOL,我怎么告诉C ++增加?countChars
输出计数的随机,负值。我注意到值的变化取决于我输入的内容(EOL除外),但我不确定为什么我会得到负值。除了使用unsigned int
并初始化值之外,我不确定如何修复它。另外,我预见到有人告诉我使用getline函数,但我们有非常具体的使用cin.get
的说明(毕竟我们应该学习一些东西)所以请避免使用getline
的修补程序。
标题文件:
/*
+----------------------------------------+
| CountChars |
+----------------------------------------+
| -countVorC : Integer |
| -countEOL : Integer |
| -totalChars : Integer |
| -vowelCount : Boolean |
+----------------------------------------+
| <<constructor>> |
| CountChars() |
| +inputChars() : |
| +vowelCheck(characterToCheck : Boolean)|
| +setVowelCount(VorC : Character) |
| +getCountVorC() : Integer |
| +getCountEOL() : Integer |
| +getTotalChars() : Integer |
| +getVowelCount() : Boolean |
+----------------------------------------+
*/
using namespace std;
#ifndef COUNTCHARS_H
#define COUNTCHARS_H
class CountChars
{
private:
unsigned int countVorC;
unsigned int countEOL;
unsigned int totalChars;
bool vowelCount;
public:
CountChars();
void inputChars();
bool vowelCheck(char characterToCheck);
void setVowelCount(char VorC);
int getCountVorC();
int getCountEOL();
int getTotalChars();
bool getVowelCount();
};
#endif
实施档案:
#include <iostream>
#include <iomanip>
#include <string>
#include <cctype>
#include <cstdio>
#include "CountChars.h"
using namespace std;
CountChars::CountChars()
{
unsigned int countVorC = 0;
unsigned int countEOL = 0;
unsigned int totalChars = 0;
bool vowelCount = false;
}
void CountChars::inputChars()
{
int letter;
while ((letter = cin.get()) != EOF && letter != EOF){
if (vowelCount == true && (vowelCheck(letter) == true)) {
countVorC++;
}
else if (vowelCount == false && (vowelCheck(letter) == false)) {
countVorC++;
}
if (isalpha(letter)) {
totalChars++;
}
if (letter == '\n') {
countEOL++;
}
}
}
bool CountChars::vowelCheck(char characterToCheck)
{
characterToCheck = toupper(characterToCheck);
if ((isalpha(characterToCheck)) &&
(characterToCheck == 'A' || characterToCheck == 'E' ||
characterToCheck == 'I' || characterToCheck == 'O' ||
characterToCheck == 'U')) {
return true;
}
else {
return false;
}
}
void CountChars::setVowelCount(char VorC)
{
VorC = toupper(VorC);
if (VorC == 'V') {
vowelCount = true;
}
else {
vowelCount = false;
}
}
int CountChars::getCountVorC()
{
return countVorC;
}
int CountChars::getCountEOL()
{
return countEOL;
}
int CountChars::getTotalChars()
{
return totalChars;
}
bool CountChars::getVowelCount()
{
return vowelCount;
}
主:
#include <iostream>
#include <iomanip>
#include <string>
#include <cctype>
#include <cstdio>
#include "CountChars.h"
using namespace std;
void printCounts(CountChars);
int main()
{
char VorC;
char repeat = 'Y';
CountChars charCounter;
cout << "Welcome to the Character Counter Program!" << endl;
cout << "\nWould you want to count vowels or consonants?" << endl;
cout << "Type 'V' for vowels and 'C' for consonants: ";
cin >> VorC;
cout << endl;
while (toupper(VorC) != 'V' && toupper(VorC) != 'C') {
cout << "\nSorry, that was an invalid choice. Please try again: ";
cin >> VorC;
cout << endl;
}
do {
cout << "You may being typing input below.\n" << endl;
charCounter.setVowelCount(VorC);
charCounter.inputChars();
cin.clear();
printCounts(charCounter);
cout << "\nWould you like to enter new input?" << endl;
cout << "Type 'Y' for yes or 'N' for no: ";
cin >> repeat;
cout << endl;
while (toupper(repeat) != 'Y' && toupper(repeat) != 'N') {
cout << "\nSorry, that was an invalid choice. Please try again: ";
cin >> repeat;
cout << endl;
}
} while (toupper(repeat) == 'Y');
cout << "\nThank you for using the Character Counter Program!\n" << endl;
system("pause");
return 0;
}
void printCounts(CountChars charCounter)
{
cout << "\nTotal characters: " << charCounter.getTotalChars() << endl;
if (charCounter.getVowelCount() == true) {
cout << "Total vowels: " << charCounter.getCountVorC() << endl;
}
else {
cout << "Total consonants: " << charCounter.getCountVorC() << endl;
}
cout << "Total end-of-lines: " << charCounter.getCountEOL() << endl;
}
答案 0 :(得分:3)
cin.get()
返回int
你有:
char letter;
while ((letter = cin.get()) != EOF)
如果普通char
是无符号类型,就像在某些机器上一样,那么这将永远不会评估为true,因为值-1
(EOF的正常值)被分配给(无符号)char
,它被映射到0xFF,当0xFF
与int
(如EOF
(仍为-1
)进行比较时,答案是假,所以循环继续。
对此的修复是使用int letter
而不是char letter
。 (请注意,如果char
是带符号的类型,则代码存在不同的问题;然后,代码为0xFF的字符 - 通常是ÿ,y umlaut,U + 00FF,LATIN带有DIAERESIS的小写字母 - 被误解作为EOF。修复是相同的;使用int letter;
)。
在同一个功能中,你还有:
if (letter == EOF) {
countEOL++;
}
您知道letter
不是EOF(因为循环检查了它)。此外,你想要计算EOL,而不是EOF(每个文件只有一个EOF,但如果你继续尝试超过EOF读取,你将重复返回EOF)。你可能需要:
if (letter == '\n') {
countEOL++;
}
或者您可能想要定义EOL并与之比较:
const int EOL = '\n';
if (letter == EOL) {
countEOL++;
}
cin
将换行符留在输入在代码中:
cout << "Type 'V' for vowels and 'C' for consonants: ";
cin >> char(VorC);
cout << endl;
while (toupper(VorC) != 'V' && toupper(VorC) != 'C') {
cout << "\nSorry, that was an invalid choice. Please try again: ";
cin >> char(VorC);
cout << endl;
}
第一个cin
操作会在输入流中保留换行符。如果使用键入'Y',比如说,那么下一个cin
操作(在循环内)将读取换行符,并且因为换行符既不是'V'也不是'C',它会再次抱怨(但是然后等待更多输入。)
添加#include <limits>
并使用:
cin.ignore(numeric_limits<streamsize>::max(), '\n');
阅读过去换行。
同样,这不是整个问题。
cin
最后一部分,我想......
您注释掉的代码是:
/*do {
cout << "You may being typing input below.\n" << endl;*/
charCounter.setVowelCount(VorC);
charCounter.inputChars();
/*cout << "Would you like to enter new input?";
cout << "Type 'Y' for yes or 'N' for no: " << endl;
cin >> char(repeat);
cout << endl;
while (toupper(repeat) != 'Y' && toupper(repeat) != 'N') {
cout << "\nSorry, that was an invalid choice. Please try again: ";
cin >> char(repeat);
cout << endl;
}
} while (toupper(repeat) == 'Y');*/
请注意,在charCounter.inputChars()
到达cin
之前,EOF
的来电不会停止。此时没有任何输入,因此循环中的cin
(被注释掉)将每次都失败,从不生成'Y'。您需要清除cin
上的错误,以便输入更多数据,例如“更多输入”问题的答案。
我想知道你是否在阅读代码中混淆了EOL和EOF。也许你打算只读到行的末尾而不是文件的末尾。然后你的循环条件(我先提到的那个)应该是:
int letter;
while ((letter = cin.get()) != EOF && letter != '\n') // Or EOL if you define EOL as before
你应该随时准备好任何输入操作,以便在你没有真正期望的时候返回EOF,就像这里一样。
乐观主义者!上一部分不是最后一部分。
但我仍然有打印垃圾的问题。例如,它表示总字符数:-85899345。
我尝试编译你的代码:
$ g++ -O3 -g -std=c++11 -Wall -Wextra -Werror -c CountChars.cpp
CountChars.cpp: In constructor ‘CountChars::CountChars()’:
CountChars.cpp:13:18: error: unused variable ‘countVorC’ [-Werror=unused-variable]
unsigned int countVorC = 0;
^
CountChars.cpp:14:18: error: unused variable ‘countEOL’ [-Werror=unused-variable]
unsigned int countEOL = 0;
^
CountChars.cpp:15:18: error: unused variable ‘totalChars’ [-Werror=unused-variable]
unsigned int totalChars = 0;
^
CountChars.cpp:16:10: error: unused variable ‘vowelCount’ [-Werror=unused-variable]
bool vowelCount = false;
^
cc1plus: all warnings being treated as errors
$
您已在构造函数中声明了隐藏类成员的局部变量,因此构造函数实际上并没有实际构造。垃圾数字是因为你从垃圾开始。
cin >> char(VorC)
无法在任何地方编译同样,当我尝试编译Main.cpp
时,我遇到错误:
$ g++ -O3 -g -std=c++11 -Wall -Wextra -Werror -c Main.cpp
Main.cpp: In function ‘int main()’:
Main.cpp:18:9: error: ambiguous overload for ‘operator>>’ (operand types are ‘std::istream {aka std::basic_istream<char>}’ and ‘char’)
cin >> char(VorC);
^
Main.cpp:18:9: note: candidates are:
In file included from /usr/gcc/v4.9.1/include/c++/4.9.1/iostream:40:0,
from Main.cpp:1:
/usr/gcc/v4.9.1/include/c++/4.9.1/istream:120:7: note: std::basic_istream<_CharT, _Traits>::__istream_type& std::basic_istream<_CharT, _Traits>::operator>>(std::basic_istream<_CharT, _Traits>::__istream_type& (*)(std::basic_istream<_CharT, _Traits>::__istream_type&)) [with _CharT = char; _Traits = std::char_traits<char>; std::basic_istream<_CharT, _Traits>::__istream_type = std::basic_istream<char>] <near match>
operator>>(__istream_type& (*__pf)(__istream_type&))
^
/usr/gcc/v4.9.1/include/c++/4.9.1/istream:120:7: note: no known conversion for argument 1 from ‘char’ to ‘std::basic_istream<char>::__istream_type& (*)(std::basic_istream<char>::__istream_type&) {aka std::basic_istream<char>& (*)(std::basic_istream<char>&)}’
/usr/gcc/v4.9.1/include/c++/4.9.1/istream:124:7: note: std::basic_istream<_CharT, _Traits>::__istream_type& std::basic_istream<_CharT, _Traits>::operator>>(std::basic_istream<_CharT, _Traits>::__ios_type& (*)(std::basic_istream<_CharT, _Traits>::__ios_type&)) [with _CharT = char; _Traits = std::char_traits<char>; std::basic_istream<_CharT, _Traits>::__istream_type = std::basic_istream<char>; std::basic_istream<_CharT, _Traits>::__ios_type = std::basic_ios<char>] <near match>
operator>>(__ios_type& (*__pf)(__ios_type&))
^
…
$
这里的问题是:
cin >> char(VorC);
你真的不想在那里演员:
cin >> VorC;
你可以说应该检查输入是否有效:
if (!(cin >> VorC)) …process EOF or error…
同样的问题当然会影响cin >> char(repeat);
。
我不知道为什么要为你编译;它不应该这样做。有了这个固定,它有点工作。我遇到了'换行中的换行符',所以inputChars()
函数在EOL等之前得到了零个字符。现在由你来处理。