2017-02-03 2 views
2

J'ai des problèmes avec une affectation où je dois prendre le contenu d'un fichier dans un tampon, inverser ces contenus, et les écrire dans un autre fichier. Ce programme a besoin d'utiliser deux fonctions qui ressemblent à ceci:C programme pour inverser le contenu d'un fichier et l'écrire dans un autre fichier

  • int read_file(char* filename, char **buffer);
  • int write_file(char* filename, char *buffer, int size);

jusqu'à présent mes fichiers ressembler à ceci:

file_utils.h

#ifndef UTILS_H 
#define UTILS_H 
     int read_file(char* filename, char **buffer); 
     int write_file(char* filename, char *buffer, int size); 
#endif 

file_utils.c

#include "file_utils.h" 
#include <stdlib.h> 
#include <stdio.h> 
#include <font1.h> 
#include <string.h> 
#include <sys/stat.h> 
#include <unistd.h> 

int read_file(char* filename, char **buffer) { 
     FILE* file1; 
     file1 = fopen(filename, "r"); 

     //gets the size of the file 
     struct stat st; 
     stat(filename, &st); 
     int size = st.st_size; 

     buffer = malloc(size); 
     read(file1, &buffer, 1); 
     return size; 
} 

int write_file(char* filename, char*buffer, int size) { 
     FILE* file2; 
     file2 = fopen(filename, 'w'); 

     for (int k = size - 1; k >= 0; k--) { 
      char* x = &buffer + k; 
      fprintf(file2, "%s", x); 
     } 
     printf(filename, '\O'); 
     return 1; 
} 

Reverse.c

#include "file_utils.h" 
#include <stdlib.h> 
#include <stdio.h> 
#include <font1.h> 
#include <string.h> 
#include <sys/stat.h> 
#include <unistd.h> 

int main(int argc, char *argv[]) { 
     char* buffer; 
     char* filename1; 
     char* filename2; 
     int filesize; 

     filename1 = argv[1]; 
     filename2 = argv[2]; 

     filesize = read_file(filename1, &buffer); 
     write_file(filename2, buffer, filesize); 

     return 0; 
} 

et c'est tout ce qu'il ya. Je lance à l'aide de "clang file_utils.c Reverse.c" et je reçois des avertissements pour file_utils.c comme

  • incompatible integer to pointer conversion passing 'int" to parameter of type 'const char *' (pour la ligne fichier1 = fopen (nom de fichier, 'r')
  • incompatible pointer to integer conversion passing 'FILE *' (aka 'struct_IO_FILE*') to parameter of type 'int' (pour la ligne de lecture (fichier_1, tampon &, 1);)
  • le même avertissement que le premier mais pour la ligne fichier2 = fopen (filename, 'w');
  • et incompatible pointer types initializing 'char *' with an expression of type 'char **'; dereferences with * (pour la ligne char * x = & buffer + k;)

au-dessus de tout cela quand je continue à lancer l'exécutable en tant que telle

./a.out file1 file2 

où fichier 1 a le texte qui devrait être inversée dans le fichier 2, je reçois une erreur de segmentation.

Tout aperçu des choses que je peux réparer sera très apprécié.

+0

Votre première erreur/avertissement est que vous avez passé '' r'' quand vous avez besoin de '' r ''. Et la même chose vaut pour cette troisième balle. – Charles

+0

Tout d'abord c'est '' r ''(pas''r''). La double citation est une * chaîne *, la citation unique est un * entier *. – pmg

+0

Est-ce un devoir, d'ailleurs? – Charles

Répondre

3

Situé juste à côté du haut de ma tête, sans essai, je vois ces bugs:

buffer = malloc(size); devrait être *buffer = malloc(size);

... parce que buffer est un pointeur vers pointeur vers char, vous devez déréférencer une fois.

read(file1, &buffer, 1); devrait être fread(*buffer, 1, size, file1);

... parce que vous ouvriez file1 avec fopen, il est donc FILE *. read est Unix E/S, pas d'E/S en flux et n'utilise pas FILE *.

file2 = fopen(filename, 'w'); devrait être file2 = fopen(filename, "w");

Le second argument doit être une "chaîne" (pointeur vers char ou une matrice de char). 'w' est un seul char.

char* x = &buffer + k; devrait être char *x = buffer + k;

buffer est un pointeur vers char, si vous voulez l'utiliser directement, sans prendre son adresse. Notez également le style de mettre * à côté de la variable au lieu du type. Ceci est une bonne habitude, parce que ces ne signifient pas la même chose:

char *a, *b, *c; /* three pointers */ 
char* a, b, c;  /* one pointer, two chars */ 

fprintf(file2, "%s", x); devrait être fprintf(file2, "%c", *x);

La première forme traite x comme le début d'une chaîne et la volonté sortie tout de ce point jusqu'à ce qu'il touche un terminateur NUL. Vous voulez sortir un seul char, utilisez le spécificateur %c, et dereference x pour obtenir un char.

Une meilleure façon serait fwrite(x, 1, 1, file2);

printf(filename, '\O'); n'est pas nécessaire et ne fait pas ce que vous pensez. Il semble que vous vouliez écrire un NUL à la fin. Ce serait '\0' (zéro), pas '\O' (lettre O). En tout cas, ce n'est pas nécessaire ou voulu. NUL est utilisé pour terminer une chaîne en C, pas un fichier. Votre fichier de sortie aura un caractère plus long que ce qu'il devrait être si vous le faites.

+0

Cela a tout arrangé, merci beaucoup! –

2

La question la plus importante avec votre code est ici

 char* x = &buffer + k; 
     fprintf(file2, "%s", x); 

peut-être vous dire

 char *x = buffer + k; 
     fprintf(file2, "%c", *x); 

Vous aussi, mixez fonctions IO. Pour un objet FILE *, vous devez utiliser fread() au lieu de read(), il devrait y avoir un arguments incompatibles avertissement du compilateur.

S'il n'y a pas d'avertissement (BTW char *x = &buffer + k devrait déclencher un autre avertissement), alors vous devriez probablement leur permettre explicitement que votre compilateur peut vous aider à d'autres problèmes.

En outre, vérifiez que file1 n'est pas NULL après fopen(), vérifiez que fread() avez bien lu le montant demandé, en contrôle général pour toutes les erreurs possibles que vous pouvez facilement déduire de la valeur de retour de la fonction implicite, si vous ne le faites pas connaître la signification d'une telle valeur puis LIRE LA DOCUMENTATION avant d'utiliser une telle fonction.

+0

J'ai fait le changement initial que vous avez suggéré et j'ai reçu l'avertissement "format spécifie type 'int' mais l'argument a tapez 'char *' –

+0

Notez le '*' avant le 'x'! –

0

Et enfin tous ensemble:

#include <stdlib.h> 
#include <stdio.h> 
#include <string.h> 
#include <sys/stat.h> 
#include <unistd.h> 

int read_file(char* filename, char **buffer) { 
    FILE* file1; 
    file1 = fopen(filename, "r"); 

    //gets the size of the file 
    struct stat st; 
    stat(filename, &st); 
    int size = st.st_size; 

    *buffer = malloc(size); 
    fread(*buffer, size, 1, file1); 
    fclose(file1); 

    return size; 
} 

void write_file(char* filename, char*buffer, int size) { 
    FILE* file2 = fopen(filename, "w"); int k; 

    for (k = size - 1; k >= 0; k--) { 
    fwrite(buffer + k, 1, 1, file2); 
    } 

    fclose(file2); 
} 

int main(int argc, char *argv[]) { 
    char* buffer; 
    char* filename1; 
    char* filename2; 
    int filesize; 

    filename1 = "input.txt"; 
    filename2 = "reverse.txt"; 

    filesize = read_file(filename1, &buffer); 
    write_file(filename2, buffer, filesize); 

    free(buffer); 

    return 0; 
} 

avec un demo en direct. S'il vous plaît ajouter des vérifications pour toutes les valeurs de retour, comme malloc() ne renvoie pas NULL.