J'ai déjà essayer, mais l'erreur est au même niveau :
Code : Sélectionner tout - Visualiser dans une fenêtre à part fichier << nomchaine[c[f6]];
J'ai déjà essayer, mais l'erreur est au même niveau :
Code : Sélectionner tout - Visualiser dans une fenêtre à part fichier << nomchaine[c[f6]];
Oui, l'erreur est la même pour la même raison: des échafaudages d'indice calculés par indice qui sont très difficiles à contrôler correctement et mènent à des accès mémoire illégaux...
Je viens de remarquer qu'avant que mon programme plante il écrit bien dans le fichier. Mais j'ai remarqué aussi qu'il écrivait TOUTES les chaînes de caractères, puis qu'après il y avait plein de caractères spéciaux (contenu dans mes chaînes) écrit dans un ordre totalement aléatoire...
Je ne suis pas certain d'avoir bien compris ce que tu essaye de faire... Est-ce que tu veux que si l'utilisateur a entré "ABC", tu affiches :
?
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27 AAA AAB AAC ABA ABB ABC ACA ACB ACC BAA BAB BAC BBA BBB BBC BCA BCB BCC CAA CAB CAC CBA CBB CBC CCA CCB CCC
Si oui, est-tu conscient qu'avec la chaîne en entrée dont tu parles, de 36 caractères, tu parles d'un fichier de 36^36 lignes, soit 36^36 * 37 caractères, soit environ 4E57, à peu près autant qu'il y a d'atomes dans le soleil... J'espère que tu as un bon disque dur
Si non, peux-tu montrer l'ensemble de la sortie que tu attends dans ce cas ?
Ma session aux Microsoft TechDays 2013 : Développer en natif avec C++11.
Celle des Microsoft TechDays 2014 : Bonnes pratiques pour apprivoiser le C++11 avec Visual C++
Et celle des Microsoft TechDays 2015 : Visual C++ 2015 : voyage à la découverte d'un nouveau monde
Je donne des formations au C++ en entreprise, n'hésitez pas à me contacter.
Non je ne souhaite pas faire ça. En faite le but est de faire un dictionnaire de mot de 8 à 63 caractères contenant soit :
1) 94 caractères ASCII
2) Les lettres de l'alphabet (MAJ et min) + chiffres
3) Les lettres de l'alphabet (MAJ) + chiffres
4) Les lettres de l'alphabet (min) + chiffres
Je sais que pour tout cela, ça ferai des milliards de milliards de To de place (8^94+9^94+10^94+...+63^94 pour le 1er dictionnaire).
Mais le but étant de contenir tout cela dans une suite de fichier, et qu'il n'y aurai que 3 fichiers d'environ 90Mo sur le disque dur.
J'ai tenter avec le code ASCII des caractères, mes chaînes ressemblent sont donc une suite du code ASCII des lettres de l'alphabet min et/ou maj et/ou chiffres et/ou caractères spéciaux.
Donc je veux que, par exemple, pour la chaîne n°3 si l'utilisateur a choisi de commencer a 8 caractères, cela écrive :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10 AAAAAAAA AAAAAAAB AAAAAAAC AAAAAAAD ... AAAAAAA9 AAAAAAA0 AAAAAABA ... (jusqu à) 0000000000000000000000000000000000000000000000000000000000000000
Je n'ai pas trop compris ce que tu dis, puisque d'un côté tu dis que c'est bien trop gros (et je suis d'accord avec toi), pour ensuite dire que ça tient dans une suite de fichiers (et là, je ne le suis plus trop...)
Toujours est-il que sur des petits "mots", dans le cas de ton ensemble 3 par exemple, il faut voir que ton énumération consiste simplement à compter de 0 à 36^8 en base 36.
Voici un bout de code, non optimisé, qui fait ça (attention, rien que pour une valeur de 4 avec ton alphabet de 36 caractères, on obtient un fichier de 10Mo...)
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45 #include <iostream> #include <string> #include <fstream> using namespace std; long long pow(int a, int b) // return a^b { long long result = 1; for (int i=0 ; i<b ; ++i) { result *= a; } return result; } string toStringInBase(long long nb, std::string const &alphabet, int wordSize) { string revertResult; int base = alphabet.size(); for (int i = 0 ; i<wordSize ; ++i) { int modulo = nb % base; revertResult.push_back(alphabet[modulo]); nb /= base; } return string(revertResult.rbegin(), revertResult.rend()); } int main() { string alphabet; cout << "Alphabet : "; cin >> alphabet; cout << "Taille du mot : "; int wordSize; cin >> wordSize; int const nbChars = alphabet.size(); long long nbIter = pow(alphabet.size(), wordSize); ofstream resultFile("Result.txt"); for (long long i = 0 ; i<nbIter ; ++i) { resultFile << toStringInBase(i, alphabet, wordSize) << endl; } }
Ma session aux Microsoft TechDays 2013 : Développer en natif avec C++11.
Celle des Microsoft TechDays 2014 : Bonnes pratiques pour apprivoiser le C++11 avec Visual C++
Et celle des Microsoft TechDays 2015 : Visual C++ 2015 : voyage à la découverte d'un nouveau monde
Je donne des formations au C++ en entreprise, n'hésitez pas à me contacter.
Oui car quand tu débordes de ton tableau ça se met à utiliser des indices venant d'une partie de la pile d'appel qui n'est pas ton tableau, et qui ont donc des valeurs complètement farfelues.
Puis comme tu écris à ces indices farfelus tu commences à labourer sauvagement des espaces mémoire choisis au hasard, jusqu'à ce que ça tappe dans une adresse qui t'es interdite ou que ça commence à faire n'importe quoi parce que tes variables locales sont corrompues...alors là ça finit par planter
En faite ce programme permet de générer un dictionnaire (ça j'ai déjà dit) qui sera utilisé par un autre programme pour faire quelque chose. Cet autre programme scanne les fichiers un par un.
J'ai donc décidé qu'au bout du 3e fichier, mon programme ce met en pause et attend que l'utilisateur donne son accord pour commencer la création du 4e fichier, mais va détruire le 1er fichier.
Ce qui fait que tout ce dictionnaire tiendrait dans maximum 3 fichiers au total.
Dans le cas de mon 3e exemple on compte de 0 à 36^63 ! Pas 36^8.
Mais comment c'est possible de déborder de mon tableau ? J'ai pourtant bien mis le bon nombre de caractères...
Et quand j'ai ce morceau de code la :
Mon programme fonctionne parfaitement...
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6 if(c[63]==longchaine) { c[62]++; c[63]=0; } if(c[62]==longchaine) { c[61]++; c[62]=0; } etc... if(c[2]==longchaine) { c[1]++; c[2]=0; } if(c[1]==longchaine) { c[0]++; c[1] = 0; } if(c[0]==longchaine) { c[0]=0; }
Donc c'est que c'est ce morceau de code qui pose problème :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 i=longint; while(continuer2==0) { if(c[i]==longint) { c[i]=0; c[i-1]++; } i--; if(i==0) { if(c[0]==longint) { c[0] = 0; } continuer2=1; } }
l'erreur de borne entre lonchaine et longchaine-1 suffit à aller lire une valeur située après le tableau et dont la valeur n'a ni queue ni tête...effet boeuf garanti. Si le tableau est en fin de pile c'est de la mémoire non initialisée, mais même dans le cas contraire ça n'a aucune raison d'être un indice valide.
Mais ce que je ne comprend pas c'est comment il peux y avoir une erreur de borne ou que le programme change de chaîne de caractères étant donner que j'ai spécifié des valeurs précises qui correspondent au nombre exacte de valeur dans chaque chaîne de caractères, et que j'ai fait des chaînes de caractères précises distincte ?
Peut-être parce que certaines valeurs se retrouvent dans toutes mes chaînes ?
Il n'y a pas un moyen pour palier à ce problème ?
le fait d'aller lire ne serais-ce qu'un rang après la fin d'un tableau te fait des indices imprévisibles...quand au fait d'écrire, qui sait ce qui peut arriver? avec "un peu de bol" tu réinitialise ta variable f6 à 1235778 et vlan...ou alors tu change la valeur de ton pointeur de chaine, bref impossible de savoir...écrire "à côté" d'une variable c'est "undefined behavior", plus rien n'est garanti...
Par ailleurs, je maintiens qu'il faudrait que tu exprimes ton algorithme de manière plus structurée, et de préférence plus simple, pour le rendre plus facile à maîtriser.
Inspire toi de ce que JolyLoic a proposé.
Très bien dans ce cas je vais revoir la structure de mon algorithme.
Merci beaucoup de votre aide (je met en "Résolu")
Vous avez un bloqueur de publicités installé.
Le Club Developpez.com n'affiche que des publicités IT, discrètes et non intrusives.
Afin que nous puissions continuer à vous fournir gratuitement du contenu de qualité, merci de nous soutenir en désactivant votre bloqueur de publicités sur Developpez.com.
Partager