0
votes

c ++ Question avec affichage de texte entre deux variables de tableau

Je semble toujours avoir ce problème lorsque je veux afficher deux variables d'un tableau en une itération d'une boucle, je me demande s'il existe une meilleure façon d'afficher le tableau.

Le code fonctionne si je change ++ i en i + 1 mais je me demande pourquoi cela se produit, et je me demande s'il existe une manière plus intelligente de faire ce que je veux. L'erreur indique une modification sans séquence et un accès à «i» [-Wunsequenced]

#include <iostream>
#include <memory>
#include <string>
#include <algorithm>
using namespace std;

int main()
{
    int players = 0,rounds=0;
    bool winnerFound=false;
    cout << "Welcome to my tournament match maker\n";
    cout << "Enter the number of participants in the tournament: ";
    cin >> players;
    rounds=players/2;
    string *pNames = new string[players]; //dynamically allocate 
    for (int i = 0;i < players;i++)
    {
        cout << "Enter the name of player " << i + 1<<":";
        cin >> pNames[i];
    }
        random_shuffle(&pNames[0],&pNames[players]);
        for(int i=0;i<rounds;i++)
        {
           cout<<pNames[i]<<" vs "<<pNames[++i]; //
        }
        return 0;
}

Je ne suis pas sûr que ce soit la meilleure façon de le faire, des conseils seraient appréciés.


7 commentaires

Double possible de Comportement et points de séquence non définis


"Le code fonctionne si je change ++ i en i + 1 mais je me demande pourquoi cela se produit" Vous augmentez i dans pour (int i = 0; i et ensuite vous l'augmentez également dans pNames [++ i] . Vous l'augmentez deux fois à chaque passage dans la boucle, ce n'est certainement pas prévu.


Il est prévu, je veux afficher deux chaînes différentes et non seulement faire monter le «i» par un, car il affichera un nom trop de fois si je ne le fais pas. Je ne vois pas de différence entre ce code et ce code qui fonctionne pour (int i = 0; i


Veuillez noter qu'il existe deux incréments: pré-incrément ( ++ i ) et post-incrément ( i ++ ). L'ancienne incrémente la valeur de i et renvoie la nouvelle valeur. Ce dernier renvoie la valeur de i et s'incrémente ensuite (avant le point de séquence suivant).


Ouais c'est pourquoi j'ai mis ++ i et non i ++, et c'est pourquoi je me demande pourquoi il y a un problème.


@MikeCalicoder: par exemple, vous obtiendrez 3 joueurs, dans la deuxième boucle, vous obtiendrez i = 2 , et lorsque vous aurez ++ i , vous essayez de accédez à pNames [3] , mais pNames n'a que 3 valeurs (de 0 à 2).


@Raffallo Non, car la boucle tourne jusqu'à rounds , et 3/2 == 1, donc la boucle ne fonctionnera qu'une seule fois, il n'essaiera pas d'accéder à un élément supplémentaire mais manquera plutôt le dernier.


3 Réponses :


1
votes

Pour les astuces, je pense qu'il vaut mieux utiliser un conteneur STL au lieu d'un tableau brut. std :: array ou std :: vector par exemple. Vous pouvez modifier la déclaration de pNames comme suit:

for(size_t i = 0; !pNames.empty() && i < pNames.size()-1; i+=2)
{
    std::cout << pNames[i] << " vs " << pNames[i+1] << std::endl;
}

Votre problème est que vous n'effectuez une itération que jusqu'à arrondis . Vous ne voulez pas cela, vous voulez boucler sur tous les joueurs, pas seulement la moitié.

Pour faire fonctionner votre code, vous devez écrire:

for(size_t i = 0; !pNames.empty() && i < pNames.size()-1; ++i)
{
    std::cout << pNames[i] << " vs " << pNames[++i] << std::endl;
}


5 commentaires

pourquoi vérifier pNames.empty () quand la boucle s'interromprait avec la condition 0 <0-1 avec i = 0 et size = 0?


@FalcoGer Parce qu'avec un size_t aka unsigned long long , 0-1 sera sous-estimé. Et je n'ai pas utilisé un int pour utiliser les bons types attendus par le vecteur (et éviter les avertissements pour la conversion automatique ou les static_cast s).


Pour être plus clair, 0-1 est égal à -1 avec les types signé . Mais avec les types non signés , il déborde et équivaut généralement à la valeur positive maximale que le type correspondant peut contenir. La condition ne sera donc jamais false .


J'ai dit que size_t est un unsigned long long mais cela dépend de la plate-forme. Mais généralement, size_t est défini comme unsigned ( unsigned short , unsigned int , ...)


Merci le i + = 2 c'est ce que l'on cherchait



-1
votes

Premièrement, i ++ et ++ i sont différents.
i ++ s'incrémente après avoir renvoyé la valeur et
++ i s'incrémente avant de renvoyer la valeur du résultat.

Ce serait plus lisible si vous incrémentiez votre i dans la boucle for de deux et que vous n'ayez pas d'effet secondaire lorsque vous demandez le tableau évaluer. Et bien sûr, vous devez vérifier si i est valide à ce stade

for(int i=0; i < players-1; i += 2)
{
    // check if valid.
    // with odd numbers of players, the last remaining player will be dropped.
    cout << pNames[i]<<" vs " << pNames[i+1]; // no side effect.
                                                  // In a for loop
                                                  // all increments should happen in
                                                  // the loop header.
}


5 commentaires

Cette méthode est fausse, considérons 10 joueurs. À la première itération, vous afficherez 0 et 1, mais à la deuxième itération, vous afficherez 4 et 5, vous manquerez 2 et 3.


Je vois, mais je ne suis pas celui qui a décliné votre réponse, donc je ne peux pas la supprimer.


Mais il y a toujours une erreur, vous devriez itérer pendant que i .


@Fareanor que diriez-vous de supprimer votre vote négatif et de supprimer le message puisque vous avez déjà répondu?


Je ne vous ai jamais déconseillé. Ce n'est pas moi, je ne peux donc pas supprimer le vote défavorable. Mais oui, j'ai déjà donné la solution et j'ai été le premier à répondre :)



0
votes
#include <iostream>
#include <memory>
#include <string>
#include <algorithm>
#include <ctime>
using namespace std;
int main()
{
    srand(time(NULL));
    int players = 0,count=0;
    cout << "Welcome to my tournament match maker\n";
    cout << "Enter the number of participants in the tournament: ";
    cin >> players;
    string *pArray = new string[players]; //dynamically allocate
    cin.ignore();
    for (int i = 0;i < players;i++)
    {
        cout << "Enter the name of player " << i + 1<<":";
        getline(cin, pArray[i]);
    }
    random_shuffle(&pArray[0], &pArray[players]);
    for (int i = 0;i < players;i++)
    {
        cout << ++count << ": " << pArray[i] << " vs " << pArray[i + 1] << endl;
        i++;
    }

    return 0;
}
Any critiques?

2 commentaires

Vous faites beaucoup de choses étranges pour être honnête. Lisez ma réponse, elle vous fournira quelques astuces et la solution à votre problème.


puisque vous voulez quand même incrémenter à la fin de la boucle, vous pouvez aussi bien incrémenter de 2 dans l'en-tête de la boucle. généralement, vous utiliserez une boucle for pour de tels scénarios où tout le contrôle peut se produire dans l'instruction for