Comment lire le contenu d'un fichier dans une chaîne de caractères en C?
Quelle est la façon la plus simple (moins sujettes à l'erreur, moins de lignes de code, toutefois, vous souhaitez interpréter) pour ouvrir un fichier en C et de lire son contenu dans une chaîne de caractères (char*, char[], peu importe)?
- "plus simple" et "moins sujettes à l'erreur" sont souvent opposés les uns des autres.
- "plus simple" et "moins enclins à faire des erreurs" sont en fait un synonyme dans mon livre. Par exemple, la réponse en C# est
string s = File.ReadAllText(filename);
. Comment ça pourrait être plus simple et plus enclins à faire des erreurs?
Vous devez vous connecter pour publier un commentaire.
J'ai tendance à charger la totalité de la mémoire tampon brut pour mémoire morceau dans la mémoire et faire l'analyse de mon propre chef. De cette façon, j'ai un meilleur contrôle sur ce que la lib standard ne sur de multiples plateformes.
C'est un stub-je utiliser pour cela. vous pouvez également vérifier l'erreur-codes pour fseek, ftell et fread. (omis pour plus de clarté).
fread
n'est pas à zéro à la fin de votre chaîne. Cela peut conduire à des problèmes.buffer = malloc (length + 1);
et d'ajouter, après fclose :buffer[length] = '\0';
(validé par Valgrind)fseek (f, 0, SEEK_END);
est explicitement un comportement indéfini pour un flux binaire. 7.21.9.2 Lafseek
fonction, paragraphe 3: ... Un flux binaire ne doivent pas contribuer à fseek appels avec unwhence
valeur deSEEK_END
. Et par note de bas de page 268 de la norme C: Réglage de la position de l'indicateur de fin de fichier, comme avecfseek(file, 0, SEEK_END)
, a un comportement indéfini pour un flux binaire...Un autre, malheureusement très dépendants, la solution est de mappage de mémoire le fichier. Les avantages comprennent généralement les performances de la lecture, et la réduction de l'utilisation de la mémoire comme la vue applications et systèmes d'exploitation du cache de fichiers peuvent partager de la mémoire physique.
POSIX code devrait ressembler à ceci:
Windows sur l'autre main est un peu plus délicat, et malheureusement je n'ai pas de compilateur en face de moi pour tester, mais la fonctionnalité est fournie par
CreateFileMapping()
etMapViewOfFile()
.Si "lire son contenu dans une chaîne de caractères" signifie que le fichier ne contient pas de caractères avec le code 0, vous pouvez également utiliser getdelim fonction de (), qui accepte un bloc de mémoire et réalloue si nécessaire, ou tout simplement alloue de la mémoire tampon entier pour vous, et lit le fichier jusqu'à ce qu'il rencontre un délimiteur spécifié ou la fin du fichier. Il suffit de passer au '\0' comme délimiteur pour lire l'intégralité du fichier.
Cette fonction est disponible dans la Bibliothèque C de GNU, http://www.gnu.org/software/libc/manual/html_mono/libc.html#index-getdelim-994
L'exemple de code pourrait ressembler aussi simple que
Si le fichier est de type texte, et vous souhaitez obtenir le texte ligne par ligne, de la façon la plus simple est d'utiliser fgets().
Si vous êtes la lecture de fichiers spéciaux comme stdin ou un tuyau, vous n'allez pas être en mesure d'utiliser fstat pour obtenir la taille du fichier au préalable. Aussi, si vous êtes à la lecture d'un fichier binaire fgets va perdre la taille de la chaîne de l'information en raison de l'embedded caractères '\0'. Meilleur moyen de lire un fichier est alors d'utiliser la lecture et realloc:
Si vous utilisez
glib
, alors vous pouvez utiliser g_file_get_contents;Note: Ceci est une modification de la accepté la réponse ci-dessus.
Voici une façon de le faire, complet avec contrôle d'erreur.
J'ai ajouté une taille de checker pour arrêter de fumer quand le fichier est plus grand que 1 GiB. J'ai fait cette parce que le programme met l'intégralité du fichier en une chaîne de caractères qui peuvent utiliser trop de mémoire vive et de crash d'un ordinateur. Toutefois, si vous ne se soucient pas que vous pouvez simplement le supprimer à partir du code.
Et vérifier les erreurs:
C'est un joli brut solution parce que rien n'est vérifié par rapport à la valeur null.
glShaderSource
peut éventuellement prendre.Juste modifié à partir de la accepté la réponse ci-dessus.
Je vais ajouter ma propre version, sur la base des réponses ici, juste pour la référence. Mon code prend en considération sizeof(char) et y ajoute quelques commentaires.