1

Salut !


J'essaye de concatener un entier avec un char*, mais cela me donne un resultats faux avec cette technique: transformation du short en char* par sprintf, et concatenation des 2 char* par strcpy (donné dans TiWiki):


attribute__((regparm)) char * strcpy_fast(char * dst, const char * src)
{
register char * result;
__asm__ (
"move.l %1,%0 \n\t"
"move.b %0@+,%2@+ \n\t" /* copie d'un caractère */
"bne .-2 \n\t" /* bouclage jusqu'à un caractère \0 */
: "=a" (result)
: "g" (dst), "a" (src)
);
return result-1; /* result a été incrémenté une fois de trop */
}

[...]
{
while(key != -35)
{
key = ngetchx();
key = key - 48;
char * keyC = sprintf(keyC, "%d", key);

calcul = strcpy_fast(calcul, keyC);
printf("%s", calcul);
}
}



Et cela ne maffiche rien a l'écran et finit meme par me donner un Out Of Memory !



Merci d'avance.

2

lut,

Humm, tu devrait ptet allouer l'espace pour ton keyC (malloc) , avant de sprintf.

char *keyC = malloc(CONSTANTE * sizeof(char));
sprintf(keyC, "%d", key);


Fais le de préférence avant ta boucle.

3

Merci pour l' idée de l'allocatoin dynamimique, mais malhereusement, c'est la variable calcul qui provoque le Out of Memory. Mais comme je ne connais malheureusement pas la taille de cette derniere lors de son allocation, je n'ai donc pas la constante.

Je pense que le probleme vient de sprintf car apres avoir regardé la valeur de varible, je remarque que sprintf concatene 2 fois la variable key dans la variable keyC !

Donc: comment transformer un short en char* ?



Merci d'avance

4

> char * keyC = sprintf(keyC, "%d", key);
Please RTM pour savoir ce que retourne sprintf, et pourquoi ça ne se convertit pas en char*.
avatar
Membre de la TI-Chess Team.
Co-mainteneur de GCC4TI (documentation en ligne de GCC4TI), TIEmu et TILP.
Co-admin de TI-Planet.

5

euh... Pourquoi tu utilises un strcpy pour concaténer ?
c'est pas plutot un strcat qu'il faudrait utiliser?

Et tu ne peux pas convertir directement un entier en chaîne, sans réserver un buffer quelque part qui contiendra ladite chaîne.
Pour les entiers, il me semble qu'un buffer de 12 octets suffit à représenter n'importe quel entier sous forme décimale. (mais pas un float)
Pour un short, un buffer de 8 octets devrait suffire. En suite, tu utilises strcat pour concaténer les deux buffers (lebuffer de destination doit être assez grand pour les contenir tous les deux!)

Edit: Cross
avatar
Maintenant j'ai la flemme de garder une signature à jour sur ce site. Je n'ai même plus ma chaîne Exec sous la main.

6

Bien vu: il utilise strcpy... Ceci dit, ça pourrait marcher, en exploitant correctement la valeur de retour de sprintf.
avatar
Membre de la TI-Chess Team.
Co-mainteneur de GCC4TI (documentation en ligne de GCC4TI), TIEmu et TILP.
Co-admin de TI-Planet.

7

