Jak zrobiłbym pętlę for dla każdego znaku w łańcuchu w C ++?
char
, Punkt kodowy Unicode, rozszerzony klaster grafemowy?
index
część w odpowiedziach.
Jak zrobiłbym pętlę for dla każdego znaku w łańcuchu w C ++?
char
, Punkt kodowy Unicode, rozszerzony klaster grafemowy?
index
część w odpowiedziach.
Odpowiedzi:
Pętlowanie znaków a std::string
, przy użyciu pętli opartej na zakresie (pochodzi z C ++ 11, obsługiwanej już w najnowszych wersjach GCC, clang i VC11 beta):
std::string str = ???;
for(char& c : str) {
do_things_with(c);
}
Pętla po znakach std::string
iteratorów:
std::string str = ???;
for(std::string::iterator it = str.begin(); it != str.end(); ++it) {
do_things_with(*it);
}
Pętlowanie przez postacie std::string
ze staroświecką pętlą for:
std::string str = ???;
for(std::string::size_type i = 0; i < str.size(); ++i) {
do_things_with(str[i]);
}
Pętla przez znaki tablicy znaków zakończonej znakiem null:
char* str = ???;
for(char* it = str; *it; ++it) {
do_things_with(*it);
}
std::string
, która jest po prostu seria bajtów.
Pętlę for można zaimplementować w następujący sposób:
string str("HELLO");
for (int i = 0; i < str.size(); i++){
cout << str[i];
}
Spowoduje to wydrukowanie łańcucha znak po znaku. str[i]
zwraca znak przy indeksie i
.
Jeśli jest to tablica znaków:
char str[6] = "hello";
for (int i = 0; str[i] != '\0'; i++){
cout << str[i];
}
Zasadniczo powyżej dwóch są dwa typy ciągów obsługiwanych przez c ++. Drugi nazywa się ciągiem c, a pierwszy ciągiem std lub (ciągiem c ++). Sugerowałbym użycie ciągu c ++, co jest łatwe w obsłudze.
We współczesnym C ++:
std::string s("Hello world");
for (char & c : s)
{
std::cout << "One character: " << c << "\n";
c = '*';
}
W C ++ 98/03:
for (std::string::iterator it = s.begin(), end = s.end(); it != end; ++it)
{
std::cout << "One character: " << *it << "\n";
*it = '*';
}
W przypadku iteracji tylko do odczytu można użyć std::string::const_iterator
w C ++ 98 for (char const & c : s)
lub tylko for (char c : s)
w C ++ 11.
auto
jest zawsze dobrym pomysłem. Podczas korzystania z niego rozróżnienie między begin()
i cbegin()
staje się istotne.
char & c
)? Czy to po prostu pozwala na modyfikację wartości postaci w przypadku, gdy jest to potrzebne?
Oto inny sposób na zrobienie tego przy użyciu standardowego algorytmu.
#include <iostream>
#include <string>
#include <algorithm>
int main()
{
std::string name = "some string";
std::for_each(name.begin(), name.end(), [] (char c) {
std::cout << c;
});
}
const char* str = "abcde";
int len = strlen(str);
for (int i = 0; i < len; i++)
{
char chr = str[i];
//do something....
}
strlen
w warunku pętli, ponieważ wymaga ona operacji O (n) na łańcuchu dla każdej iteracji, co powoduje, że cała pętla O (n ^ 2) w rozmiarze ciągu. strlen
w pętli można wywołać warunek, jeśli łańcuch zmienia się podczas pętli, ale powinien być zarezerwowany dla przypadków, w których jest to faktycznie wymagane .
Nie widzę żadnych przykładów używania zakresu opartego na pętli z „ciągiem c”.
char cs[] = "This is a c string\u0031 \x32 3";
// range based for loop does not print '\n'
for (char& c : cs) {
printf("%c", c);
}
nie spokrewnione, ale int przykład tablicy
int ia[] = {1,2,3,4,5,6};
for (int& i : ia) {
printf("%d", i);
}
W przypadku C-string ( char []
) powinieneś zrobić coś takiego:
char mystring[] = "My String";
int size = strlen(mystring);
int i;
for(i = 0; i < size; i++) {
char c = mystring[i];
}
Dla std::string
można użyć str.size()
, aby uzyskać jego rozmiar i powtórzyć, jak na przykład, czy można użyć iterator:
std::string mystring = "My String";
std::string::iterator it;
for(it = mystring.begin(); it != mystring.end(); it++) {
char c = *it;
}
for (int x = 0; x < yourString.size();x++){
if (yourString[x] == 'a'){
//Do Something
}
if (yourString[x] == 'b'){
//Do Something
}
if (yourString[x] == 'c'){
//Do Something
}
//...........
}
Łańcuch jest w zasadzie tablicą znaków, dlatego możesz określić indeks, aby uzyskać znak. Jeśli nie znasz indeksu, możesz go przeglądać jak w powyższym kodzie, ale robiąc porównanie, upewnij się, że używasz pojedynczych cudzysłowów (które określają znak).
Poza tym powyższy kod jest oczywisty.
możesz pobrać każdy znak w ciągu używając funkcji at biblioteki ciągów, tak jak ja to zrobiłem
string words;
for (unsigned int i = 0; i < words.length(); i++)
{
if (words.at(i) == ' ')
{
spacecounter++; // to count all the spaces in a string
if (words.at(i + 1) == ' ')
{
i += 1;
}
to tylko fragment mojego kodu, ale chodzi o to, że możesz uzyskać dostęp do znaków przez stringname.at(index)
std::string
?