String vers structure de char [Résolu]

Signaler
Messages postés
80
Date d'inscription
mercredi 6 octobre 2004
Statut
Membre
Dernière intervention
26 septembre 2006
-
Messages postés
80
Date d'inscription
mercredi 6 octobre 2004
Statut
Membre
Dernière intervention
26 septembre 2006
-
Bonjour,
Mon objectif est de gérer fichier texte formaté:
Ce fichier contient des enregistrements composé d'une suite de 60 caractères.
Mon but est de passer d'une chaine à une structure, dont bien sûr le format global est le même.

Exemple

struct MaStruct
{
char info1 ;
char info2 ;
char info3 ;
char info4 ;
}
_____________________
string MaChaine="azer" ;
MaStruct(=)MaChaine ;

En C++ 6, j'utilisait "memcpy" et ça marchait nickel....lol

Merci d'avance

Remarque :
Le format peut bouger, donc pas envie de passer par
MaStruct.info1=MaCaine.SubString(0,1) ;
.....
......

Nico
Strasbourg
France

22 réponses

Messages postés
1024
Date d'inscription
mardi 4 février 2003
Statut
Membre
Dernière intervention
7 juin 2010
64
Hello,

J'ai pensée à une solution à ton problème en C# pur, dis-moi ce que tu en penses :

public struct MaStruct
{
string s;
public MaStruct(string s)
{
this.s = s;
}
public char this[eStruct loc]
{
get
{
return s[(int)loc];
}
}
}


public enum eStruct
{
info1 ,
info2 ,
info3 ,
info4
}

Et tu utilise avec :


MaStruct ms =
new MaStruct("sdkl");
ms[eStruct.info1];

Amicalement, SharpMao
Messages postés
6351
Date d'inscription
samedi 1 juin 2002
Statut
Modérateur
Dernière intervention
2 août 2014
93
Salut,

Qu'est ce que tu entends au juste par "le format peut bouger" ?

/*
coq
MVP Visual C#
*/
Messages postés
3246
Date d'inscription
lundi 25 avril 2005
Statut
Modérateur
Dernière intervention
27 octobre 2012
39
Salut, utilise l'opérateur d'indexation [ ] sur ta chaine pour construire ta structure, non !?
Messages postés
80
Date d'inscription
mercredi 6 octobre 2004
Statut
Membre
Dernière intervention
26 septembre 2006

En fait, chaque caractère représente une donnée. Pour la suite du traitement, il est beaucoup plus simple d'utiliser
MaStructure.Info1 que MaChaine.SubString(0,1)
Et si je change la signification d'une info, Il suffit de modifier le nom dans la définition de ma structure.
Concernant l'opérateur d'indexation, écrire 60 fois
MaStructure.Info1 = MaChaine.SubString(0,1) ;
MaStructure.Info2 = MaChaine.SubString(11) ;
MaStructure.Info3 = MaChaine.SubString(2,1) ;
..........

C'est un peu lourd, alors qu'il sufit de convertir une chaine de N caractères, en une structure composée de N caractères.

Ca pb va aussi se poser pour les champs de bits. Conversion d'un nombre en une suite de champs de bit.
En clair, l'idée est de "caster" un string, ou un tableau de char, en une structure qui contient les mêmes données ; ou caster un nombre "byte" en une structure de N bits.

Ce que je peux dire, c'est qu'en C simple, je n'avais aucun pb.... un memcpy(...) faisait l'affaire .... Donc j'espère qu'en C# c'est aussi faisable !!

Merci beaucoup

Nico
Strasbourg
France
Messages postés
3246
Date d'inscription
lundi 25 avril 2005
Statut
Modérateur
Dernière intervention
27 octobre 2012
39
Je pense qu'il n'ya pas d'équivalent en code managé.

( tu peux aussi fixer ta chaine en mémoire pour travailler avec un pointeur sur ta chaine. )



// Attention au dépassement !!

string s = "ABCD";
MyStruct m = new MyStruct( );


unsafe
{

char* p = ( char* )&m;

for ( int i = 0; i < s.Length; i++ )
{
p[ i ] = s[ i ];
}
}
Messages postés
80
Date d'inscription
mercredi 6 octobre 2004
Statut
Membre
Dernière intervention
26 septembre 2006

Salut Lutinore...
Merci pour ta réponse qui me semble pas male.
Peux-tu juste me donner des explications, ou un lien, concernant "unsafe" ?
Etant un habitué du bon vieux ANSI C, ça me parait intéressant d'inclure ce type de bout de code...
Question dépassement, je sais faire gaffe. J'ai eu assez de "core dump" dans ma jeunesse

Eh oui, à la base, je suis électronicien, donc le bas niveau, j'aime bien ça... lol

Merci encore et à +

P.S : Je n'irai quand même pas jusqu'à l'assembleur

Nico
Strasbourg
France
Messages postés
6351
Date d'inscription
samedi 1 juin 2002
Statut
Modérateur
Dernière intervention
2 août 2014
93
Donc si j'ai bien saisis, tu veux que si du jour au lendemain tu changes

struct MaStruct
{
public char info1 ;
public char info2 ;
public char info3 ;
public char info4 ;
}

en

struct MaStruct
{
public char info1 ;
public char info2 ;
public char info3 ;
public char info4 ;
public char info5 ;
}

ce soit suffisant pour se mettre à gérer les chaînes de 5 caractères ?

/*
coq
MVP Visual C#
*/
Messages postés
3246
Date d'inscription
lundi 25 avril 2005
Statut
Modérateur
Dernière intervention
27 octobre 2012
39
Tu peux utiliser les pointeurs dans du code unsafe, suffit de déclarer la classe, la méthode ou juste un bloc unsafe et de compiler avec l'option unsafe ( Projet->Propriété ) ou -unsafe avec csc.exe. Comme la GC peut deplacer les objets en mémoire faut utiliser le mot clé fixed, sauf là vu que j'utilise un type valeur qui est sur la pile, de toute façon le compilo te previens.

http://msdn2.microsoft.com/en-us/library/t2yzs44b.aspx

Attention quand même avec les chaines ( extrait MSDN ) :

"un caractère Unicode peut être représenté par plusieurs Char."
Messages postés
80
Date d'inscription
mercredi 6 octobre 2004
Statut
Membre
Dernière intervention
26 septembre 2006

Coq :
Non pas vraiment...

Si Info1 devient Dupont1
...
C'est qu'une histoire de noms

Mais en fait, c'est surtout pour simplifier la copie.
Comme j'ai dit, un "memcpy" en "ANSI C" est très simple ; et on est très proche du matériel.

Pour moi, il suffirait de "caster" : les données sont les mêmes. C'est juste un autre packaging.
C'est comme si tu passes d'un byte, à une structure de 8 bits.
c'est beaucoup plus simple à manipuler, et les infos sont exactement les mêmes.

Nico
Strasbourg
France
Messages postés
6351
Date d'inscription
samedi 1 juin 2002
Statut
Modérateur
Dernière intervention
2 août 2014
93
J'avoue que j'ai du mal à saisir le truc là.
Pour moi l'autre type naturel d'une chaîne de caractères est un tableau de caractères, pas une structure de caractères.

Si tu veux éviter de multiplier les
MaStructure.Info1 = MaChaine.SubString(0,1) ;
MaStructure.Info2 = MaChaine.SubString(1,1) ;
MaStructure.Info3 = MaChaine.SubString(2,1) ;
..........
à chaque utilisation de ta structure dans le code, donne lui un constructeur :
struct MaStruct
{
public MaStruct(string str)
{
this.info1 = str[0];
this.info2 = str[1];
this.info3 = str[2];
this.info4 = str[3];
}


public char info1;
public char info2;
public char info3;
public char info4;
}

D'ailleurs à ce sujet je vais me permettre d'insister sur le point indiqué par Lutinore, l'utilisation de l'indexeur de la structure string.
MaChaine.SubString(0,1) ; devient MaChaine[0] ;
et devient dont plus court que MaStructure.Info1

Et si tu veux travailler "directement" avec le tableau de caractères, utilise la méthode =/library/fre/cpref/html/frlrfSystemStringClassToCharArrayTopic.asp String.ToCharArray

/*
coq
MVP Visual C#
*/
Messages postés
80
Date d'inscription
mercredi 6 octobre 2004
Statut
Membre
Dernière intervention
26 septembre 2006

Je suis tout à fait d'accord avec tout ce qui a été dit.
Mais je suis déçu de voir qu'on ne peut plus manipuler simplement les données brutes
Je ne sais pas ce qu'il en ai avec le C++ .Net, mais pour moi, qui fait beaucoup d'informatique embarqué, l'informatique c'est avant tout des cases mémoires dans lesquelles on place des données. Les types, les structures (simples et sans méthodes), c'est rien d'autre qu'un package.....
10011101 : c'est :
char cData ;
ou
struct donnees
{
info0:1;

info1:1;

info2:1;

info3:1;

info4:1;

info5:1;

info6:1;

info7:1;

} structData ;

&structData=(donnees*)&cData ;

il en va de même pour les chaines qui ne sont rien d'autre que des caractères.

J'éspère pouvoir qqch dans le "unsafe" pour écrire ce genre d'opérations, qui pour moi, est la base du traitement de l'information.

Je suis à l'écoute de toutes vos remarques

Nico
Strasbourg
France
Messages postés
6351
Date d'inscription
samedi 1 juin 2002
Statut
Modérateur
Dernière intervention
2 août 2014
93
Effectivement, le C++ avec extensions managées ainsi que le C++ /CLI te conviendrons probablement plus que le C# (et son contexte unsafe "limité") ou le VB.NET (sans contexte unsafe du tout), pour garder tes habitudes tout en pouvant au besoin profiter des éléments du framework.
En tout cas tu ne pourras pas garder toutes tes habitudes de programmation C/C++ en C#, ou alors au prix de gros efforts qui au final risquent de te faire perdre du temps plutôt qu'autre chose.

