Posté le 09/12/2014 à 21:27 Membre depuis le 27/04/2006, 59488 messages
top
avatarZeroblog

« Tout homme porte sur l'épaule gauche un singe et, sur l'épaule droite, un perroquet. » — Jean Cocteau
« Moi je cherche plus de logique non plus. C'est surement pour cela que j'apprécie les Ataris, ils sont aussi logiques que moi ! » — GT Turbo
Posté le 11/12/2014 à 20:53 Membre depuis le 18/06/2001, -26239 message
Est-ce portable comme manière de faire, svp :
char* GetName (char* filename)
{
    *char name_ptr;

    name_ptr = strrchr (filename, '/');
    if (!name_ptr)  {
        name_ptr = strrchr (filename, '\');
    }
    if (name_ptr) {
        filename = name_ptr + 1;
    }
    return filename;
}

Comme vous voyez, le but est tout simplement de retrouver un nom de fichier à partir d'un éventuel nom complet. J'aimerais éviter de faire des ifdef _linux_ toussa.
Merci bien. smile
avatar<<< Kernel Extremist©®™ >>>
Feel the power of (int16) !
Posté le 11/12/2014 à 22:10 Membre depuis le 27/04/2006, 59488 messages
Ça m'a l'air correct au moins pour Windows et Linux. (Godzil te dirait que ce n'est pas portable vu que ça ne marche pas sous MacOS <= 9 tongue)
Théoriquement ça serait mieux d'utiliser une fonction de l'OS vu qu'il pourrait y avoir des cas particuliers, mais je n'en vois pas à priori.
avatarZeroblog

« Tout homme porte sur l'épaule gauche un singe et, sur l'épaule droite, un perroquet. » — Jean Cocteau
« Moi je cherche plus de logique non plus. C'est surement pour cela que j'apprécie les Ataris, ils sont aussi logiques que moi ! » — GT Turbo
Posté le 11/12/2014 à 22:25 Membre depuis le 30/06/2001, 70810 messages
(c'est yN qui a bouffé un \ ?)

J'ai un doute sous windows, mais il me semble que (c'est un cas extreme) mais "/" est un caractère valide dans un nom de fichier. En plus si il y a un C: ou equivalent dans le chemin tu va avoir des soucis..

Tu devrait plutot regarder du coté de basename dirname (man 3)

Mais forcement ca n'existe pas sous windows :/ (enfin a traver mingw/cygwin si)

Le soucis c'est que découper un nom de fichier il y a plein de détails qu'on a tendance a oublier, ca va marcher dans 80% des cas, et 20% on va avoir des bizzareries parceque le nom de fichier contien des choses qu'on avait pas prévu..

Sinon globalement ta fonction doit marcher oui, mais tu va avoir des problemes si un nom de fichier contiens / ou \ ou si le "filename" est un dossier avec un / ou \ final

(si tu vois ce que je veux dire)

Windows a _splitfile de mémoire

edit cross: non tu vois je n'ai meme pas parlé qu'il y a des OS qui utilisent ni \ ni / comme séparateur de fichier embarrassed (et qui acceptent / ET \ dans les nom de fichiern et meme le ":" en trichant)
avatarProud to be CAKE©®™
The cake is a lie! - Love your weighted companion cube

->986-Studio's Wonder Project!<-
yN a cassé ma signature :o
Posté le 11/12/2014 à 22:35 Membre depuis le 27/04/2006, 59488 messages
Godzil (./33) :
J'ai un doute sous windows, mais il me semble que (c'est un cas extreme) mais "/" est un caractère valide dans un nom de fichier. En plus si il y a un C: ou equivalent dans le chemin tu va avoir des soucis..
Le slash fait partie des caractères interdits dans les noms de fichiers Windows (il était traditionnellement réservé pour les options des programmes en ligne de commande). Certaines fonctions le considèrent comme équivalent au backslash en entrée, probablement pour faciliter la compatibilité avec les programmes prévus pour UNIX, mais (à ma connaissance du moins) aucune n'en renvoie en sortie. Et un chemin du type "X:\machin.chose" ne pose pas de problème non plus, vu qu'il y a un backslash final. Idem pour les chemins réseaux UNC et spéciaux (ceux qui commencent par \\?\ et \\.\).

Par contre, c'est vrai qu'il y a un cas particulier que j'ai oublié : "X:machin.chose", qui désigne un fichier situé dans le répertoire courant du lecteur X, car chaque lecteur a son propre répertoire courant. Ce cas n'est pas géré par la fonction de Folco.

Wikipédia a une page intéressante sur le sujet : http://en.wikipedia.org/wiki/Path_(computing)
La doc de MS est assez complète aussi : http://msdn.microsoft.com/en-us/library/windows/desktop/aa365247(v=vs.85).aspx
avatarZeroblog

« Tout homme porte sur l'épaule gauche un singe et, sur l'épaule droite, un perroquet. » — Jean Cocteau
« Moi je cherche plus de logique non plus. C'est surement pour cela que j'apprécie les Ataris, ils sont aussi logiques que moi ! » — GT Turbo
Posté le 11/12/2014 à 23:37 Membre depuis le 18/06/2001, -26239 message
Merci beaucoupà vous deux pour toutes ces infos. Oui Zerosquare, j'ai zappé le cas que tu cites, je vais le rajouter... Ca va c'est pas grand chose.
Godzil (./33) :
En plus si il y a un C: ou equivalent dans le chemin tu va avoir des soucis..

strrchr renvoie la dernière occurence d'un \, donc tous ce qui précède sera viré. J'adore cette fonction grin
Godzil (./33) :
Mais forcement ca n'existe pas sous windows :/ (enfin a traver mingw/cygwin si)

J'y ai pensé, mais je suis pas assez skillé en MinGW, ou en cross compilation, pour faire ça proprement et de manière sûre. Mea culpa.
Godzil (./33) :
Sinon globalement ta fonction doit marcher oui, mais tu va avoir des problemes si un nom de fichier contiens / ou \ ou si le "filename" est un dossier avec un / ou \ final

Je ne crois pas, si le dernier caractère est un / ou un \, donc un dossier, ma fonction devrait renvoyer une chaine vide. J'ai pas encores testé ceci dit.
avatar<<< Kernel Extremist©®™ >>>
Feel the power of (int16) !
Posté le 11/12/2014 à 23:45 Membre depuis le 30/06/2001, 70810 messages
Ben justement tu peux vouloir le nom du dossier dans ce cas non?
avatarProud to be CAKE©®™
The cake is a lie! - Love your weighted companion cube

->986-Studio's Wonder Project!<-
yN a cassé ma signature :o
Posté le 11/12/2014 à 23:50 Membre depuis le 18/06/2001, -26239 message
En fait, non. C'est pour convertir des fichier texte au format .89t/9xt. Le nom oncalc est à inscrire dans le fichier. Si ya pas de nom, c'est considéré comme une erreur d'entrée. Si jamais tu veux traiter le contenu d'un répertoire, il suffit de passer ..../blabla/*.asm par exemple
Mais c'est vrai que j'aurais pu accepter les répertoires en entrée, j'y ai pas pensé. Le truc, c'est que je sais récupérer une liste de fichiers sous windows ou linux depuis un répertoire, mais c'est pas portable, donc ça me fait encore plus suer que ces histoires de / \.
avatar<<< Kernel Extremist©®™ >>>
Feel the power of (int16) !
Posté le 12/12/2014 à 12:45 Membre depuis le 02/11/2003, 8072 messages
À noter que l'antislash est un caractère valide dans un nom de fichier posix.
Tu peux tout à fait avoir ça comme nom de fichier : '/home/spectras/photos/2013\mars/bidule.jpg'
Le bon découpage dans ce cas est ['home', 'spectras', 'photos', '2013\mars', 'bidule.jpg']

En fait, il n'y a que deux caractères interdits : le / et le nul. Un nom de fichier tel que "-- \#&!?""";|" est totalement valide.

Essaie de lancer : echo Test >'-- \#&!?""";|'
Posté le 12/12/2014 à 13:44 Membre depuis le 18/06/2001, -26239 message
erf, donc on peut pas faire du portable, faut de la compilation conditionnelle... On va interdire les antislash, toute façon c'est interdit sur TI ^^ Mais merci, j'avais jamais fait gaffe à ça. smile

Au fait, getopt est standard ? Apparemment c'est posix, c'est implémenté par GNU, mais est-ce que MSVC connait ça ? J'aimerais garder un source portable autant que possible...
Et c'est couramment utilisé, ou alors 50% des apps gèrent ça à leur sauce ?

Merci bien. smile
avatar<<< Kernel Extremist©®™ >>>
Feel the power of (int16) !
Posté le 12/12/2014 à 14:10 Membre depuis le 30/06/2001, 70810 messages
Pas sur que sa soit tres utilise, c'est plutot recent comme ajout a POSIX, et je doute que ca soit dans la libc de windows (qui n'est pas POSIX)
avatarProud to be CAKE©®™
The cake is a lie! - Love your weighted companion cube

->986-Studio's Wonder Project!<-
yN a cassé ma signature :o
Posté le 12/12/2014 à 22:26 Membre depuis le 02/11/2003, 8072 messages
En fait, getopt() est très utilisée.
Elle fait partie de la norme POSIX.2, et elle a été renormalisée plus récemment. Enfin tout est relatif, 2001 c'était il y a 13 ans déjà.
Et même avant ça, elle était présente sur toutes les variantes UNIX, avec un comportement similaire, ce qui en faisait une excellente solution portable. En fait à part Windows, ou les cas un peu de niche comme l'OS des TI, elle est dispo absolument partout.

HP-UX, IBM AIX, toutes les BSD, tous les GNU/truc, Android, OSX, QNX, Solaris, IRIX… non vraiment à part Windows…
Posté le 17/12/2014 à 22:58 Membre depuis le 24/04/2002, 4696 messages
Attention, l'utilisation de feof() telle qu'elle est dans le code que tu as posté est mauvaise: feof() n'a de valeur clairement définie qu'après qu'un fread() ait retourné une valeur différente du nombre d'éléments que tu lui as passé en entrée (ou après qu'un fgets() ait retourné NULL, un getc() retourné EOF, etc.).

Tu n'est pas censé faire de test dessus avant.
avatarMaintenant 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.
Posté le 19/12/2014 à 19:23 Membre depuis le 16/06/2001, 69242 messages
folco : fgets pour getline, getopt est posix mais pas msvc. par contre ca doit se trouver dans mingw.

void* buffer [BLOCK_SIZE];

do {
    size_t write_count;
    size_t read_count = fread (buffer, 1, BLOCK_SIZE, src);

    if (read_count < 0) {
        fprintf (stderr, "Eh merde pour lire... num de la merde = %d\n", errno); //faire joujou avec strerror
    }
    write_count = fwrite (buffer, 1, read, dest);
    if (write_count < 0) {
        fprintf (stderr, "Eh merde pour ecrire... num de la merde = %d\n", errno);
    }

} while (!feof (src));

mais j'aime pas bien fread avec ses histoires de lire des blocks, moi je sais jamais qui est block_size et qui est block_count

do {
    size_t write_count;
    size_t read_count = read (srcfd, buffer, BLOCK_SIZE);

    if (read_count < 0) {
        fprintf (stderr, "Eh merde pour lire... num de la merde = %d\n", errno); //faire joujou avec strerror
    }
    write_count = write (dstfd, buffer, read_count);
    if (write_count < 0) {
        fprintf (stderr, "Eh merde pour ecrire... num de la merde = %d\n", errno);
    }

} while (read_count == BLOCK_SIZE); //pas de eof pour les api a file descriptor
Posté le 19/12/2014 à 19:33 Membre depuis le 27/04/2006, 59488 messages
La version avec fread()/fwrite() n'est pas correcte. fread() et fwrite() peuvent renvoyer une valeur positive et plus petite que la taille du bloc s'il y a eu une erreur de lecture.

La logique m'a l'air bonne pour read()/write(), par contre.
avatarZeroblog

« Tout homme porte sur l'épaule gauche un singe et, sur l'épaule droite, un perroquet. » — Jean Cocteau
« Moi je cherche plus de logique non plus. C'est surement pour cela que j'apprécie les Ataris, ils sont aussi logiques que moi ! » — GT Turbo
Posté le 19/12/2014 à 22:27 Membre depuis le 16/06/2001, 69242 messages
ah oui, bah tu peux checker ferror pour en etre sur .
Posté le 20/12/2014 à 11:48 Membre depuis le 24/04/2002, 4696 messages
L'usage, c'est si fread() retourne une valeur différente du nombre de blocs qu'on lui a demandé, alors on check ferror() / feof() (généralement, si ce n'est pas l'un on considère que c'est l'autre) et on agit en conséquence.
avatarMaintenant 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.
Posté le 20/12/2014 à 14:17 Membre depuis le 30/06/2001, 70810 messages
heureusent que fopen initialisé correctement la structure FILE et met le flag EOF a la bonne valeur faisant que feof marche.
avatarProud to be CAKE©®™
The cake is a lie! - Love your weighted companion cube

->986-Studio's Wonder Project!<-
yN a cassé ma signature :o
Posté le 20/12/2014 à 14:49 Membre depuis le 18/06/2001, -26239 message
En effet, merci beaucoup pour cette remarque, le pire c'est que je l'ai lu il y a quelques semaines, mais ne l'ayant jamais utilisé, je n'ai pas percuté. smile
avatar<<< Kernel Extremist©®™ >>>
Feel the power of (int16) !