Comment faire un délimiteur/séparateur en langage EBPro
Résolu/Fermé[Dal] Messages postés 6194 Date d'inscription mercredi 15 septembre 2004 Statut Contributeur Dernière intervention 11 octobre 2024 - 2 nov. 2022 à 17:46
- Comment faire un délimiteur/séparateur en langage EBPro
- Langage ascii - Guide
- Langage binaire - Guide
- Pascal langage - Télécharger - Édition & Programmation
- Langage pascal - Télécharger - Édition & Programmation
- Comment séparer un pdf - Guide
11 réponses
28 oct. 2022 à 12:01
Salut Newbie,
Voici une réponse en C.
Si à partir de l'interface tu peux récupères les 4 données et que ton problème est juste de les assembler sous la forme d'une chaîne de caractères C séparant ces données par des $, alors tu peux utiliser sprintf() pour composer cette chaîne.
Par exemple pour 4 données sous forme de chaînes de caractères C dont la taille maximale est connue à l'avance, permettant de dimensionner correctement la chaîne à composer :
#include <stdio.h> #define MAX_STR 19 int main(void) { char code_operateur[] = "12"; char lancement[] = "3456"; char poste[] = "7890"; char phase[] = "1234"; char chaine[MAX_STR]; sprintf(chaine, "%s$%s$%s$%s", code_operateur, lancement, poste, phase); printf("chaine = %s\n", chaine); return 0; }
donne :
$ gcc -Wall -Wextra 37718521.c
$ ./a.out
chaine = 12$3456$7890$1234
Si, en fait ton problème est autre, explique mieux ce sur quoi tu bloques et en quoi on peut t'aider.
Si tu programmes en C++, c'est un langage différent du C et le code que tu postes fonctionne très bien. S'il ne fait pas ce que tu veux, c'est juste qu'il ne fait rien. Tu devrais dire ce que tu veux obtenir pour que l'on soit tous sur la même longueur d'onde et confirmer quel est le langage qui concerne ta question.
28 oct. 2022 à 10:53
bonjour,
peux-tu partager ton programme en C? merci de tenir compte de ceci: https://codes-sources.commentcamarche.net/faq/11288-poster-un-extrait-de-code
#include <iostream>
#include <string>
#include <vector>
#include <cstring>
int main()
{
std::string s = "AE_0";
const char delim = '$';
std::vector<std::string> out;
for (auto &s: out) {
std::cout << s << std::endl;
}
return 0;
}
Voici le code que j'ai mais il ne fonctionne pas donc je ne sais pas où vient le problème
28 oct. 2022 à 11:42
N'est-ce pas du C++, et pas du C?
Bah dans la doc technique c'est marquer en C ou Visual Basic
Donc je ne sais pas vraiment lequel prendre ni utiliser le C me sent plus simple car j'ai de petite base mais sans plus.
29 oct. 2022 à 00:28
Bah c'est du EBPro, ni du C, ni du Visual Basic
Vous n’avez pas trouvé la réponse que vous recherchez ?
Posez votre questionSi j'ai bien compris votre code ce que je veux faire c'est juste l'inverse je ne veux pas passer de 4 codes en une chaine mais de 1 code-barres et le séparer avec " $ "
28 oct. 2022 à 12:27
Tu veux donc diviser une chaîne C au moyen d'un caractère séparateur.
Pour cela, en C, tu peux utiliser strtok() par exemple, qui va découper ta chaîne de départ en sous-chaînes.
#include <stdio.h> #include <string.h> #define MAX_STR 256 int main(void) { char * code_operateur; char * lancement; char * poste; char * phase; char chaine[MAX_STR] = "12$3456$7890$1234"; char * pch; pch = strtok(chaine, "$"); int field = 0; while (pch != NULL) { field++; switch (field) { case 1: code_operateur = pch; break; case 2: lancement = pch; break; case 3: poste = pch; break; case 4: phase = pch; break; } pch = strtok(NULL, "$"); } printf("J'ai récupéré :\n" "code_operateur = %s\n" "lancement = %s\n" "poste = %s\n" "phase = %s\n", code_operateur, lancement, poste, phase ); return 0; }
donne ceci à l'exécution :
$ gcc -Wall -Wextra 37718521.c
$ ./a.out
J'ai récupéré :
code_operateur = 12
lancement = 3456
poste = 7890
phase = 1234
Modifié le 28 oct. 2022 à 14:02
Je ne fais pas beaucoup de C++, mais dans ce langage tu pourrais faire cette chose équivalente :
#include <bits/stdc++.h> int main() { std::string code_operateur; std::string lancement; std::string poste; std::string phase; std::string s = "12$3456$7890$1234"; const char delim = '$'; std::stringstream my_stringstream(s); int field = 0; std::string st; while(getline(my_stringstream, st, delim)) { field++; switch (field) { case 1: code_operateur = st; break; case 2: lancement = st; break; case 3: poste = st; break; case 4: phase = st; break; } } std::cout << "J'ai récupéré :" << std::endl; std::cout << "code_operateur = " << code_operateur << std::endl; std::cout << "lancement = " << lancement << std::endl; std::cout << "poste = " << poste << std::endl; std::cout << "phase = " << phase << std::endl; return 0; }
Au lieu de mettre les données dans des variables string, tu peux aussi créer un vecteur de string et pousser les résultats dedans, utiliser des itérateurs, etc.
Rebonjour comment vous allez ?
Je reviens d'un weekend de 4 jours, j'ai la tête fraiche et reposer.
Maintenant que je reviens je me rend compte de plusieurs erreurs de ma part quand j'ai posé la question.
Merci à yg_be qui m’a fait remarquer que ce n'est pas du C, ni du Visual Basic mais du EBPro (Je suis vraiment désolé, je ne sais pas pourquoi je n'étais mis en tête que c'était du C. J'étais perdu dans mon idée) -_-.
Apparemment c'est du EBPro similaire au C mais je ne sais pas du tout ce qui change.
Après ce qu'à proposer [Dal] en C. C'est tout à fait ça.
Il faut juste que je trouve comment faire pour qu'avec une douchette (scanner qu'on voit dans les supermarché) change la valeur du ""char chaine[MAX_STR] = "douchette-variable";""
Je trouve cette partie c'est que du détail.
Maintenant le problème, je dirais c'est de passer le programme de [Dal] en EBPro et là je suis autant perdu que vous.
Modifié le 2 nov. 2022 à 11:32
Salut Newbie,
Je ne connaissais pas du tout EBPro et je t'ai donné des exemples qui fonctionnent en C (et en C++) car tu indiquais initialement que tu voulais une aide dans ce langage.
En consultant un manuel de EBPro, on peut voir que le langage proposé par EBPro n'est effectivement pas du C, ni du BASIC. Cela emprunte un peu aux deux du point de la syntaxe, les boucles ressemblent plus au BASIC, ainsi que les instructions du langage.
En bref, tu ne pourras rien faire de mon code en C et C++.
Tu devrais te trouver un manuel EBPro correspondant à ta version et étudier les instructions et fonctions proposées par le langage.
Par exemple, ce manuel pour EasyBuilder Pro Ver. 6.05.01 décrit les fonctions StringFindOneOf et StringMid
qui te permette, respectivement, de trouver la position d'un groupe d'un ou plusieurs caractères dans une chaîne et d'extraire une sous-chaîne d'une chaîne existante. En utilisant ces deux fonctions, tu peux faire quelque chose de similaire à ce que je proposait en C et C++.
Voici un code rudimentaire sans boucle, pour te donner une idée, fait "en aveugle", car je ne dispose pas de EBPro et de la possibilité de le tester.
char chaine[256] = "12$3456$7890$1234" bool success int position int start = 0 // start vaut 0 position = StringFindOneOf(chaine[start], "$") // position contient 2, extraction du premier champ char code_operateur[10] success = StringMid(chaine[start], position, code_operateur) // code_operateur contient la sous-chaîne "12" start = start + position + 1 // start vaut 3 position = StringFindOneOf(chaine[start], "$") // position contient 4, extraction du deuxième champ char lancement[10] success = StringMid(chaine[start], position, lancement) // lancement contient la sous-chaîne "3456" (... etc. ...)
Les tailles des chaînes sont des exemples à adapter à ton cas.
Il faudrait aussi faire un contrôle d'erreurs. Par exemple vérifier que StringFindOneOf trouve le $ qu'il est censé trouver. S'il ne le trouve pas alors la fonction retourne -1 (selon la documentation). Lorsqu'on arrivera au dernier champ, elle devra nécessairement retourner -1 (ce qui ne sera pas une erreur dans ce cas, on vérifie ainsi qu'il n'y a plus de caractère séparateur), et alors il suffira d'utiliser une fonction comme StringTrimLeft (au lieu de StringMid) pour récupérer la fin à partir de la dernière position de départ.
De même, le booléen retourné par StringMid devrait sans doutes être vérifié.
Si tu as l'assurance que les champs ont une taille fixe et que la chaîne est correctement construite, rechercher le délimiteur est inutile puisque la position des sous-chaînes est connue à l'avance, et il suffit alors de les extraire une à une avec StringMid. Tu peux aussi faire un contrôle de la chaîne en vérifiant la longueur et en vérifiant que les séparateurs se trouvent aux positions fixes prévues.
Le langage est très rudimentaire et les fonctions peu nombreuses. Vois la documentation pour trouver celle qui te correspond le mieux, en partant de la table des fonctions :
Pour récupérer une donnée d'un matériel il y a des chances que tu doives utiliser GetData ou GetDataEx.
Apprend à lire et utiliser la documentation qui t'est fournie.
En tant que possesseur d'une licence de ce produit, peut-être disposes-tu d'un support de ton revendeur ou de l'éditeur, ou peut-être vendent-ils des formations. Tu pourrais aussi explorer ces pistes là si ces indications et la documentation ne te suffisent pas.
Ok et merci de l'aide et d'un début de code. \(^ - ^)/
j'avais trouvé le même document que toi pour EBPro pour les fonctions maintenant je vais essayer de comprendre pour faire un code qui va.
Quand j'ai un truc je l'envoie ici pour vous demander si ce que je fais par pas dans tous les sens.
Bon voici le code que j'ai plus ou moins réussir à faire, il y a des points que vous pensez que je dois modifier ? (Je rappeler c'est du EBPro)
macro_command main()
//CODE OPERATEUR
char Scan_Code_Operateur[8], Code_Operateur[6] //Déclaration code avant et apres traitement
bool Code_Operateur_Valide //bit voyant
GetData(Scan_Code_Operateur[0], "Local HMI", LW, 0, 8) //recupère le champ d'écriture
if Scan_Code_Operateur[0] == 46 and Scan_Code_Operateur[1] == 84 and not Scan_Code_Operateur[2] == 36 then //si le code commence par .T et n'est pas suivit d'un $ (évite de rentrer le code LPP dans l'operateur)
Code_Operateur_Valide = true //Voyant vert
StringTrimLeft(Scan_Code_Operateur[0], ".T", Code_Operateur[0]) //enleve .T au debut du code operateur
SetData(Code_Operateur[0], "Local HMI", LW, 10, 6) //écrit le code modifié dans le champ
else
Code_Operateur_Valide = false //Voyant rouge
end if
SetData(Code_Operateur_Valide, "Local HMI", LB, 0, 1) //Met a jour le voyant de validité
//CODE LANCEMENT/PHASE/POSE(LPP)
char Scan_Code_LPP[35], Code_Lancement[15] = "", Code_Poste[6] = "", Code_Phase[10] = "" //Déclaration codes avant et apres traitement
int Debut_Lancement, Longueur_Lancement, Debut_Poste, Longueur_Poste, Debut_Phase, Longueur_Phase //Positions du debut de chaques codes + longueurs codes
bool Code_LPP_Valide = 0 //bit voyant
GetData(Scan_Code_LPP[0], "Local HMI", LW, 100, 35) //recupère le champ d'écriture
if Scan_Code_LPP[0] == 46 and Scan_Code_LPP[1] == 84 and Scan_Code_LPP[2] == 36 then //si le code commence par .T$
Code_LPP_Valide = true //Voyant vert
Debut_Lancement = StringFind(Scan_Code_LPP[0], "$") + 1 //Donne la possition après le 1er $
Debut_Poste = StringFind(Scan_Code_LPP[Debut_Lancement], "$") + Debut_Lancement + 1 //Donne la possition après le 2e $
Debut_Phase = StringFind(Scan_Code_LPP[Debut_Poste], "$") + Debut_Poste + 1 //Donne la possition après le 3e $
Longueur_Lancement = Debut_Poste - Debut_Lancement - 1 //Donne le nombre de charactères du code Lancement
Longueur_Poste = Debut_Phase - Debut_Poste - 1 //Donne le nombre de charactères du code Poste
Longueur_Phase = StringLength(Scan_Code_LPP[Debut_Phase]) //Donne le nombre de charactères du code Phase
StringMid(Scan_Code_LPP[Debut_Lancement], Longueur_Lancement, Code_Lancement[0]) //Extrait le code Lancement du code LPP (StringMid(source[start], count, destination[start]))
StringMid(Scan_Code_LPP[Debut_Poste], Longueur_Poste, Code_Poste[0]) //Extrait le code Poste du code LPP
StringMid(Scan_Code_LPP[Debut_Phase], Longueur_Phase, Code_Phase[0]) //Extrait le code Phase du code LPP
SetData(Code_Lancement[0], "Local HMI", LW, 120, Longueur_Lancement) //écrit le code Lancement dans le champ
SetData(Code_Poste[0], "Local HMI", LW, 130, Longueur_Poste) //écrit le code Poste dans le champ
SetData(Code_Phase[0], "Local HMI", LW, 140, Longueur_Phase) //écrit le code Phase dans le champ
else
Code_LPP_Valide = false //Voyant rouge
end if
SetData(Code_LPP_Valide, "Local HMI", LB, 1, 1) //Met a jour le voyant de validité
end macro_command
2 nov. 2022 à 15:18
Comme je te le dis, je peux pas tester ton code.
Toi oui.
Dans quelle partie de ton code récupères tu la chaîne entière correspondant à ce code barre ".T25$45615$56564$4564" ?
Si tu scannes ce code barre, que fait ton code ?
Est-ce que cela te satisfait ? Si ce n'est pas le cas, décrit ton problème en indiquant le résultat souhaité et le résultat que tu obtiens.
2 nov. 2022 à 15:39
Alors quand je compile ce code j'obtiens des warnings pour les différentes int et char comme quoi ils ne sont pas initialisés.
Je récupère la chaîne entière correspondant à ce code-barres dans "Code Lancement / Poste / Phase" avec le ".T'enlever.
Puis Dans "Code Operateur" je récupère le 25 avant le premier "$"
Puis a "Code Lancement" je récupère "45615"
et ainsi de suite pour "Code Poste" = "56564"
et "Code Phase" = "4564"
/// .T25$45615$56564$4564 \\\
Je scan le code-barres avec sa:
Et le problème que j'ai c'est après avoir scanner le code-barres bah il ne se passe rien.
Modifié le 2 nov. 2022 à 15:59
Je te demande "Dans quelle partie de ton code récupères tu la chaîne entière correspondant à ce code barre ".T25$45615$56564$4564" ?" tu dis :
Je récupère la chaîne entière correspondant à ce code-barres dans "Code Lancement / Poste / Phase" avec le ".T'enlever.
Si je comprends bien, là tu ne dis pas quelles sont les instructions dans ton code source qui récupèrent ".T25$45615$56564$4564", mais dans quel champ de ton interface cette information (tronquée de ".T") est censée se trouver. Stp réponds à la question.
De plus, tu ne précises pas si cette information est effectivement copiée dans ce champ ou non.
Puis Dans "Code Operateur" je récupère le 25 avant le premier "$"
Puis a "Code Lancement" je récupère "45615"
et ainsi de suite pour "Code Poste" = "56564"
et "Code Phase" = "4564"
Est-ce que tu décris ce que fait effectivement ton code quand tu l'exécutes ou ce que tu voudrais qu'il fasse ?
Et le problème que j'ai c'est après avoir scanner le code-barres bah il ne se passe rien.
Que devrait-il se passer et qui ne se passe pas ?
Je récupère tu la chaîne entière du code-B avec :
StringMid(Scan_Code_LPP[Debut_Lancement], Longueur_Lancement, Code_Lancement[0])
et avant je lui dis d'enlever ".T"
StringTrimLeft(Scan_Code_Operateur[0], ".T", Code_Operateur[0])
La plupart du code oui je lui dis ou il va aller.
Et juste avant où j'explique le résultat que j'aimerais avoir.
Et pour de comment je récupère les données du code-B , la douchette et l'IHM ont une fonction entre eux je n'ai pas cela à faire
2 nov. 2022 à 17:46
Tu as répondu à une seule de mes questions qui est "Dans quelle partie de ton code récupères tu la chaîne entière correspondant à ce code barre ".T25$45615$56564$4564" ?"
En réponse tu dis :
Je récupère tu la chaîne entière du code-B avec :
StringMid(Scan_Code_LPP[Debut_Lancement], Longueur_Lancement, Code_Lancement[0])
Il me semble que c'est plutôt cette instruction, dans ton code, qui est censée récupérer ".T25$45615$56564$4564" :
GetData(Scan_Code_LPP[0], "Local HMI", LW, 100, 35) //recupère le champ d'écriture
As-tu vérifié que cette instruction permet effectivement de récupérer ".T25$45615$56564$4564" dans la variable Scan_Code_LPP ?
En supposant que cela soit le cas, la chaîne entière serait dans la variable Scan_Code_LPP. Ce que tu postes est une instruction qui tente d'extraire à partir de Scan_Code_LPP une information pour la stocker dans la variable Code_Lancement.
Autrement, tu ne dis toujours pas clairement ce que tu constates que fait ton code quand tu l'exécutes, en quoi tu penses qu'il ne fait pas ce que tu veux, et ce que tu voudrais qu'il fasse au lieu de son comportement actuel.
C'est la 3ème fois que je te demande ces informations. Je ne les demanderai plus, j'ai atteint mon quota :-)