Enfin, c'est un choix à faire :-)

/*
coq
MVP Visual C#
*/
Messages postés
80
Date d'inscription
mercredi 6 octobre 2004
Statut
Membre
Dernière intervention
26 septembre 2006

Le pb, c'est que l'affichage des procédures et l'IDE en général dans C++ .Net, c'est assez catastrophique.
Quand tu vois l'agencement, tu n'a VRAIMENT pas envoe de faire du C++

Donc, soit je m'adapte au C#, soit je mélange les languages.
A ce que j'ai compris, c'est assez simple en .Net.... Ou bien ?

Nico
Strasbourg
France
Messages postés
6351
Date d'inscription
samedi 1 juin 2002
Statut
Modérateur
Dernière intervention
2 août 2014
93
Côté IDE, tu as regarder le C++/CLI (.Net 2.0) ?
Si tu veux te faire une idée tu peux prendre Visual C++ 2005 Express (FR / EN)

/*
coq
MVP Visual C#
*/
Messages postés
80
Date d'inscription
mercredi 6 octobre 2004
Statut
Membre
Dernière intervention
26 septembre 2006

Je parle justement de .Net 2005 Express
Je l'ai...
J'ai comparé, et je le trouve assez catastrophique

C'est très compliqué la multitude de code pré-généré. Et si tu touche qqch, tu casses tou le projet.

Et la déclaration de variable avec des ^ partout ...
les acolades qui se mettent n'importe où...

Enfin bref, je n aime pas du tout.
Mais je vais peut être faire queque modules avec, du traitement pur.
Sais tu comment on mélange les languages ?
Il faut forcément faire des projets différents, ou tu peux avoir certaines classes en C++ et d'autres en C# ?

Nico
Strasbourg
France
Messages postés
6351
Date d'inscription
samedi 1 juin 2002
Statut
Modérateur
Dernière intervention
2 août 2014
93
Tu ne pourras pas mettre les 2 langages dans un même projet.
Par contre les interactions entre les 2 ça devrait aller.

/*
coq
MVP Visual C#
*/
Messages postés
3246
Date d'inscription
lundi 25 avril 2005
Statut
Modérateur
Dernière intervention
27 octobre 2012
39
Nico_fip1, je ne sais pas si tu connais P/Invoke, ça te permettra d'appeller tes fonctions en C natif directement dans un code C#, si tu limites le marshalling des données les performances ne sont pas mauvaises du tout.
Messages postés
80
Date d'inscription
mercredi 6 octobre 2004
Statut
Membre
Dernière intervention
26 septembre 2006

Ok, merci Lutinore.
Sais-tu par hasard dans quelles conditions il est possible de mélanger les languages en .Net ?

Etant, comme je l'ai déjà dit, novis dans le .net, que me conseilles tu (conseillez-vous) ?
- M'adapter au C# et faire du C# pur
- Tenter de "bricoller" pour utiliser mes anciennes compétences (ANSI C et C++)

Quelqu'un sait si en C++.Net les librairies standard <stdio.h> et toutes les autres, sont encore utilisable ? Toujours pour mon "memcpy"...

Bien, encore merci à tous, et on va essayer de se faire au nouveaux languages.

Faut bien se dire qu'avoir souplesse et simplicité en même temps, c'est pas facile.

Nico
Strasbourg
France
Messages postés
6351
Date d'inscription
samedi 1 juin 2002
Statut
Modérateur
Dernière intervention
2 août 2014
93
A ma connaissance le C++/CLI permet de mélanger le monde managé et non managé, d'où les déclarations avec des '^' qui si je ne trompe pas permettent de définir le fait que le Framework devra gérer cet élément. (Garbage Collector, etc)
Donc tu auras accès aux 2 mondes, mais je ne sais pas quelles seront les limitations d'utilisation de la stdlib sur un élément défini pour le Framework, je ne connais pas assez bien ce langage.

Sinon si tu veux continuer sur le C#, je pense qu'il vaut mieux "laisser tomber" les anciennes habitudes et se mettre à fond à profiter de l'architecture du Framework au lieu d'essayer de le shunter.
Bien sûr comme le dit Lutinore, l'accès à l'API Win32 est toujours possible via les techniques de PInvoke.
Après tout, le Framework est en soi un énorme wrapper au dessus de l'API Win32, avec naturellement d'autres fonctionnalités, mais son implémentation sur Windows repose naturellement sur les API de ce dernier.

/*
coq
MVP Visual C#
*/
Messages postés
80
Date d'inscription
mercredi 6 octobre 2004
Statut
Membre
Dernière intervention
26 septembre 2006

Ok, je esssayer comme ça le pense ; etude de PInvoke, en essayant de rester rigoureux.

Autre petie question, si j'ai bien compris, il n'y a plus moyen d'utiliser
#define INFO1 str[3]
ce qui permetrais de palier à mon problème d'une autre manière...

Nico
Strasbourg
France