/*
Ordena um arquivo de NUMINT inteiros aleatórios em formato binário usando
operações convencionais de leitura/escrita em arquivos binários (fread, fwrite).

Antes de executar, criar um arquivo com NUMINT inteiros aleatórios em formato
binário (4 bytes por inteiro). Pode-se fazer isso por exemplo com:

	dd if=/dev/urandom of=randomint.dat bs=SIZE count=1

com SIZE sendo 4 * NUMINT.

Carlos Maziero, DINF/UFPR 2020
*/

#include <stdio.h>
#include <stdlib.h>

// número de valores int no arquivo de dados
#define NUMINT 10000000

int vet[NUMINT] ;
int num ;
FILE *datafile;

// compara dois inteiros (para a função qsort)
int compara (const void *p1, const void *p2)
{
  int *i1 = (int*) p1 ;
  int *i2 = (int*) p2 ;

  if (*i1 < *i2) return (-1) ;
  if (*i1 > *i2) return ( 1) ;
  return (0) ;
}

int main (int argc, char *argv[], char *envp[])
{
  // abrir o arquivo de dados
  if (argc < 2)
  {
     printf ("Error: should inform a file name\n") ;
     exit (1) ;
  }
  datafile = fopen (argv[1], "r+") ;
  if ( !datafile)
  {
    perror ("Error fopen") ;
    exit (1) ;
  }

  // ler os dados do arquivo e carregar no vetor
  num = 0 ;
  while ( !feof (datafile) && (num < NUMINT))
  {
    fread (&vet[num], 1, sizeof (int), datafile) ;
    num++ ;
  }
  if (num < NUMINT)
  {
    printf ("Data file contain only %d values\n", num) ;
    exit (1) ;
  }

  // ordenar o vetor de dados (quicksort)
  qsort (vet, NUMINT, sizeof (int), compara) ;

  // descarregar o conteúdo ordenado
  rewind (datafile) ;
  num = 0 ;
  while (num < NUMINT)
  {
    fwrite (&vet[num], 1, sizeof (int), datafile) ;
    num++ ;
  }
  fclose (datafile) ;

  exit (0) ;
}

