From c133c4185b7a5962095dcda2122bbf011e39d94b Mon Sep 17 00:00:00 2001 From: j-twite <jonathan.twite@student.uclouvain.be> Date: Tue, 14 Apr 2020 00:17:31 +0200 Subject: [PATCH] fileFeature --- fileFeatures.h | 104 ++++++++++++++++++++----------------------------- prime_divs.c | 60 ++++++++++++++++++++++++++++ 2 files changed, 103 insertions(+), 61 deletions(-) create mode 100644 prime_divs.c diff --git a/fileFeatures.h b/fileFeatures.h index 39acef6..bd9b457 100644 --- a/fileFeatures.h +++ b/fileFeatures.h @@ -10,78 +10,60 @@ #include <stdlib.h> #include <fcntl.h> #include <unistd.h> +#include <math.h> -/** - * A SAVOIR pour la conversion de char en int: - * Si 'x' ∈ ['0', '1', '2', ..., '9'] alors - * alors (int) x = x - '0' - */ -// Mes fonctions: -long readLine(int file, char *buff); -long parseLong(char *buff, int index); -long ipow(int base, int exp); -// bizarrement, quand j'appelle la fonction pow de la librairie math.h, -// on me retourne des erreurs donc j'ai refait une implementation +//functions: +int factorize(char *file_in_memory, FILE *fileOutput); +int factAndWrite(FILE *out, int n); +int ipow(int base, int exp); -/** - * @param #file le fichier a read qu'on a prealablement charge (on ne charge pas le fichier ici) - * @param #buff un char[x>=20] qui collecte les digits lus byte par byte - * @return la ligne lue dans file sous forme numérique - */ -long readline(int file, char buff[]) { - if(file == 0) { - puts("End of file."); - return 0; - } - - if (file <= 0) { - printf("Trying to read into %d directory.", file); - close(file); - return -1; - } else if (buff == NULL) { // char doit être - puts("Trying to store values into NULL buffer."); - return -2; - } - int byteReader = read(file, &(*buff), 1); // In order to call the read() iteratively, we have to call it once before - if (buff[0] > '9') { - puts("Illegal argument."); - return -3; - } else if(buff[0] < '0') { - puts("End of file"); - return 0; - } - int i = 1; - while (byteReader = read(file, &buff[i], 1) > 0) { // while datas are still remaining - if (buff[i] == '\n') { // if this is the end of line - return parseLong(buff, i); // return the long value - } else if (buff[i] > '9' || buff[i] < '0') { // if the readed value isn't a digit - printf("Illegal argument (%d)..", i); // stop the program - return -3; - } else // otherwise keep iterating +// iterate through a mapped file and write each number found and factorize them +// the program stop if file_in_memory contains anything else than a digit or a '\n' +int factorize(char *file_in_memory, FILE *fileOutput) { + int start = 0; + int size = strlen(file_in_memory); + int i = 0; + while (i < size) { + if (file_in_memory[i] == '\n' && i > start) { // if we are at the end of the line + int k = 0; + for (int j = i - 1; j >= start; j--) // iterate from right to left + k += ((file_in_memory[j] - '0') *ipow(10, i - j - 1)); // record each digit into k + factAndWrite(fileOutput, k); // write and factorize k into fileOutput + start = i += 1; + } + else if ((file_in_memory[i] > '9' || file_in_memory[i] < '0') && file_in_memory[i] != '\n') { + perror("Not a digit."); + return -2; + } + else i++; } - return byteReader; + return 0; } -/** - * @param #buff la ligne lue dans le fichier - * @param index qui signifie les n premiers digits à lire - * @return la ligne lue dans file sous forme numérique - */ -long parseLong(char *buff, int index) { - if (buff == NULL) - return -1; - long k = 0; - for (int i = index - 1 ; i >= 0; i--) { - k += (buff[i] - '0') * ipow(10, index - (i + 1)) ; +// * write n and its factorization in the file @out * +int factAndWrite(FILE *out, int n) { + int x = n; + fprintf(out, "%d", n); + while (n % 2 == 0) { + fprintf(out, " 2"); + n /= 2; } - return k; + for (int i = 3; x >= i*i; i+=2) + while (n % i == 0) { + fprintf(out, " %d", i); + n /= i; + } + if(n > 1 && n < x) + fprintf(out, " %d", n); + fprintf(out, " \n"); + return 0; } -long ipow(int base, int exp) { - long result = 1; +int ipow(int base, int exp) { + int result = 1; for (;;) { if (exp & 1) result *= base; diff --git a/prime_divs.c b/prime_divs.c new file mode 100644 index 0000000..a18db11 --- /dev/null +++ b/prime_divs.c @@ -0,0 +1,60 @@ +// +// Created by jtwite on 28.03.20. +// +#include <sys/mman.h> +#include <stdio.h> +#include <stdlib.h> +#include <fcntl.h> +#include <unistd.h> +#include <sys/stat.h> +#include <sys/time.h> +#include <string.h> +#include "fileFeatures.h" + + +// int max value: 2 147 483 647 +// long max value: 9223372 036 854 775 807 + + +// char *filepath = "/home/jtwite/Desktop/test"; + +// Remplacez-le contenu par le chemin relatif du fichier que vous souhaitez tester. + + + +int main(int argc, char *argv[]) +{ + struct timeval stop, start; + gettimeofday(&start, NULL); + + printf("argv[1]: %s\n", argv[1]); + printf("argv[2]: %s\n", argv[2]); + + //open the file + int fileInput = open(argv[1], O_RDONLY); + if (fileInput <= 0) + exit(1); + + // get the fileInput size + struct stat sb; + fstat(fileInput, &sb); + char *file_in_memory = mmap(NULL, sb.st_size, PROT_READ, MAP_PRIVATE, fileInput, 0); + close(fileInput); + // Create a new file struct in which the output is writen + FILE *fileOutput = fopen(argv[2], "w"); + if(fileOutput == NULL) + exit(-2); + //go through the mapped file to get numbers and write them in fileOutput + + factorize(file_in_memory, fileOutput); + + //close everything + munmap(file_in_memory, sb.st_size); + + fclose(fileOutput); + + gettimeofday(&stop, NULL); + printf("took %lu µs\n", (stop.tv_sec - start.tv_sec) * 1000000 + stop.tv_usec - start.tv_usec); + + return 0; +} -- GitLab