Ich versuche, mehrere Möglichkeiten in einer if-Anweisung zu überprüfen.
Der Benutzer gibt eine Zeichenfolge ein, und dann überprüfe ich diese Zeichenfolge auf mehrere Möglichkeiten.
if (theString == "Seven" || "seven" || "7")
{
theInt = 7;
cout << "You chose: " << theInt << endl;
}
else if (theString == "Six" || "six" || "6")
{
theInt = 6;
cout << "You chose: " << theInt << endl;
}
Also gibt es nur ein kurzes Beispiel dafür, was ich zu erreichen versuche. Irgendwelche Ideen?
Ich nehme an, dass der Typ der Variablen theString
ist std::string
. Ansonsten zumindest dieser Vergleich
theString == "Seven"
macht keinen Sinn,
Die Bedingung in der if-Anweisung
if (theString == "Seven" || "seven" || "7")
ist äquivalent zu
if ( ( theString == "Seven" ) || ( "seven" ) || ( "7" ) )
und gibt immer nach true
denn zumindest die Adresse des String-Literals "seven"
ist nicht gleich null. Also dieser Unterausdruck ( "seven" )
sorgt dafür, dass der gesamte Ausdruck gleich true ist.
Du solltest schreiben
if (theString == "Seven" || theString == "seven" || theString == "7")
Aber es wäre besser, den String zunächst in Groß- oder Kleinschreibung umzuwandeln.
Zum Beispiel
#include <algorithm>
#include <string>
#include <cstring>
//...
std::transform(theString.begin(), theString.end(), theString.begin(),
[](char c) { return std::toupper((unsigned char)c); });
if (theString == "SEVEN" || theString == "7")
{
theInt = 7;
cout << "You chose: " << theInt << endl;
}
else if ( theString == "SIX" || theString == "6" )
{
theInt = 6;
cout << "You chose: " << theInt << endl;
}
Verwenden std::set
und c ++ 11 können Sie einen Liner mit ähnlicher Syntax wie Ihrer erstellen.
Überprüfen Sie dies:
#include <iostream>
#include <string>
#include <set>
int main()
{
if( (std::set<std::string>{"Seven", "seven", "7"}).count("seven") )
{
std::cout << "foo\n";
}
std::string theString("6");
if( (std::set<std::string>{"Six", "six", "6"}).count(theString) )
{
std::cout << "bar\n";
}
}
Sie können eine Variable nicht wie in C++ mit mehreren Werten vergleichen. Sie sollten Folgendes tun:
if (theString == "Seven" || theString == "seven" || theString == "7")
{
theInt = 7;
cout << "You chose: " << theInt << endl;
}
else if (theString == "Six" || theString == "six" || theString == "6")
{
theInt = 6;
cout << "You chose: " << theInt << endl;
}
Dies ist ein klassisches Beispiel für die Identifizierung einer abgeleiteten Anforderung, die während der Implementierung gefunden wurde. Ich schlage vor, Sie erwägen, eine Funktion zu schreiben, um dies zu unterstützen.
Wechsel von
if (theString == "Seven" || "seven" || "7")
{
//....
(was kein gültiges C++ ist, weil die if-Bedingung immer wahr ist)
ändern
if (0 == compare(theString, "Seven", "seven", "7")
{
//....
und deklarieren und implementieren so etwas wie
// return 0 when theString matches at least one patX
// else return -1
int compare(const std::string& theString,
const char* pat0, // no default, must provide
const char* pat1 = nullptr,
const char* pat2 = nullptr,
const char* pat3 = nullptr,
const char* pat4 = nullptr
/* add as many patX as you desire */)
{
if (0 == theString.compare(pat0)) return 0; // found a match
//
// ignore nullptr patterns
if (nullptr != pat1) && (0 == theString.compare(pat1)) {
return(0);
}
if(nullptr != pat2) && (0 == theString.compare(pat2)) {
return(0);
}
// ...
// when get to end with no match
return (-1); // indicate no match to any of patterns
}
Eigentlich bevorzuge ich folgendes. Das obige ist so etwas wie strstr(), wo dies mehr Funktionalität von std::string verwendet
int compare(const std::string& theString, // what you are given
const std::string& patterns) // concatenated list of search patterns
{
//..
}
Dies rufen Sie als auf
if (0 == compare(theString, "Seven seven SEVEN 7")
{
//
Die Implementierung muss durch Leerzeichen getrennte Muster auseinanderziehen, aber das ist nicht schwierig und kann leicht in einer Schleife implementiert werden, also gibt es keine Begrenzung, wie viele Vergleiche Sie testen möchten.
Wann sollten Sie erwägen, eine neue Funktion zur Unterstützung einer neuen abgeleiteten Anforderung zu erstellen?
Es ist meine Praxis, die neue Funktion zu erstellen, wenn ich 3 oder mehr Verwendungen identifizieren kann. Viel Glück.
Ich habe einen Code gefunden, den ich vor ein paar Jahren geschrieben habe, ihn repariert, Demos hinzugefügt …
Code kompiliert und scheint zu laufen, aber sehr wenig getestet.
- Ich habe eine minimale Paketierung erstellt – einen Dummy-Namensraum (dtb – für die Werkzeugkiste von d___) und eine Dummy-Klasse (T471_t – Test 471).
dtb::T471_t bietet private Methoden für Ihre Überprüfung.
-
size_t Vergleich (const std::string s, std::string Muster)
-
size_t grep(const std::string pfn, const std::string pattern, std::ostream& an_ostream = std::cout)
— verwendet vergleichen()
-
size_t cpuinfoGet()
— verwendet grep
— “wc < /proc/cpuinfo" (eine "bekannte Datei" auf Ubuntu) meldet 54 Zeilen auf meiner 2-Kern-Maschine, mehr Kerne, mehr Zeilen
-
size_t coreCountGet()
— verwendet grep()
— erstellt nullDev, um die normale grep-Ausgabe zu unterdrücken
#include <chrono>
#include <fstream>
#include <iostream>
#include <sstream>
#include <string>
#include <cassert>
// 'compressed' chrono access --------------vvvvvvv
typedef std::chrono::high_resolution_clock HRClk_t; // std-chrono-hi-res-clk
typedef HRClk_t::time_point Time_t; // std-chrono-hi-res-clk-time-point
typedef std::chrono::microseconds US_t; // std-chrono-microseconds
using namespace std::chrono_literals; // support suffixes like 100ms
// examples:
//
// Time_t start_us = HRClk_t::now();
//
// auto duration_us = std::chrono::duration_cast<US_t>(HRClk_t::now() - start_us);
// auto count_us = duration_us.count();
// or
// std::cout << " complete " << duration_us.count() << " us" << std::endl;
namespace dtb
{
class T471_t
{
const std::string dashLine = (" --------------------------------------------------------------");
public:
T471_t() = default;
~T471_t() = default;
int exec()
{
std::cout << "\n cpuinfoGet()\n" << dashLine << std::endl;
(void)cpuinfoGet(); // uses grep which uses compare
std::cout << dashLine << std::endl;
// count of lines which contain "processor" in linux file "/proc/cpuinfo"
std::cout << "\n\n " << coreCountGet()
<< " cores on this system. (coreCountGet())\n\n" << std::endl;
return(0);
}
private: // methods
// returns std::string::npos when none of the patterns found,
// else returns index of earliest found patterns of space delimited substr in
size_t compare (const std::string& s,
std::string patterns) // pass by value
{
size_t found = std::string::npos;
size_t patCount = 0;
std::stringstream ssPat(patterns + ' '); // load patterns into ram based stringstream
// ^^^^^ -- getline() can cause eof() in this
const char delim = ' '; // see getline()
do
{
if(0 == patterns.size()) break; // no patterns to search for, kick out
if(0 == s.size()) break; // no string in which to search, kick out
do {
std::string pat;
(void)std::getline(ssPat, pat, delim); // extract 1 space delimited pattern
if(false == ssPat.good())
{
if(ssPat.eof()) break; // quitely exit, a normal op
// let user know of patten problem
std::cerr << "\n err pattern extract: " << patterns
<< " (" << patCount << ')' << std::endl;
break;
}
patCount += 1;
//trimLeadingWhiteSpace(patterns); // tbr
//trimTrailingWhiteSpace(patterns); // tbr
if(0 == patterns.size()) break; // no more patterns
// search s for pat
found = s.find(pat);
if(found != std::string::npos) break; // one of the patterns found in s
} while(1); // repeat until 1 found or all patterns tried
}while(0);
return(found);
} // size_t compare (const std::string& s, std::string patterns)
size_t grep(const std::string pfn,
const std::string patterns, // concatenated list of search patterns
std::ostream& an_ostream = std::cout) // redirectable
{
size_t foundCount = 0;
an_ostream << " grep (" << pfn << ", [" << patterns
<< "] )" << std::endl;
do
{
std::ifstream infile(pfn);
if(!infile.is_open())
{
an_ostream << pfn << " not found.\n" << std::endl; // tbr - std::cerr?
break; // skip over file op's (no close needed)
}
do
{
if(infile.eof()) break; // file empty?
std::string lineIn;
(void)getline(infile, lineIn); // default delimiter is \n
if (0 == lineIn.size()) continue; // empty line?
size_t found = compare(lineIn, patterns); // any of patterns in lineIn?
if(std::string::npos != found) // found at least one pattern
{
an_ostream << " " << lineIn << std::endl; // found it, print it
foundCount += 1;
}
// else no pattern found - continue until eof of inFil
} while(1);
infile.close();
}while(0);
return(foundCount);
} // size_t grep(const std::string pfn, const std::string patterns, std::ostream& an_ostream = std::cout)
// space delimited list of ---^^^^^^^^
size_t cpuinfoGet()
{
size_t count = grep("/proc/cpuinfo", // pfn
"bogomips model name processor"); // patterns to search for
std::cout << "\n info lines: " << count << std::endl;
return(count);
} // size_t cpuinfoGet(void)
size_t coreCountGet()
{
// create a no-ouptput output
std::ofstream nullDev; // and do not open
nullDev.setstate(std::ios_base::badbit); // set error, ignore errors, do not close
size_t retVal = grep(std::string("/proc/cpuinfo"),
std::string("processor"), // line count of "processor" is core count
nullDev); // nullDev -- no output
return(retVal);
} // size_t coreCountGet()(void)
}; // class T471_t
} // namespace dtb
int main(int /*argc*/, char** /*argv[]*/)
{
Time_t start_us = HRClk_t::now();
int retVal = -1;
{
dtb::T471_t t471;
retVal = t471.exec();
}
auto duration_us = std::chrono::duration_cast<US_t>(HRClk_t::now() - start_us);
std::cout << " FINI " << duration_us.count() << " us" << std::endl;
return(retVal);
}
Ausgabe:
cpuinfoGet()
--------------------------------------------------------------
grep (/proc/cpuinfo, [bogomips model name processor] )
processor : 0
model : 75
model name : AMD Athlon(tm) 64 X2 Dual Core Processor 5000+
bogomips : 4809.67
processor : 1
model : 75
model name : AMD Athlon(tm) 64 X2 Dual Core Processor 5000+
bogomips : 4809.67
info lines: 8
--------------------------------------------------------------
2 cores on this system. (coreCountGet())
FINI 829 us
Manchmal können Daten eine bessere Lösung sein als Code.
std::map<std::string, int> values;
values["Seven"]=7;
values["seven"]=7;
values["7"]=7;
values["Six"]=6;
values["six"]=6;
values["6"]=6;
std::string input;
std::cin >> input;
std::cout << values[input];
Wie Vlad angemerkt hat, ist es möglicherweise besser, zuerst in Kleinbuchstaben umzuwandeln. Diese Antwort ist nur die einfache Konvertierung Ihres Codes in Daten. Beachten Sie, dass diese Antwort einen Standardwert von 0 für fehlende Zeichenfolgen verwendet; Ihr Code hat einen solchen Standard ausgelassen.
if (theString == "Seven" || theString == "seven" || theString == "7")
– Benutzer2100815
19. April 2017 um 1:29 Uhr
Was ist die Art von
theString
?– songyuanyao
19. April 2017 um 1:31 Uhr