Je suis actuellement sur un projet où je dois créer un fichier CSV, je m'explique ;
Je trace une fonction V(t), à l'aide de gnuplot, en stockant tous mes points dans un fichier txt. J'ai donc deux colonnes dans ce fichier, la première qui représente toutes les valeurs de t et la deuxième les valeurs de V correspondante.
Mais, je dois transformer ce fichier txt en fichier csv pour pouvoir l'utiliser sur un GBF par la suite. Ma question et donc la suivante :
Comment puis-je transformer mon séparateur de colonne, dans mon fichier txt, qui est un espace, par une virgule comme pour les fichiers csv ?
Voici mon fichier txt :
J'espère être assez clair, je vous remercie d'avance !
Et comme dit magma, cela peut se faire un avec petit fscanf bien placé et un fprintf suivant (soit une dizaine de lignes maximum). Le mieux est d'utiliser stdin/stdout comme les bon programmes UNIX comme ça tu n'as même pas à gérer l'ouverture et la fermeture des fichiers entrée et sortie
git is great because Linus did it, mercurial is better because he didn't.
Avec la famille de fonctions getc / putc, on lit les caractères un par un et on fait une boucle qui contient ce genre de chose (ça fait un bail que je n'ai pas utilisé getc/putc donc j'écris ça un peu au pif, c'est pour donner l'idée) :
char c = getc();
if (c == ' ')
putc(',');
else
putc(c);
Là on lit/écrit sur l'entrée/sortie standard, ça me permet de taper ce genre de commande :
> convertir < fichier.txt > fichier.csv
où 'convertir' est le programme qu'on vient d'écrire. Sinon on peut aussi manipuler des fichiers et utiliser fgetc/fputc, mais je préfère suivre le conseil de markand.
Tu lis ligne par ligne ton fichier.txt que tu re-écris ligne par ligne dans un nouveau fichier au format souhaité ...
Bonne continuation.
Oui c'est ce que je me suis dit, mais je n'arrive pas à trouver comment faire (je suis assez débutant en C), peut-être comme robun m'a dit de faire ici ;
robun a écrit:
Avec la famille de fonctions getc / putc, on lit les caractères un par un et on fait une boucle qui contient ce genre de chose (ça fait un bail que je n'ai pas utilisé getc/putc donc j'écris ça un peu au pif, c'est pour donner l'idée) :
char c = getc();
if (c == ' ')
putc(',');
else
putc(c);
Là on lit/écrit sur l'entrée/sortie standard, ça me permet de taper ce genre de commande :
> convertir < fichier.txt > fichier.csv
où 'convertir' est le programme qu'on vient d'écrire. Sinon on peut aussi manipuler des fichiers et utiliser fgetc/fputc, mais je préfère suivre le conseil de markand.
Vu la tête du fichier, on s'en tirerait avec une simple commande unix
tr " " "," < ancien.txt > nouveau.csv
- Edité par michelbillaud il y a 29 minutes
En effet, cela a marché, plutôt efficace !! Merci !
Mais j'aurais quand même bien aimé savoir comme le faire en C dans mon code, si quelqu'un aurait une réponse ? Enfin si quelqu'un serait implémenter une partie de code pour lire caractère par caractère un fichier.txt.
#include <stdio.h>
int main() {
FILE *fileIn, *fileOut;
char buffer[100] = {0};
fileIn = fopen("input.txt", "r");
fileOut = fopen("output.txt", "w");
while (fgets(buffer, 100, fileIn) != NULL) {
if (buffer[0] == '\0' || buffer[0] == '\n') {
continue;
}
for (int i = 0; i < 100; i++) {
if (buffer[i] == ' ') {
buffer[i] = ',';
}
}
fputs(buffer, fileOut);
}
fclose(fileIn);
fclose(fileOut);
return 0;
}
Je prends en compte le cas des lignes vides en les ignorant.
Par contre je ne prends pas le cas où les fichiers n'existent pas...
- Edité par fred1599 6 février 2023 à 18:30:53
Celui qui trouve sans chercher est celui qui a longtemps cherché sans trouver.(Bachelard) La connaissance s'acquiert par l'expérience, tout le reste n'est que de l'information.(Einstein)
Faut pas s'emmerder à traiter caractère par caractère.
Si on suppose que le fichier d'entrée est bien formatté, c'est pas compliqué. (et si on veut supposer qu'il ne l'est pas il faut nous dire quoi faire dans ce cas)
Bref Un filtre qui lit des nombres deux par deux (sur l'entrée standard) et les ressort (sur la sortie standard) séparés par des virgules) :
D'abord se documenter, puis poser les questions nécessaires à la compréhension. Mais avant faut chercher, faire des petits tests afin de vérifier qu'on comprend certaines choses. Apprendre le C ne se fait pas en peu de temps !
Celui qui trouve sans chercher est celui qui a longtemps cherché sans trouver.(Bachelard) La connaissance s'acquiert par l'expérience, tout le reste n'est que de l'information.(Einstein)
Celui qui trouve sans chercher est celui qui a longtemps cherché sans trouver.(Bachelard) La connaissance s'acquiert par l'expérience, tout le reste n'est que de l'information.(Einstein)
Il y a une autre approche, un programme qui MODIFIE un fichier. Ouverture bas niveau par open en lecture écriture, read/write par blocs, lseek pour se déplacer.
Laissé en exercice, je suis en grève aujourd'hui :-)
--- j'ai pas pu résister
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#define BEFORE ' '
#define AFTER ','
#define BUFFER_SIZE 128
int main(int argc, char* argv[])
{
if (argc != 2) {
printf("usage: %s path\n", argv[0]);
return EXIT_FAILURE;
}
int fd = open(argv[1], O_RDWR);
if (fd < 0) {
perror("Ouverture fichier");
return EXIT_FAILURE;
}
// let's go
for (;;) {
char buffer[BUFFER_SIZE];
ssize_t nb_bytes_read = read(fd, buffer, BUFFER_SIZE);
if (nb_bytes_read <= 0) break;
for (ssize_t i = 0; i < nb_bytes_read; i++) {
if (buffer[i] == BEFORE) {
buffer[i] = AFTER;
}
}
// driving me backwards
// https://www.youtube.com/watch?v=V81btEv0i8U
lseek(fd, - nb_bytes_read, SEEK_CUR);
write(fd, buffer, nb_bytes_read);
}
close(fd);
return EXIT_SUCCESS;
}
Test sur un copie du fichier source
$ make test
cp prog.c exemple
./prog exemple
$ head exemple
#include,<stdio.h>
#include,<stdlib.h>
#include,<unistd.h>
#include,<sys/types.h>
#include,<sys/stat.h>
#include,<fcntl.h>
#define,BEFORE,','
$ tail exemple
,,,,,,,,}
,,,,,,,,//,driving,me,backwards
,,,,,,,,//,https://www.youtube.com/watch?v=V81btEv0i8U
,,,,,,,,lseek(fd,,-,nb_bytes_read,,SEEK_CUR);
,,,,,,,,write(fd,,buffer,,nb_bytes_read);
,,,,}
,,,,close(fd);
,,,,return,EXIT_SUCCESS;
}
J'ai pris des petits blocs de 128 octets pour vérifier que ça se passe bien avec plusieurs blocs. En pratique, il faut en prendre des grands (4 ou 8 K par exemple).
Edit : paramètrer la substitution par des options, aussi.
Et bien sur découper le source en fonctions, gérer les erreurs etc.
C'est normalement un chouia plus efficace que getc etc cie qui ajoutent une gestion de buffer supplémentaire pour la ligne.
- Edité par michelbillaud 7 février 2023 à 15:14:55
Modifier un fichier txt en C
× Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
× Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
git is great because Linus did it, mercurial is better because he didn't.
Celui qui trouve sans chercher est celui qui a longtemps cherché sans trouver.(Bachelard)
La connaissance s'acquiert par l'expérience, tout le reste n'est que de l'information.(Einstein)
Celui qui trouve sans chercher est celui qui a longtemps cherché sans trouver.(Bachelard)
La connaissance s'acquiert par l'expérience, tout le reste n'est que de l'information.(Einstein)
Le Tout est souvent plus grand que la somme de ses parties.
Celui qui trouve sans chercher est celui qui a longtemps cherché sans trouver.(Bachelard)
La connaissance s'acquiert par l'expérience, tout le reste n'est que de l'information.(Einstein)