Suppongo che i numeri siano già ordinati...nella consegna non dice nulla a riguardo.Comunque pensavo di risolvere usando un array di char dinamico che rialloco a ogni carattere che incontro,salvo il carattere nell'array e infine cerco '\n' e tutto ciò che è compreso tra '\n' e il precedente return o indice 0,è un numero.Poi con atoi converto in int e riordino in modo decrescente per poi scrivere su file.
EDIT: Ho provato a implementare l'esercizio richiesto,ma ho questo errore:
Codice: Seleziona tutto
./main num
*** Error in `./main': realloc(): invalid next size: 0x0000000000700240 ***
======= Backtrace: =========
/usr/lib/libc.so.6(+0x72055)[0x7f35a9f81055]
/usr/lib/libc.so.6(+0x779a6)[0x7f35a9f869a6]
/usr/lib/libc.so.6(+0x7aa19)[0x7f35a9f89a19]
/usr/lib/libc.so.6(realloc+0x139)[0x7f35a9f8ac69]
./main[0x4007e8]
/usr/lib/libc.so.6(__libc_start_main+0xf0)[0x7f35a9f2f610]
./main[0x400699]
======= Memory map: ========
00400000-00401000 r-xp 00000000 08:02 2360166 /home/neon/Documenti/Programmazione/Esercizi/file_num_decr/main
00600000-00601000 rw-p 00000000 08:02 2360166 /home/neon/Documenti/Programmazione/Esercizi/file_num_decr/main
00700000-00721000 rw-p 00000000 00:00 0 [heap]
7f35a4000000-7f35a4021000 rw-p 00000000 00:00 0
7f35a4021000-7f35a8000000 ---p 00000000 00:00 0
7f35a9cf9000-7f35a9d0f000 r-xp 00000000 08:02 8785108 /usr/lib/libgcc_s.so.1
7f35a9d0f000-7f35a9f0e000 ---p 00016000 08:02 8785108 /usr/lib/libgcc_s.so.1
7f35a9f0e000-7f35a9f0f000 rw-p 00015000 08:02 8785108 /usr/lib/libgcc_s.so.1
7f35a9f0f000-7f35aa0aa000 r-xp 00000000 08:02 8786582 /usr/lib/libc-2.22.so
7f35aa0aa000-7f35aa2a9000 ---p 0019b000 08:02 8786582 /usr/lib/libc-2.22.so
7f35aa2a9000-7f35aa2ad000 r--p 0019a000 08:02 8786582 /usr/lib/libc-2.22.so
7f35aa2ad000-7f35aa2af000 rw-p 0019e000 08:02 8786582 /usr/lib/libc-2.22.so
7f35aa2af000-7f35aa2b3000 rw-p 00000000 00:00 0
7f35aa2b3000-7f35aa2d5000 r-xp 00000000 08:02 8786581 /usr/lib/ld-2.22.so
7f35aa48d000-7f35aa490000 rw-p 00000000 00:00 0
7f35aa4d2000-7f35aa4d4000 rw-p 00000000 00:00 0
7f35aa4d4000-7f35aa4d5000 r--p 00021000 08:02 8786581 /usr/lib/ld-2.22.so
7f35aa4d5000-7f35aa4d6000 rw-p 00022000 08:02 8786581 /usr/lib/ld-2.22.so
7f35aa4d6000-7f35aa4d7000 rw-p 00000000 00:00 0
7fff373fa000-7fff3741b000 rw-p 00000000 00:00 0 [stack]
7fff37563000-7fff37565000 r--p 00000000 00:00 0 [vvar]
7fff37565000-7fff37567000 r-xp 00000000 00:00 0 [vdso]
ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0 [vsyscall]
Annullato (core dump creato)
Il codice scritto è:
Codice: Seleziona tutto
#include<stdio.h>
#include<stdlib.h>
#define EXCEPTED_ARGS 2
#define CMD_USAGE_ERROR 64
int main(int argc,char **argv)
{
if(argc < EXCEPTED_ARGS)
{
fprintf(stderr,"Error: too few arguments passed.\n");
exit(CMD_USAGE_ERROR);
}
FILE *fp = fopen(argv[1],"r"); //apro il file in lettura
int *v = NULL;// array di interi
int i = 0;//contatore
while(!feof(fp))//finchè il file non termina
{
v = (int *)realloc(v,i+1);//aggiungo lo spazio per un intero
if(v == NULL)// se realloc fallisce
{
//errore! esco dal ciclo
fprintf(stderr,"Error: unable to reallocate space in memory.\n");
break;
}
fscanf(fp,"%d",&v[i]);//leggo i numeri
i++;//aggiono i
}
fclose(fp);//chiudo il file
free(v);//libero lo spazio in memoria
return 0;
}
RIEDIT: ho deciso di contare prima le righe del file e poi creare l'array con dimensione pari al numero di righe senza impazzire con array dinamici.
Codice: Seleziona tutto
#include<stdio.h>
#include<stdlib.h>
#include "futils.h"
#define EXCEPTED_ARGS 2
#define CMD_USAGE_ERROR 64
int main(int argc,char **argv)
{
if(argc < EXCEPTED_ARGS)
{
fprintf(stderr,"Error: too few arguments passed.\n");
exit(CMD_USAGE_ERROR);
}
int a_size = countlines(argv[1]);
int *v = (int *) malloc(a_size * sizeof(int));
FILE *fp = fopen(argv[1],"r");
int i = 0;
while(!feof(fp))
{
fscanf(fp,"%d",&v[i]);
fprintf(stdout,"Numero: %d\n",v[i]);
}
int size = (int)sizeof(v);
fprintf(stdout,"Dimensione array: %d\n",size);
free(v);
fclose(fp);
return 0;
}
Il problemi sono:
-che mi dice che array ha dimesione pari a 8,che non è vero perchè avrei avuto problemi di overflow.
-visualizza due volte il numero nove,l'ultimo presente nel file.
Qui l'output di gdb:
Codice: Seleziona tutto
(gdb) break 24
Breakpoint 1 at 0x40091c: file main.c, line 24.
(gdb) r num
Starting program: /home/neon/Documenti/Programmazione/Esercizi/file_num_decr/main num
Numero: 1
Numero: 2
Numero: 3
Numero: 4
Numero: 5
Numero: 6
Numero: 7
Numero: 8
Numero: 9
Numero: 9
Breakpoint 1, main (argc=2, argv=0x7fffffffdf68) at main.c:24
24 int size = (int)sizeof(v);
(gdb) print size
$1 = 4196816 # Perchè diavolo vale 4196816? Forse perchè prima di countlines non è inizializzata?
(gdb) p size
$2 = 4196816 # Qui era una prova con p
(gdb) n
25 fprintf(stdout,"Dimensione array: %d\n",size);
(gdb) p size
$3 = 8 # Ora diventa 8,perchè?
(gdb) n
Dimensione array: 8
26 free(v);
(gdb) n
27 fclose(fp);
(gdb) n
28 return 0;
(gdb) n
29 }
(gdb) n
0x00007ffff7a57610 in __libc_start_main () from /usr/lib/libc.so.6
(gdb) n
Single stepping until exit from function __libc_start_main,
which has no line number information.
[Inferior 1 (process 15320) exited normally]
Codice di futils.c : (che dovrebbe essere file-util ma sembra essere futil(e)
)
Codice: Seleziona tutto
#include "futils.h"
#include<stdio.h>
#include<stdlib.h>
int countlines(const char *filename)
{
int lines = 0;
FILE *fp = fopen(filename,"r");
if(fp == NULL)
{
return -1;
}
while(!feof(fp))
{
if(fgetc(fp) == '\n')
{
lines++;
}
}
fclose(fp);
return lines;
}
Software engineers shall participate in lifelong learning regarding the practice of their profession and shall promote an ethical approach to the practice of the profession.
ACM/IEEE Code of ethics.