[C] coder ca propre fonction printf() ?

Salut a tous [:bubkate]
d’abord a tous bon dimanche :smiley:

Je dois implementer un module RATIONNEL en C (gcc of course !).
j’ai fait toutes les fonctions de maniments et de lecture.
Je bloque un peu sur la fonction qui sert a afficher.
signature:


void affrationnel(char * format,RATIONNEL a)

Qui affiche sous la forme num/den si le format n’est pas spécifier, sinon utilise le format.

  1. Comment faire un argument optionnel (pouvoir appeler la fonction avec ou sans format avec une seule definition de la fonction) ?

  2. esce qu’une fonction de remplacement dans des char * existe (ex remplacer %rat dans une chaine) ?

Cordialement

en c y a pas d’argument optionnel…

y a les varg (comme dans printf) mais c coton a utiliser
http://membres.lycos.fr/dancel/c/c70_140.htm

le moyen le plus simple c de passet NULL comme format et dans ta fonction tu teste si c NULL tu prend ton format par defaut…

Je vois que ca marche pas les varg si on veut que le 1er argument soit variable :confused:
(a moins de declaré f(…) mais on peut l appeler sans rien aussi :/)
Etant donnée que l’on ne la pas appris et que je trouve ca de l’abus de demander un truc comme ca vu le niveau de nos cours (cf. ici)
et vu qu’ils sont meme pas precis dans l’énoncé je vais pas le faire :smiley:

EDIt: En tout les cas merci pour le lien quazardous :jap:

Si t’utilises les varg il faut que le premier arguement de ta fonction soit fixe.
type func(type var, …);

Salut,

Je ne sais pas si ça peut t’aider, on avait codé ça lors d’un projet, ça marchait un peu bancale il me semble :d, on avait fait ça vite fait (normalement tout ce qui n’est pas commenté marche) :
[cpp]int EcrireFormat(FICHIER* f, char* fmt, … )
{
va_list pa;
int entier, chr, total;
unsigned int u_entier;
int* p_entier;
char car[255];
char* str;

va_start(pa, fmt);

while(fmt[0] != ‘\0’)
{
if (fmt[0] == ‘%’)
{
fmt++;
switch (fmt[0])
{
case ‘d’ :
entier = va_arg(pa, int);
strcpy(car, int_to_str(entier));
total += write(f->fd,car,strlen(car));
break;
case ‘i’ :
entier = va_arg(pa, int);
strcpy(car, int_to_str(entier));
total += write(f->fd,car,strlen(car));
break;
case ‘u’ :
u_entier = va_arg(pa, unsigned int);
strcpy(car, uint_to_str(u_entier));
total += write(f->fd,car,strlen(car));
break;
case ‘c’ :
chr = va_arg(pa, int);
car[0] = (char)chr;
total += write(f->fd,car,1);
break;
/case ‘o’ :
entier = va_arg(pa, int);
strcpy(car, int_to_str(int_to_oct(entier)));
total += write(f->fd,car,strlen(car));
break;
/
case ‘s’ :
str = va_arg(pa, char*);
total += write(f->fd,str,strlen(str));
break;
default :
total += write(f->fd,fmt,1);
}
fmt++;
}
else
{
total += write(f->fd,fmt,1);
fmt++;
}
}
return total;
}[/cpp]

Par contre je ne sais pas les include qu’il faut faire, c’était inclu dans un programme ou on devait refaire les fonctions de stdio, voici tous les includes qu’il y avait :
[cpp]#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>
#include <errno.h>
#include <stdarg.h>
#include <string.h>
#include <limits.h>[/cpp]

Ah il y a aussi les int_to_str et uint_to_str qu’il te faut:
[cpp]char* uint_to_str(unsigned int entier){
char* chaine;
char tmp[255];
int taille, i = 0;
unsigned int reste;

while (entier > 0){
tmp[i++] = (entier % 10) + ‘0’;
entier = entier / 10;
}
i–;
taille = i;
chaine = (char*)malloc((i+1)*sizeof(char));
while (i >= 0){
chaine[taille-i] = tmp[i];
i–;
}
chaine[taille+1] = ‘\0’;
return chaine;
}

char* int_to_str(int entier){
char* chaine;
char tmp[255];
char signe = ‘+’;
int reste, taille, i = 0;

if (entier < 0){
entier = -entier;
signe = ‘-’;
}
while (entier > 0){
tmp[i++] = (entier % 10) + ‘0’;
entier = entier / 10;
}
if (signe == ‘+’){
i–;
}else{
tmp[i] = ‘-’;
}
taille = i;
chaine = (char*)malloc((i+1)*sizeof(char));
while (i >= 0){
chaine[taille-i] = tmp[i];
i–;
}
chaine[taille+1] = ‘\0’;
return chaine;
}[/cpp]

Pfiou quand je relit mon code je pleure, tu dois pouvoir coder un peu plus proprement ces fonctions sans utiliser de tmp, avec des realloc par exemple.

:kimouss:

merci mec, le tp a déja été rendu mais j’étudie ca pour ma culture personelle :kimouss: