Les membres ayant 30 points peuvent parler sur les canaux annonces, projets et hs du chat.
La shoutbox n'est pas chargée par défaut pour des raisons de performances. Cliquez pour charger.

Forum Casio - Autres questions


Index du Forum » Autres questions » Ouvrir un fichier en binaire
Darkjura Hors ligne Membre Points: 389 Défis: 0 Message

Ouvrir un fichier en binaire

Posté le 28/11/2020 10:18

Bonjour

IL s'agirait, en C, d'ouvrir un fichier (par exemple de la mémoire de stockage) en binaire (via Bfile, un syscall ou une technique plus compliquée). N'y a-t-il pas d'équivalent au "rb" ou "wb" du C classique sur ordinateur ?

Toute réponse serait carrément la bienvenue...


Kbd2 Hors ligne Membre Points: 269 Défis: 0 Message

Citer : Posté le 28/11/2020 10:24 | #


The Bfile calls allow you to specify if you want the handle to be r, w, or rw. The contents are read into whichever array/buffer you give it, if it's of type char then you can operate on the individual bytes.

Bfile is a bit broken though (file sizes must be 2-aligned, and only one write can be performed on a writeable handle), and we haven't documented the filesystem enough to devise a replacement.
Yatis En ligne Membre Points: 581 Défis: 0 Message

Citer : Posté le 28/11/2020 10:44 | #


N'y a-t-il pas d'équivalent au "rb" ou "wb" du C classique sur ordinateur ?

Ce n'est pas encore fini d'être implémenté mais la fxlib permettra d'avoir une grosse abstraction de cette partie, enlevant certaines limitations alakon ce qui nous permettra de créer des fichiers à la volée, d'avoir une API très proche de la glibc, de faire plusieurs écritures là où on veut et d'ouvrir autant de fichiers que l'on souhaite. Ça vend du rêve mais c'est réalisable, il me manque juste beaucoup de temps en ce moment.

En attendant, tu peux utiliser le syscall int Bfile_OpenFile(const uint16_t *pathname, int mode) pour ouvrir un fichier (le mode n'est pas pris en compte sur les power graphics II), int Bfile_ReadFile(int handle, void *buffer, size_t size, int position) pour lire, int Bfile_WriteFile(int handle, const uint16_t *buffer, size_t nb) (fait attention car le buffer ainsi que la taille doivent être multiple de 2 et tu ne peux faire qu'une seule écriture sous peine d'avoir des données corrompus). (plus d'infos ici -> https://wiki.planet-casio.com/fr/Fxlib.h#Fonctions_de_manipulation_des_fichiers)
Lephenixnoir En ligne Administrateur Points: 24572 Défis: 170 Message

Citer : Posté le 28/11/2020 10:56 | #


N'y a-t-il pas d'équivalent au "rb" ou "wb" du C classique sur ordinateur ?

En fait c'est l'inverse : quand tu lis c'est automatiquement en mode "rb" ou "wb" et il n'y a pas d'équivalent du mode "r" ou "w".

Contrairement à ce que tu pourrais croire, le more "r" ou "w" de la libc classique n'est pas le mode le plus naturel. À chaque lecture et écriture, il convertit les fins de ligne (LF/CRLF) dans le format du système. Le mode "rb" ou "wb" est le mode le plus "simple", qui renvoie juste le contenu du fichier.

BFile ne s'embête pas à te fournir la conversion des fins de lignes AFAIK, et donc quand tu ouvres un fichier c'est toujours en mode binaire.
Mon graphe (11 Avril): ((Rogue Life || HH2) ; PythonExtra ; serial gint ; Boson X ; passe gint 3 ; ...) || (shoutbox v5 ; v5)
Darkjura Hors ligne Membre Points: 389 Défis: 0 Message

Citer : Posté le 28/11/2020 11:52 | #


Lephenixnoir a écrit :
BFile ne s'embête pas à te fournir la conversion des fins de lignes AFAIK, et donc quand tu ouvres un fichier c'est toujours en mode binaire.

...Et pourtant, quand on lit des fichiers avec Bfile_ReadFile(), en entrant une chaîne de caractères comme argument, la fonction traduit automatiquement ce qu'elle trouve dans le fichier en ASCII, n'est-ce pas ? Comment donc obtenir une "chaîne de caractères binaire" (ex: "0100") après lecture du fichier ?
Lephenixnoir En ligne Administrateur Points: 24572 Défis: 170 Message

Citer : Posté le 28/11/2020 12:03 | #


Aha donc toi aussi tu es sous l'emprise de la "malédiction de la conversion".

Pour faire court : le binaire n'est pas ce que tu crois. C'est une suite de bits 0 et 1, pas une suite de caractères 0 et 1 (l'ASCII de "0" c'est 48 sur huit bits, donc c'est la suite de 8 bits 00110000, et l'ASCII de "1" c'est de même 00110001).

Quand tu lis le fichier tu obtiens la séquence de bits 0 et 1 qui est dans le fichier. Toujours. Et après c'est à toi de voir comment tu interprètes ces bits. Si tu prends la séquence 00110001 comme un char, c'est "1". Si tu la prends comme un int sur 8 bits, c'est 49. Tu peux l'interpréter comme un flottant sur 8 bits, aussi ; bref tu peux en faire ce que tu veux.

BFile n'a rien converti du tout, il t'a donné les bits du fichier. Si tu as l'impression d'obtenir de l'ASCII c'est parce que tu le charges dans un char * et que tu l'affiches comme du texte. Mais tu n'es pas obligé de faire ça.

En C il n'y pas d'unité agréable plus petite qu'un octet (8 bits) donc tu seras obligé de passer par là de façon intermédiaire. Si tu veux lire les bits individuels, généralement c'est mieux de se donner un entier non-signé, et sur 8 bits tu as unsigned char (pour faire simple). Tu peux charger ton fichier dans un tableau de unsigned char et à partir de là chaque élément du tableau représentera 8 bits de données. Ensuite tu peux utiliser les opérations bit-à-bit sur les entiers en question pour sortir les bits inviduels.

Dans tous les cas sortir une chaîne de caractères utilisant les caractères "0" et "1" n'est pas très intéressant (à part si c'est pour l'afficher à l'écran) parce que tu vas transformer tous les 0 en 00110000 et tous les 1 en 00110001, ce pour quoi tu auras besoin de 8 fois plus de mémoire que ce qui est nécessaire pour stocker la totalité du fichier. Pour calculer avec les bits, utilise les entiers 8 bits et les opérations bit-à-bit.

TL;DR : Il n'y a pas de conversion, et tu as déjà les bits que tu veux. Tu vois de l'ASCII parce que tu les charges dans un tableau de char mais tu peux les voir comme tu veux, les bits en eux-même n'ont pas de "type".
Mon graphe (11 Avril): ((Rogue Life || HH2) ; PythonExtra ; serial gint ; Boson X ; passe gint 3 ; ...) || (shoutbox v5 ; v5)
Dark storm En ligne Labélisateur Points: 11641 Défis: 176 Message

Citer : Posté le 28/11/2020 12:06 | #


Bon, y'a encore du boulot d'apprentissage. Il ne faut pas confondre donnée et représentation.

La donnée, c'est ce qui est physiquement dans la mémoire. Une suite de 0 et de 1, classique quoi. La représentation, c'est comment tu vois la donnée, ie comment tu la manipule.

Un exemple pour lequel on a 3 fois la même donnée en mémoire, et 3 manières de la représenter.
char a[] = "Àlo";
unsigned int b = 0xb76c6f00;
int c = -1217630464;


Dans tous les cas, dans la mémoire, ça donne 1011 0111 0110 1100 0110 1111 0000 0000.
Il se trouve que BFile te retourne la donnée sous la forme d'un tableau de char, donc comme le premier exemple. À toi ensuite de la traiter comme tu veux.
Finir est souvent bien plus difficile que commencer. — Jack Beauregard
Darkjura Hors ligne Membre Points: 389 Défis: 0 Message

Citer : Posté le 28/11/2020 12:23 | #


Oké oké, j'enregistre. Mais comment connaître la donnée parce qu'on ne pas l'afficher en mode binaire, n'est-ce pas ? On peut afficher un char, un unsigned int, un int (qui ne sont que des représentations de la donnée) mais on ne peut pas afficher la longue suite de 0 et de 1...
Kbd2 Hors ligne Membre Points: 269 Défis: 0 Message

Citer : Posté le 28/11/2020 12:44 | #


Gint has functionality to display a variable as hexadecimal, which is easy to convert to binary.

EDIT: You can also use sprintf for hexadecimal, or bitwise operations to create a string with the binary representation of the number, but this is inefficient. It's very rare you want the raw bits of a variable.
Darkjura Hors ligne Membre Points: 389 Défis: 0 Message

Citer : Posté le 28/11/2020 12:50 | #


But I don't work with Gint...
I work with the Casio SDK...
Kbd2 Hors ligne Membre Points: 269 Défis: 0 Message

Citer : Posté le 28/11/2020 12:51 | #


You will have to learn to use breakpoints and the SDK's local variable viewer in that case.
Darkjura Hors ligne Membre Points: 389 Défis: 0 Message

Citer : Posté le 28/11/2020 13:01 | #


En fait, ce que je voudrais faire, c'est un add-in qui lit une picture. Pour pouvoir modifier un pixel, il faut forcément changer un bit de cette picture, pas vrai ? Et d'où le fait que je voulais ouvrir un fichier en binaire. Bon du coup, seconde question: Comment modifier une variable d'un bit ?
Ex:
char a[] = "Àlo";
Donc dans la mémoire, ça donne 1011 0111 0110 1100 0110 1111 0000 0000.
Et je voudrais que ce soit 1011 1111 0110 1100 0110 1111 0000 0000

Est-ce possible ?
Kbd2 Hors ligne Membre Points: 269 Défis: 0 Message

Citer : Posté le 28/11/2020 13:06 | #


Bitwise operations let you modify the contents of a byte. I recommend researching bitwise operations in C.
Lephenixnoir En ligne Administrateur Points: 24572 Défis: 170 Message

Citer : Posté le 28/11/2020 13:19 | #


Darkjura a écrit :
Mais comment connaître la donnée parce qu'on ne pas l'afficher en mode binaire, n'est-ce pas ? On peut afficher un char, un unsigned int, un int (qui ne sont que des représentations de la donnée) mais on ne peut pas afficher la longue suite de 0 et de 1...

Pour ton information, en général on n'affiche pas du binaire sous forme de 0/1 parce que c'est pas assez compact... faut en tartiner des pages. À la place, on l'écrit en hexadécimal : pareil, mais chaque symbole fait 4 bits.

En hexa, 0 représente la suite 0000, 1 représente 0001, ..., 9 représente 1001, a représente 1010, ... et f représente 1111.

Tu peux afficher un octet un hexa avec le format %02x de sprintf(), par exemple sprintf(str, "%02x", 48) te donnera 00110000 dans str, que tu peux ensuite afficher avec locate() ou PrintXY().

Le standard C ne donne pas de format pour le binaire (y'a pas de truc genre %b qui pour la suite de 8 bits 00110000 afficherait la suite de 8 caractères "00110000"). Je peux toujours le coder dans gint comme une extension, cependant le SDK ne permet pas d'étendre les formats disponibles. Tu peux aussi écrire ta fonction pour générer le texte. Mais si tu le peux je te conseille de t'habituer à l'hexadécimal, tu ne le regretteras pas !

En fait, ce que je voudrais faire, c'est un add-in qui lit une picture. Pour pouvoir modifier un pixel, il faut forcément changer un bit de cette picture, pas vrai ? Et d'où le fait que je voulais ouvrir un fichier en binaire.

C'est exact, tu es sur la bonne voie.

Voilà quelques indices. 1 << i te donne un entier qui contient que des 0, sauf un 1 à la position i (comptée à partir de la droite). Par exemple sur 8 bits, 1<<3 c'est 00001000. Et voilà comment tu peux fixer la valeur d'un bit :

xxxxxxxx |  00001000 = xxxx1xxx
xxxxxxxx & ~11110111 = xxxx0xxx

Mon graphe (11 Avril): ((Rogue Life || HH2) ; PythonExtra ; serial gint ; Boson X ; passe gint 3 ; ...) || (shoutbox v5 ; v5)
Darkjura Hors ligne Membre Points: 389 Défis: 0 Message

Citer : Posté le 29/11/2020 14:21 | #


Merci beaucoup Lephé

Mais pour remplacer un bit choisi de la chaîne "Àlo", il faut d'abord la lire 'en binaire'...
Et comment faire pour modifier ensuite le résultat de cette lecture ? Parce que 1<<i crée un entier; mais pour le modifier, quelle est la technique ?
Breizh_craft En ligne Modérateur Points: 1171 Défis: 7 Message

Citer : Posté le 29/11/2020 14:23 | #


Darkjura a écrit :
Merci beaucoup Lephé

Mais pour remplacer un bit choisi de la chaîne "Àlo", il faut d'abord la lire 'en binaire'...
Et comment faire pour modifier ensuite le résultat de cette lecture ? Parce que 1<<i crée un entier; mais pour le modifier, quelle est la technique ?


Justement, << peut modifier l’entier. Tu peux directement le faire sur ta chaîne qui est un entier comme un autre. Tu aurais dû trouver cela en cherchant comment s’utilisent << et >>.
Breizh.pm – Un adminsys qui aime les galettes.
Lephenixnoir En ligne Administrateur Points: 24572 Défis: 170 Message

Citer : Posté le 29/11/2020 14:29 | #


Mais pour remplacer un bit choisi de la chaîne "Àlo", il faut d'abord la lire 'en binaire'...

Tout est en binaire, Darkjura. Le texte de ce message est encodé en binaire (à l'aide d'un encodage qui s'appelle UTF-8). L'image qui s'affiche à tout écran est encodé en binaire (dans un format bitmap spécifique à ta carte graphique). Les données que tu échanges avec le serveur de Planète Casio sont encodées en binaire (dans un format compressé Gzip qui cache du texte encodé en UTF-8).

Tout est en binaire parce que le binaire est la seule chose qui existe.

La seule question que tu peux avoir c'est comment accéder aux données. Et pour ça tu peux utiliser les types et opérateurs du C. Par exemple si tu as :

char str[] = "Àlo";

Tu peux écrire str[0] pour accéder aux 8 premiers bits, str[1] pour accéder aux 8 suivants, etc etc. (Note que compte tenu du fonctionnement du processeur le résultat d'un calcul comme str[0] est toujours sur 32 bits. Les 8 bits en provenance de la chaîne de caractères sont les 8 premiers et tu peux ignorer les 24 autres.)
Mon graphe (11 Avril): ((Rogue Life || HH2) ; PythonExtra ; serial gint ; Boson X ; passe gint 3 ; ...) || (shoutbox v5 ; v5)
Darkjura Hors ligne Membre Points: 389 Défis: 0 Message

Citer : Posté le 29/11/2020 14:40 | #


Lephenixnoir a écrit :
le binaire est la seule chose qui existe.

J'ai bien compris, d'accord...

Lephenixnoir a écrit :
Tu peux écrire str[0] pour accéder aux 8 premiers bits

Evidemment ! J'aurais dû y penser, désolé

Breizh_craft a écrit :
Tu aurais dû trouver cela en cherchant comment s’utilisent << et >>.

Oui, pardon, je le fais maintenant

LienAjouter une imageAjouter une vidéoAjouter un lien vers un profilAjouter du codeCiterAjouter un spoiler(texte affichable/masquable par un clic)Ajouter une barre de progressionItaliqueGrasSoulignéAfficher du texte barréCentréJustifiéPlus petitPlus grandPlus de smileys !
Cliquez pour épingler Cliquez pour détacher Cliquez pour fermer
Alignement de l'image: Redimensionnement de l'image (en pixel):
Afficher la liste des membres
:bow: :cool: :good: :love: ^^
:omg: :fusil: :aie: :argh: :mdr:
:boulet2: :thx: :champ: :whistle: :bounce:
valider
 :)  ;)  :D  :p
 :lol:  8)  :(  :@
 0_0  :oops:  :grr:  :E
 :O  :sry:  :mmm:  :waza:
 :'(  :here:  ^^  >:)

Σ π θ ± α β γ δ Δ σ λ
Veuillez donner la réponse en chiffre
Vous devez activer le Javascript dans votre navigateur pour pouvoir valider ce formulaire.

Si vous n'avez pas volontairement désactivé cette fonctionnalité de votre navigateur, il s'agit probablement d'un bug : contactez l'équipe de Planète Casio.

Planète Casio v4.3 © créé par Neuronix et Muelsaco 2004 - 2024 | Il y a 197 connectés | Nous contacter | Qui sommes-nous ? | Licences et remerciements

Planète Casio est un site communautaire non affilié à Casio. Toute reproduction de Planète Casio, même partielle, est interdite.
Les programmes et autres publications présentes sur Planète Casio restent la propriété de leurs auteurs et peuvent être soumis à des licences ou copyrights.
CASIO est une marque déposée par CASIO Computer Co., Ltd