C'est vrai, sprintf renvoie le nombre de caractères écrits...
(Au passage, les "pointer from integer without a cast", ils doivent pleuvoir dans ce code.

Mais ce que j'ai du mal à voir, c'est pouquoi il parle de concaténer, alors que je ne vois aucune concaténation dans le code, ni aucune raison de concaténer quoi que ce fût...
car si c'est pour écrire un nombre en affichant chaque shiffre entrée à l'écran, y'a beaucoup plus simple que des conversiosn dans un sens puis dans l'autre...
avatar
Maintenant j'ai la flemme de garder une signature à jour sur ce site. Je n'ai même plus ma chaîne Exec sous la main.

8

Hum

En fait, ce que je veux éssayer de faire c'est de demander a ce que l'utilisateur tape un calcul et le valide par ENTER.

Donc, pour cela je fais une boucle while jusqu'a ce que l'utilisateur tape sur enter. Ensuite j'attends le prochain caractere qu'il tape pour l'ajouter à la chaine calcul contenant les caracteres precedant par concatenation. Mais comme la concatenation n'accepte qu des char*, il faut d'abord transformer le int key en char*.

Hum donc avec vos conseils j' en suis arriver au code suivant:
     int key = 0;      char *calcul;      char *keyC = malloc(1 * sizeof(char));            while(key != -35)      {           key = ngetchx();           key = key - 48;                      //printf("%d     ", key);           sprintf(keyC, "%d", key);           //printf("%s", keyC);                                 strcat(calcul, keyC);           printf("%s", calcul);      }            printf("%s \n\n", calcul);


Mais je n'ai pas trop compris la fin du 4me post par Link:

Et tu ne peux pas convertir directement un entier en chaîne, sans réserver un buffer quelque part qui contiendra ladite chaîne.


Si j'ai un entier "avec des données", et un chaine "sans données", la chaine sans donnée ne peut elle pas faire office de buffer ?


Merci d'avance

9

Ben, y'a beaucoup plus simple: tu réserve un buffer, un compteur de caractères et tu rajoutes directement le résultat de ngetchx() à la fin...

char buf[42];
size_t i;
short k=0;

//quitte la boucle si reçu caractère 13 
//(normalement c'est enter, mais je ne sais pas si c'est le cas sur TI)
for(i =0 ; i<41 && k!=13 ; i++) 
  {
  k = ngetchx();
  buf[i] = k;
  i++;
  //place un caractère nul a la fin.
  //inutile si on initialise le buffer avec des zéros avant.
  buf[i] = '\0'; 
  printf("%s", buf);
  }

Pas besoin de convertir d'abord le caractère de la touche en chiffre, puis à nouveau en caractère roll
avatar
Maintenant j'ai la flemme de garder une signature à jour sur ce site. Je n'ai même plus ma chaîne Exec sous la main.

10

Ok.

Mais le probleme: on ne peut faire des calculs de plus de 42 caractère ! Le probleme est que le calcul peut etre des fois extremement long et extrement cours. Donc, le seul moyen que j'ai trouvé pour remlédier a cette situation est d'utiliser des pointeurs..... Donc si pointeur l'utilisation de [i]buf = k; devient mauvaise, on ne peut plus connaitre la limite de i, etc....



Merci d'avance.

11

Ben, tu fais de l'allocation dynamique: tu alloues ton buf avec un malloc, et puis dès que i atteint la taille maximale actuelle, tu fais un realloc en doublant la taille...
avatar
Maintenant j'ai la flemme de garder une signature à jour sur ce site. Je n'ai même plus ma chaîne Exec sous la main.

12

Mais lorsque j'essaye cette technique, la valeur du buffer est tres innatendu:
     short size = 10 * sizeof(char);      size_t i;      short k=0;       char *buf = malloc(size);              while(k != -35 && k != 216)      {           for(i = 0 ; i < size-1 && k != -35 && k != 216; i++)             {                 k = ngetchx() - 48;                if(k != -35 && k != 216)                {                     buf[i] = k;                      i++;                     printf("%d", k);                 }           }                       if(k != -35 && k != 216)           {                size = size * 2;                buf = realloc(buf, size);           }      }      printf("\n \n %s\n\n", buf);      buf = realloc(buf, size+1);      buf[size] = '\0';      printf("\n \n %s\n\n", buf);





Merci d'avance

13

14

Nanar_duff :
Mais lorsque j'essaye cette technique, la valeur du buffer est tres innatendu:


C'est un pe normal ...

k = ngetchx() - 48;


En faisant ça, tu met dans ton buffer le caractère ascii correspondant au nombre tapé.. Il ne faut pas faire le - 48.

Sinon, je vois pas trop pourquoi tu as fait 2 boucles, j'aurai plutot fait un truc de ce genre la :


unsigned short i, k, t;
unsigned char *calcul;

t = 40;
i = 0;
calcul = malloc(t * sizeof(char));

while ((k = ngetchx()) != -35)
{ 
 if (i >= t - 1)
  calcul = realloc(calcul, (t += 40));
 
 calcul[i++] = k;
}

if (i >= t - 1)
 calcul = realloc(calcul, t + 1);

calcul[i] = 0;

15

> (Au passage, les "pointer from integer without a cast", ils doivent pleuvoir dans ce code.)
Probable.
"Nanar_duff", poste tes options de compilation (Projet / Options si tu es dans l'IDE). Moins de -W -Wall -Wextra -Os -ffunction-sections -fdata-sections -mregparm=5 -mpcrel -Wa,-l -Wa,--all-relocs + toutes les optimisations du linker, ce n'est pas bien.
avatar
Membre de la TI-Chess Team.
Co-mainteneur de GCC4TI (documentation en ligne de GCC4TI), TIEmu et TILP.
Co-admin de TI-Planet.

16

Martial Demolins :
tu parles de la valeur... tu l'initialise ton buffer?


Heuh que veut tu dire par initialiser le buffer ? (tu veux dire buf = "" ?)


Ykizar :
En faisant ça, tu met dans ton buffer le caractère ascii correspondant au nombre tapé.. Il ne faut pas faire le - 48.


Je m'explique pour le -48: en fait, pour les chiffres, les codes des touches sont: x + 48 (x = chiffre de 0 à 9). Donc si j'enleve -48, j'obtiens directement les chiffres, sans utilisations de if ou autre. Je pense que cette technique est bonne car si l' on affiche k, les valeurs sont correcte, seul buf est incorrect.
Merci beaucoup pour ce code beaucoup plus compact !



Lionel Debroux
"Nanar_duff", poste tes options de compilation (Projet / Options si tu es dans l'IDE). Moins de -W -Wall -Wextra -Os -ffunction-sections -fdata-sections -mregparm=5 -mpcrel -Wa,-l -Wa,--all-relocs + toutes les optimisations du linker, ce n'est pas bien.


Heuh, mes options de compilations ne vont pas bien loin: tigcc t.c => aucune option de compilation.



Merci d'avance.

17

18

Alors a ton avis :




for(g=0 ; g < size ; g++)
{
buf[g] = ""
}




Mais la je ne suis pas trop car ceci est la meme chose que buf[x] = k non ?



Merci d'avance.

19

20

Nanar_duff :
Je m'explique pour le -48: en fait, pour les chiffres, les codes des touches sont: x + 48 (x = chiffre de 0 à 9). Donc si j'enleve -48, j'obtiens directement les chiffres, sans utilisations de if ou autre. Je pense que cette technique est bonne car si l' on affiche k, les valeurs sont correcte, seul buf est incorrect.


Euh, c x + 48 paske, les différents chiffres sont à partir de 48 dans la table ascii. En fait, en faisant ton x - 48 tu obtiens le bon chiffre, mais lorsque tu les stocke dans ton buffer, il te faut utiliser la valeur ascii et non pas la valeur décimale et donc ne pas faire le - 48.
(Au passage 48 = '0' d'ou la soustraction).

Si tu n'est pas convaincu, fais un printf("%c", touche - 48) et tu vera que ça correspond aux même symboles (et non pas aux chiffres) que dans ton buffer.

L'initialisation du buffer est un pe inutile dans ton cas vu ke tu le rempli et tu que met un 0 à la fin, peu importe ce qu'il contenait avant.

21

Hum. Heuh... Merci Ykizar smile

Mais alors heuh je necomprends pas trop l' explication: la valeur du short est transformé en valeur ASCII quand on le stock dans un char ? Hum en gros il s'agit d'une sorte de surcharge d' operateur preconcue eek ?!



Donc, le schmilblik avance: mais la je suis encore plus perdu. Si j'essaye sans memset, alors, (hum) je ne sais par quel miracle i n'a plus l'air d'être incrementé !

	short size = 10 * sizeof(char);
	size_t i;
	short k=0; 
	char *buf = malloc(size); 
	//memset(buf, '\t', size);
 	
	while(k != 13 && k != 264)
	{
		for(i = 0 ; i < size-1 && k != 13 && k != 264; i++)  
		{ 
			k = ngetchx();
			if(k != -35 && k != 264)
			{
				buf[i] = k;
				i++;
				printf("%s", buf);
			}
		} 
		
		if(k != -35 && k != 264)
		{
			size = size * 2;
			buf = realloc(buf, size);
		}
	}



Mais quant je decommente le memset, le resultat devient encore plus bizarre: le caractère \t reste dans la var buf 1 fois sur 2. Je m'explique: si la var buf = 8\t9\t7\t6\t5\t4\t3\t2\t1\t0, alors on aura taper sur: 8976543210...... Et si je mets \0 comme caractère dans memeset, alor il se passe comme si memset n'existait pas, seule le prmier chiffre est pris en compte



Merci d'avance

22

23

Je veux dire par la que quant:

short x = 48;
char* y;

y = x;



Par quel miracle 48 = 0 dans y ?!


Hum exactement triso , heuh voila ma source au complet:
//#define SAVE_SCREEN       #define USE_TI89         #include <tigcclib.h>         //tt les includes void _main(void)  {      FontSetSys(F_8x10);            printf("\t?");            short size = 10 * sizeof(char);      size_t i;      short k=0;       char *buf = malloc(size);       memset(buf, ' ', size);             while(k != 13 && k != 264)      {           for(i = 0 ; i < size-1 && k != 13 && k != 264; i++)             {                 k = ngetchx();                if(k != -35 && k != 264)                {                     buf[i] = k;                     i++;                     printf("%s", buf);                }           }                       if(k != -35 && k != 264)           {                size = size * 2;                buf = realloc(buf, size);           }      }      printf("\n \n %s\n\n", buf);      buf = realloc(buf, size+1);      buf[size] = '\0';      printf("\n \n %s\n\n", buf);            while(k != 264)      {           k = ngetchx();      } }      


Si vous auriez le temps de la tester svp



Merci d'avance

24

> Heuh, mes options de compilations ne vont pas bien loin: tigcc t.c => aucune option de compilation.
Horreur. Je sais bien que certains profs le font, mais franchement, compiler sans optimisation et compiler sans warnings (surtout du C !)...
avatar
Membre de la TI-Chess Team.
Co-mainteneur de GCC4TI (documentation en ligne de GCC4TI), TIEmu et TILP.
Co-admin de TI-Planet.

25

Erf ton code de trois ligne là....

essaie de le compiler tout seul....

[cite]tayst.c
int main()
{
short x=321;
char *y;
y = x;
return 0;
}[/Cite]

Le compilateur te renvoie
tayst.c:5: attention : affectation transforme un entier en pointeur sans transtypage


Que ce passe t'il ?

short x;
ça crée une variable x

char* y;
ça crée un POINTEUR qui s'apelle y pointant vers la variable *y.

en faisant
y = x;
c'est l'ADRESSE que tu modifie, pas la VALEUR !

Si tu n'as pas d'erreur de segmentation à l'exécution, là il y a un miracle.
avatar
† In te confirmátus sum ex útero : de ventre matris meæ tu es protéctor meus.
illwieckz.net ~ Unvanquished ~ gg.illwieckz.net { le frag courtois } ~ NetRadiant ~ Crunch

26

oui en effet quelle horreur sick

En tout cas nos profs eux ne sont pas comme ça.
La première choses qu'ils nous ont dis c'est de compiler en faisant ça : gcc -Wall monprog.c
Et si on lance une compilation devant eux sans le faire le -Wall euh fear !
avatar
† In te confirmátus sum ex útero : de ventre matris meæ tu es protéctor meus.
illwieckz.net ~ Unvanquished ~ gg.illwieckz.net { le frag courtois } ~ NetRadiant ~ Crunch

27

short x = '0';  // ==> x = 48
char y = 48; // ==> y = '0'


C'est pas "une sorte de surcharge d' operateur preconcue", c la correspondance entier / char de la table ascii.
Ascii

28

Vrai, bien que le charset des TI-68k ne soit pas de l'ASCII, mais un ISO 8859-1 (je crois) modifié pour avoir les symboles mathématiques et les lettres grecques, par exemple, car la partie 32-127 est identique pour tous (sauf bizarre).
avatar
Membre de la TI-Chess Team.
Co-mainteneur de GCC4TI (documentation en ligne de GCC4TI), TIEmu et TILP.
Co-admin de TI-Planet.

29

naPO, lionel -> Nanar_duff ne sait sans doute pas qu'il n'y a aucun avertissment par défaut. Je l'ai moi-même appris à mes dépens en projet de compil sad Voilà ce qui arrive quand on est habitué à visual c++ (warning lv3 par défaut, erreur pour tout identificateur non-déclaré)

Nanar_duf comme l'a dit Ykizar, il n'y a pas 48 = 0 mais 48 = '0': le caractère "zéro" (et aussi 0 = '\0' : le caractère nul, qui termine une chaîne)
Edit: au fait, dans ta boucle, il y a deux fois i++ : c'est normal que le buffer soit rempli un caratère sur 2 triso

PS: C'est quoi, le caractère -35 ? confus (ou plutot 65501, je suppose...)
avatar
Maintenant j'ai la flemme de garder une signature à jour sur ce site. Je n'ai même plus ma chaîne Exec sous la main.

30

Hum:
illwieckz :
Erf ton code de trois ligne là....

essaie de le compiler tout seul....


Excusez moi mais j'ai vraiment ce code à la va vite sans reflechir; je voulais exprimer plutot ce bout de code :
char *buf = malloc(10 * sizeof(char));
short x = 48
buf[0] = x;




Lionel Debroux :
Horreur. Je sais bien que certains profs le font, mais franchement, compiler sans optimisation et compiler sans warnings (surtout du C !)...


Heuh hum. Reparons vite cette betise alors: a part l' option -Wall que vaut-il mieux ajouter comme option à la compilation ?




Link :
Nanar_duf comme l'a dit Ykizar, il n'y a pas 48 = 0 mais 48 = '0': le caractère "zéro" (et aussi 0 = '\0' : le caractère nul, qui termine une chaîne)
Edit: au fait, dans ta boucle, il y a deux fois i++ : c'est normal que le buffer soit rempli un caratère sur 2 triso

PS: C'est quoi, le caractère -35 ? confus (ou plutot 65501, je suppose...)


Merci pour l' histoire de traduction entre ASCII et short, je pense avoir compris.
Hum, ne disons rien pour les 2 fois i++; dehors

Et en fait le -35 = 13 (code de la touche enter) - 48. roll




Hum et sinon, à la fin, l' algorithme:
	short size =   1 * sizeof(char);
	short k = 0;
	char *buf = malloc(size);
	memset(buf, ' ', size);

	short i = 0;
	while(k != 13 && k != 264)
	{
		k = ngetchx();
		if(k != 13 && k != 264)
		{
			buf[i] = k;
			printf("%c", k);
			size = size + sizeof(char);
			buf = realloc(buf, size);
			i++;
		}
	}
	
	buf[size] = '\0';







Merci beaucoup !