0
votes

Infinite imprévu pour la boucle en C ++

J'écris un programme pour renvoyer la première occurrence du personnage et la fréquence de ce caractère dans la chaîne. Pour la boucle dans la fonction exécute des temps infinis et si la condition et le bloc ne sont pas exécutés même une fois.

Quel est le problème? P>

string::size_type find_ch(string &str,char ch,int& i_r)
{
    string::size_type first=0;
    for(auto i=str.size()-1;i>=0;i--)
    {
        cout<<"\nInside a for loop."<<endl;
        if(str[i]==ch)
        {
            cout<<"Inside if."<<endl;
            first=i+1;
            i_r++;
        }
    }
    return first;
}


2 commentaires

J'écris un programme pour renvoyer la première occurrence du personnage et la fréquence de ce caractère - ma question est de savoir pourquoi êtes-vous en boucle à l'envers pour accomplir cela?


@Paulmckenzie Parce que si j'avais de l'avant, comment puis-je me souvenir de la survenue de premier caractère?


3 Réponses :


2
votes

Cette boucle: xxx

ne quitte que lorsque i est inférieur à 0 . Mais ce n'est pas une valeur valide pour un non signé INT . La valeur enveloppera au maximum non signé INT , et vous obtenez une boucle infinie.

Notez que .Size () sur un STD :: chaîne renvoie un taille_t , qui est fondamentalement un non signé int type.

un moyen de résoudre ce problème Type de retour de .Size () à un int, comme celui-ci: xxx

Notez qu'il est important de faire la distribution avant soustrayer 1, sinon vous obtiendrez la mauvaise réponse lorsque str est vide.

in c ++ 20, vous pouvez éviter ce problème entièrement en appelant le std :: ssize () fonction libre, qui renvoie une version signée de la taille.


4 commentaires

Où puis-je obtenir un document de théorie global C ++ 20? Si tu sais.


Je me réfère généralement au brouillon de travail


Et il y a un autre problème dans mon programme qui est lorsque j'utilise la valeur de i_r dans la fonction principale qu'il affiche zéro. Pouvez-vous dire quel est le problème?


Cela dépend de la manière dont vous utilisez i_r dans Main. Puisque vous le transmettez par référence, les modifications de la fonction seront visibles dans principal .



0
votes

La définition de la fonction en général est incorrecte.

Par exemple, si le caractère donné est trouvé, pourquoi la fonction renvoie-t-elle 0 qui est une position valide? p>

retourner la valeur = i + 1; code> ne confondera que les utilisateurs de la fonction. La fonction doit renvoyer std :: string :: npos code> si le caractère donné n'est pas trouvé. P>

aussi il est tout à fait difficile pourquoi la boucle commence à partir de la fin de la chaîne pendant que vous Nécessité de retourner la première position du personnage. p>

comme pour la boucle infinie, alors dans la boucle, il est utilisé la variable i code> qui a le type d'entiers non signé std :: String :: Taille_type Code> Une valeur dont la valeur ne peut jamais être négative. p> xxx pré>

c'est la condition i> = 0 code> est toujours vrai Par la définition. p>

La fonction doit être définie sur la manière suivante p> xxx pré>

Voici un programme démonstratif. P>

#include <iostream>
#include <string>
#include <utility>

std::pair<std::string::size_type, std::string::size_type> find_ch( const std::string &str, char ch )
{
    std::pair<std::string::size_type, std::string::size_type> p( std::string::npos, 0 );

    std::string::size_type n = 0;

    while ( n < str.size() && str[n] != ch ) ++n;

    if ( n != str.size() )
    {
        p.first = n;
        ++p.second;
        while ( ++n != str.size() )
        {
            if( str[n] == ch ) ++p.second;
        }           
    } 

    return p;
}

int main() 
{
    std::string s( "C++ is not the same as C" );

    auto p = find_ch( s, 'C' );

    if ( p.first != std::string::npos )
    {
        std::cout << p.first << ": " << p.second << '\n';
    }

    return 0;
}


10 commentaires

Comme vous pouvez le constater si je démarre itération de début comment puis-je trouver la première occurrence du personnage à la fin. Je n'ai utilisé aucune fonction par mon choix. Et j'ai fait de type casting pour pour (auto i = static_cast (str.size ()) - 1; i> = 0; i -) . Et aussi, je n'ai pas mentionné l'ensemble du programme dans lequel j'ai fait une fonction pour vérifier si le personnage existe ou non.


@MruGuShraulji C'est une mauvaise idée de lancer au type INT le type non signé STD :: String :: Taille_Type. Par exemple, un objet du type INT est incapable d'accueillir toutes les valeurs de type STD :: String :: Taille_Type.


OK Si je ne mets pas et que je n'utilise pas INT, peut essayer de faire la meilleure fonction sans appeler d'autre fonction.


@MRUGUGESHRULJI En fait, il n'y a pas de "d'autres fonctions. Il est utilisé la méthode de trouver la classe STD :: String que vous utilisez déjà.


Désolé 😂 Je parlais de str.find () et nos .


@Mrugehraulji comme j'ai dit trouver est une méthode de la classe STD :: String. Si vous utilisez la classe, pourquoi ne pouvez-vous pas utiliser ses méthodes? Quant aux NPOS, il est défini comme non signé -1. Voir mon poste mis à jour. NOSPOS, vous pouvez substituer à STR.SIZE (). C'est-à-dire que si le caractère n'est pas trouvé, la position renvoyée égale à la longueur de la chaîne.


Il ne s'agit pas de savoir pourquoi ne pas utiliser les méthodes. Vous pouvez le faire sans la méthode ou non? C'est ca le truc.


@Mrugehraulji J'ai montré comment faire cela en utilisant des boucles.


Et il y a un autre problème dans mon programme qui est lorsque j'utilise la valeur de i_r dans la fonction principale qu'il affiche zéro. Pouvez-vous dire quel est le problème?


@Mrugehraulji Je vous ai montré comment la fonction devrait être déclarée. Vos déclarations de fonction sont mauvaises.



0
votes

Voici une réponse similaire à @vlad à partir de Moscou, mais utilise des fonctions de chaîne et l'algorithme std :: compter . xxx

sortie: xxx

Chaque ligne de la fonction décrit fondamentalement ce qui est fait ce qui est fait :

recherche_first_of le caractère de la chaîne. Si trouvé, renvoyez ensuite cette position et le std :: comptez de ce caractère à partir de la première occurrence.

Notez la brièveté et la manière auto-documentée La fonction est écrite. Un programmeur C ++ pourrait examiner ce code et savoir immédiatement ce qu'il fait, en raison des noms des fonctions qui sont appelées.

Les boucles d'écriture en arrière (comme vous l'avez fait à l'origine) avec des variables incrémentées ici et là, le programmeur doit s'asseoir et passer par le code pour comprendre ce qu'il fait et quel est le but de la fonction est.


0 commentaires