[Utilità del Cavolo] Programma Gestione Figurine [RISOLTO]

Forum dedicato alla programmazione.

Moderatore: Staff

Regole del forum
1) Citare in modo preciso il linguaggio di programmazione usato.
2) Se possibile portare un esempio del risultato atteso.
3) Leggere attentamente le risposte ricevute.
4) Scrivere i messaggi con il colore di default, evitare altri colori.
5) Scrivere in Italiano o in Inglese, se possibile grammaticalmente corretto, evitate stili di scrittura poco chiari, quindi nessuna abbreviazione tipo telegramma o scrittura stile SMS o CHAT.
6) Appena registrati è consigliato presentarsi nel forum dedicato.

La non osservanza delle regole porta a provvedimenti di vari tipo da parte dello staff, in particolare la non osservanza della regola 5 porta alla cancellazione del post e alla segnalazione dell'utente. In caso di recidività l'utente rischia il ban temporaneo.
Avatar utente
Blallo
Packager
Packager
Messaggi: 3302
Iscritto il: ven 12 ott 2007, 11:37
Nome Cognome: Savino Liguori
Slackware: 14.2 / 12.2
Kernel: 4.4.14-smp
Desktop: DWM
Località: Torino / Torremaggiore (FG)
Contatta:

[Utilità del Cavolo] Programma Gestione Figurine [RISOLTO]

Messaggio da Blallo »

Stamane ho buttato giù di stomaco un programmino per gestire da console una collezione di figurine..
Sicuramente suscettibile di notevoli migliorire (soprattutto come "formattazione" generale del codice)..ma funzia

Codice: Seleziona tutto

#include <stdio.h>
#include <stdlib.h>
#define N 734

int main()
{
	FILE *fp;
	int *vect;
	int opt, i=0, chs=0, chs_2=0;

	if((vect=calloc(N, sizeof(int)))==NULL)
	{
		printf("Errore Allocazione Memoria!");
		return EXIT_FAILURE;
	}

	if((fp=fopen("figu.txt","r"))==NULL)
	{
		printf("Il file non esiste! Che vuoi fare?\n");
		printf("1:Crea Nuovo File\n");
		printf("2:Esci\n");
		scanf("%d", &opt);
		if(opt==1)
		{
			if((fp=fopen("figu.txt","w"))==NULL)
			{
				printf("Errore Apertura File!");
				return EXIT_FAILURE;
			}
			fclose(fp);
		}
		else if(opt==2)
		{
			printf("Uscita");
			return EXIT_SUCCESS;
		}
	}

	while((fscanf(fp, "%d", &vect[i]))==1 && !feof(fp))
		i++;
    //fclose(fp);

	while(chs==0)
	{
		printf("1:Aggiungi Figurine\n");
		printf("2:Rimuovi Figurine\n");
		printf("3:Quante Sono Le Mancanti\n");
		printf("4:Controlla Figurina\n");
		printf("5:Genera Mancanti\n");
		printf("6:Esci\n");
		scanf("%d", &opt);
		if(opt==1)
		{
		    printf("Terminare con 0\n");
			while(scanf("%d", &chs_2)==1)
			{
				if(chs_2==0 || chs_2 > N)
					break;
				else
				{
				    if(vect[chs_2-1]==1)
                        printf("Già presente\n");
                    else
                        vect[chs_2-1]=1;
				}
			}
		}
		else if(opt==2)
		{
		    printf("Terminare con 0\n");
			while(scanf("%d", &chs_2)==1)
			{
				if(chs_2==0 || chs_2 > N)
					break;
				else
				{
				    if(vect[chs_2-1]==0)
                        printf("Già Assente\n");
                    else
                        vect[chs_2-1]=0;
				}
			}
		}
		else if(opt==3)
		{
			chs_2=0;

			for(i=0;i<N;i++)
				if(vect[i]==0)
					chs_2++;

			printf("%d\n", chs_2);
		}
		else if(opt==4)
		{
		    while((scanf("%d", &chs_2))==1)
		    {
                if(chs_2==0 || chs_2 > N)
                    break;
                else
                {
                    if(vect[chs_2-1]==1)
                        printf("Presente\n");
                    else
                        printf("Assente\n");
                }
		    }
		}
		else if(opt==5)
		{
		    if((fp=fopen("mancanti.txt","w"))==NULL)
		    {
		        printf("Errore Apertura File!");
		        return EXIT_FAILURE;
		    }

		    for(i=0;i<N;i++)
		        if(vect[i]==0)
                    fprintf(fp, "%d ", i+1);

            fclose(fp);
		}
		else if(opt==6)
		{
			if((fp=fopen("figu.txt","w"))==NULL)
			{
				printf("Errore Apertura File");
				return EXIT_FAILURE;
			}
			for(i=0;i<N;i++)
				fprintf(fp, "%d ", vect[i]);

			chs=1;

			fclose(fp);
        }
	}
	free(vect);
	return EXIT_SUCCESS;
}
Per chi servisse 8)
EDIT: corrette alcune cosine, il programma funzionava ma ho aggiunto qualche comodità in più
Ultima modifica di Blallo il mer 19 mag 2010, 16:25, modificato 3 volte in totale.

Avatar utente
j0kers
Linux 2.x
Linux 2.x
Messaggi: 418
Iscritto il: dom 22 lug 2007, 1:31
Slackware: 13
Kernel: 2.6.32
Desktop: xfce4

Re: [Utilità del Cavolo] Programma Gestione Figurine

Messaggio da j0kers »

C'è un bug nel programma :D
In pratica se aggiungo nuove figurine mi va in loop il menu

Codice: Seleziona tutto

1:Aggiungi Figurine
2:Rimuovi Figurine
3:Quante Sono Le Mancanti
4:Controlla Figurina
5:Genera Mancanti
6:Esci
Devo terminarlo con CTRL+C

Avatar utente
Blallo
Packager
Packager
Messaggi: 3302
Iscritto il: ven 12 ott 2007, 11:37
Nome Cognome: Savino Liguori
Slackware: 14.2 / 12.2
Kernel: 4.4.14-smp
Desktop: DWM
Località: Torino / Torremaggiore (FG)
Contatta:

Re: [Utilità del Cavolo] Programma Gestione Figurine

Messaggio da Blallo »

a me non lo da..sei sicuro?
non credo sia possibile dato che ad ogni comparsa del menu la scanf dovrebbe "bloccare" il loop in attesa che gli dai qualcosa

Avatar utente
JohnnyMnemonic
Staff
Staff
Messaggi: 2733
Iscritto il: dom 5 set 2004, 0:00
Nome Cognome: Giuseppe Palmiotto
Slackware: 14.0
Kernel: 3.5.5-thanatos
Località: Bologna
Contatta:

Re: [Utilità del Cavolo] Programma Gestione Figurine

Messaggio da JohnnyMnemonic »

Stesso problema di jokers

Mario Vanoni
Iper Master
Iper Master
Messaggi: 3174
Iscritto il: lun 3 set 2007, 21:20
Nome Cognome: Mario Vanoni
Slackware: 12.2
Kernel: 3.0.4 statico
Desktop: fluxbox/seamonkey
Località: Cuasso al Monte (VA)

Re: [Utilità del Cavolo] Programma Gestione Figurine

Messaggio da Mario Vanoni »

Stesso errore, loop infinito, provocabile visto che

Codice: Seleziona tutto

  printf("Terminare con 0\n");
         while(scanf("%d", &chs_2)==1)
         {
secondo la man page di scanf non dara` mai un return di 1,
se si digita qualunque altro segno non numerico.

Domandina "en passant":
perche' non usare switch/case al posto di 6 if/else if?

Avatar utente
Blallo
Packager
Packager
Messaggi: 3302
Iscritto il: ven 12 ott 2007, 11:37
Nome Cognome: Savino Liguori
Slackware: 14.2 / 12.2
Kernel: 4.4.14-smp
Desktop: DWM
Località: Torino / Torremaggiore (FG)
Contatta:

Re: [Utilità del Cavolo] Programma Gestione Figurine

Messaggio da Blallo »

Mario Vanoni ha scritto:secondo la man page di scanf non dara` mai un return di 1,
se si digita qualunque altro segno non numerico.
infatti deve ricevere solo un numero, se non ne riceve non deve più continuare il while
inoltre

Codice: Seleziona tutto

if(chs_2==0 || chs_2 > N)
					break;
quindi quando è zero esce dal loop con break
Mario Vanoni ha scritto:Domandina "en passant":
perche' non usare switch/case al posto di 6 if/else if?
perchè l'ho buttato così giù in due secondi, quando avrò più tempo lo rifarò per bene con più controlli, switch/case e magari ogni caso con una sua funzione, così da migliorare la leggibilità del codice

comunque l'ho ricompilato ricopiando il codice qui postato, e a me va, e mi pare abbastanza strano che vi vada in loop, dato che a

Codice: Seleziona tutto

scanf("%d", &opt);
dovrebbe "fermarsi" per ricevere un dato in input

Mario Vanoni
Iper Master
Iper Master
Messaggi: 3174
Iscritto il: lun 3 set 2007, 21:20
Nome Cognome: Mario Vanoni
Slackware: 12.2
Kernel: 3.0.4 statico
Desktop: fluxbox/seamonkey
Località: Cuasso al Monte (VA)

Re: [Utilità del Cavolo] Programma Gestione Figurine

Messaggio da Mario Vanoni »

jimmy_page_89 ha scritto:
Mario Vanoni ha scritto:secondo la man page di scanf non dara` mai un return di 1,
se si digita qualunque altro segno non numerico.
infatti deve ricevere solo un numero, se non ne riceve non deve più continuare il while
inoltre

Codice: Seleziona tutto

if(chs_2==0 || chs_2 > N)
					break;
quindi quando è zero esce dal loop con break
Mario Vanoni ha scritto:Domandina "en passant":
perche' non usare switch/case al posto di 6 if/else if?
perchè l'ho buttato così giù in due secondi, quando avrò più tempo lo rifarò per bene con più controlli, switch/case e magari ogni caso con una sua funzione, così da migliorare la leggibilità del codice

comunque l'ho ricompilato ricopiando il codice qui postato, e a me va, e mi pare abbastanza strano che vi vada in loop, dato che a

Codice: Seleziona tutto

scanf("%d", &opt);
dovrebbe "fermarsi" per ricevere un dato in input
Con l'ultimo codice ricompilato gcc -O2 -s -o cavolo cavolo.c
strace -o cavolo.err cavolo
mettendo una "r" al posto di una cifra va in loop

Codice: Seleziona tutto

root@va2:~# less cavolo.err
execve("./cavolo", ["cavolo"], [/* 37 vars */]) = 0
brk(0)                                  = 0x85ad000
access("/etc/ld.so.preload", R_OK)      = -1 ENOENT (No such file or directory)
open("/etc/ld.so.cache", O_RDONLY)      = 3
fstat64(3, {st_mode=S_IFREG|0644, st_size=128948, ...}) = 0
mmap2(NULL, 128948, PROT_READ, MAP_PRIVATE, 3, 0) = 0xb76d6000
close(3)                                = 0
open("/lib/libc.so.6", O_RDONLY)        = 3
read(3, "\177ELF\1\1\1\0\0\0\0\0\0\0\0\0\3\0\3\0\1\0\0\0\360d\1"..., 512) = 512
fstat64(3, {st_mode=S_IFREG|0755, st_size=1570593, ...}) = 0
mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb76d5000
mmap2(NULL, 1357360, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0xb7589000
mprotect(0xb76ce000, 4096, PROT_NONE)   = 0
mmap2(0xb76cf000, 12288, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x145) = 0xb76cf000
mmap2(0xb76d2000, 9776, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0xb76d2000
close(3)                                = 0
mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7588000
set_thread_area({entry_number:-1 -> 6, base_addr:0xb75886c0, limit:1048575, seg_32bit:1, contents:0, read_exec_only:0, limit_in_pages:1, seg_not_present:0, useable:1}) = 0
mprotect(0xb76cf000, 8192, PROT_READ)   = 0
mprotect(0xb7713000, 4096, PROT_READ)   = 0
munmap(0xb76d6000, 128948)              = 0
brk(0)                                  = 0x85ad000
brk(0x85ce000)                          = 0x85ce000
open("figu.txt", O_RDONLY)              = 3
fstat64(3, {st_mode=S_IFREG|0644, st_size=0, ...}) = 0
mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb76f5000
read(3, "", 4096)                       = 0
fstat64(1, {st_mode=S_IFCHR|0620, st_rdev=makedev(4, 1), ...}) = 0
ioctl(1, SNDCTL_TMR_TIMEBASE or TCGETS, {B38400 opost isig icanon echo ...}) = 0
mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb76f4000
write(1, "1:Aggiungi Figurine\n", 20)   = 20
write(1, "2:Rimuovi Figurine\n", 19)    = 19
write(1, "3:Quante Sono Le Mancanti\n", 26) = 26
write(1, "4:Controlla Figurina\n", 21)  = 21
write(1, "5:Genera Mancanti\n", 18)     = 18
write(1, "6:Esci\n", 7)                 = 7
fstat64(0, {st_mode=S_IFCHR|0620, st_rdev=makedev(4, 1), ...}) = 0
ioctl(0, SNDCTL_TMR_TIMEBASE or TCGETS, {B38400 opost isig icanon echo ...}) = 0
mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb76f3000
read(0, "r\n", 4096)                    = 2
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
write(1, "1:Aggiungi Figurine\n", 20)   = 20
write(1, "2:Rimuovi Figurine\n", 19)    = 19
write(1, "3:Quante Sono Le Mancanti\n", 26) = 26
write(1, "4:Controlla Figurina\n", 21)  = 21
write(1, "5:Genera Mancanti\n", 18)     = 18
write(1, "6:Esci\n", 7)                 = 7
write(1, "1:Aggiungi Figurine\n", 20)   = 20
write(1, "2:Rimuovi Figurine\n", 19)    = 19
write(1, "3:Quante Sono Le Mancanti\n", 26) = 26
write(1, "4:Controlla Figurina\n", 21)  = 21
write(1, "5:Genera Mancanti\n", 18)     = 18
write(1, "6:Esci\n", 7)                 = 7
...
Il valore di return e` 2 (due), non 1 (uno).

Avatar utente
Blallo
Packager
Packager
Messaggi: 3302
Iscritto il: ven 12 ott 2007, 11:37
Nome Cognome: Savino Liguori
Slackware: 14.2 / 12.2
Kernel: 4.4.14-smp
Desktop: DWM
Località: Torino / Torremaggiore (FG)
Contatta:

Re: [Utilità del Cavolo] Programma Gestione Figurine

Messaggio da Blallo »

Mario Vanoni ha scritto:Il valore di return e` 2 (due), non 1 (uno).
giusto, ora che ho provato con le lettere si verifica effettivamente
hai quache consiglio per evitare il problema?

Mario Vanoni
Iper Master
Iper Master
Messaggi: 3174
Iscritto il: lun 3 set 2007, 21:20
Nome Cognome: Mario Vanoni
Slackware: 12.2
Kernel: 3.0.4 statico
Desktop: fluxbox/seamonkey
Località: Cuasso al Monte (VA)

Re: [Utilità del Cavolo] Programma Gestione Figurine

Messaggio da Mario Vanoni »

jimmy_page_89 ha scritto:
Mario Vanoni ha scritto:Il valore di return e` 2 (due), non 1 (uno).
giusto, ora che ho provato con le lettere si verifica effettivamente
hai quache consiglio per evitare il problema?
No per il momento, sorry, hai tanti while ...
Ma mettendo 2, poi 6, strace dice

Codice: Seleziona tutto

root@va2:~# less cavolo.err
execve("./cavolo", ["cavolo"], [/* 37 vars */]) = 0
brk(0)                                  = 0x90ca000
access("/etc/ld.so.preload", R_OK)      = -1 ENOENT (No such file or directory)
open("/etc/ld.so.cache", O_RDONLY)      = 3
fstat64(3, {st_mode=S_IFREG|0644, st_size=128948, ...}) = 0
mmap2(NULL, 128948, PROT_READ, MAP_PRIVATE, 3, 0) = 0xb76f9000
close(3)                                = 0
open("/lib/libc.so.6", O_RDONLY)        = 3
read(3, "\177ELF\1\1\1\0\0\0\0\0\0\0\0\0\3\0\3\0\1\0\0\0\360d\1"..., 512) = 512
fstat64(3, {st_mode=S_IFREG|0755, st_size=1570593, ...}) = 0
mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb76f8000
mmap2(NULL, 1357360, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0xb75ac000
mprotect(0xb76f1000, 4096, PROT_NONE)   = 0
mmap2(0xb76f2000, 12288, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x145) = 0xb76f2000
mmap2(0xb76f5000, 9776, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0xb76f5000
close(3)                                = 0
mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb75ab000
set_thread_area({entry_number:-1 -> 6, base_addr:0xb75ab6c0, limit:1048575, seg_32bit:1, contents:0, read_exec_only:0, limit_in_pages:1, seg_not_present:0, useable:1}) = 0
mprotect(0xb76f2000, 8192, PROT_READ)   = 0
mprotect(0xb7736000, 4096, PROT_READ)   = 0
munmap(0xb76f9000, 128948)              = 0
brk(0)                                  = 0x90ca000
brk(0x90eb000)                          = 0x90eb000
open("figu.txt", O_RDONLY)              = 3
fstat64(3, {st_mode=S_IFREG|0644, st_size=0, ...}) = 0
mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7718000
read(3, "", 4096)                       = 0
fstat64(1, {st_mode=S_IFCHR|0620, st_rdev=makedev(4, 1), ...}) = 0
ioctl(1, SNDCTL_TMR_TIMEBASE or TCGETS, {B38400 opost isig icanon echo ...}) = 0
mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7717000
write(1, "1:Aggiungi Figurine\n", 20)   = 20
write(1, "2:Rimuovi Figurine\n", 19)    = 19
write(1, "3:Quante Sono Le Mancanti\n", 26) = 26
write(1, "4:Controlla Figurina\n", 21)  = 21
write(1, "5:Genera Mancanti\n", 18)     = 18
write(1, "6:Esci\n", 7)                 = 7
fstat64(0, {st_mode=S_IFCHR|0620, st_rdev=makedev(4, 1), ...}) = 0
ioctl(0, SNDCTL_TMR_TIMEBASE or TCGETS, {B38400 opost isig icanon echo ...}) = 0
mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7716000
read(0, "2\n", 4096)                    = 2
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
write(1, "Terminare con 0\n", 16)       = 16
read(0, "0\n", 4096)                    = 2
write(1, "1:Aggiungi Figurine\n", 20)   = 20
write(1, "2:Rimuovi Figurine\n", 19)    = 19
write(1, "3:Quante Sono Le Mancanti\n", 26) = 26
write(1, "4:Controlla Figurina\n", 21)  = 21
write(1, "5:Genera Mancanti\n", 18)     = 18
write(1, "6:Esci\n", 7)                 = 7
read(0, "6\n", 4096)                    = 2
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
open("figu.txt", O_WRONLY|O_CREAT|O_TRUNC, 0666) = 4
fstat64(4, {st_mode=S_IFREG|0644, st_size=0, ...}) = 0
mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7715000
write(4, "0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "..., 1468) = 1468
close(4)                                = 0
munmap(0xb7715000, 4096)                = 0
exit_group(0)                           = ?
Quindi sembra un problema di un while che si inchioda.

Mario Vanoni
Iper Master
Iper Master
Messaggi: 3174
Iscritto il: lun 3 set 2007, 21:20
Nome Cognome: Mario Vanoni
Slackware: 12.2
Kernel: 3.0.4 statico
Desktop: fluxbox/seamonkey
Località: Cuasso al Monte (VA)

Re: [Utilità del Cavolo] Programma Gestione Figurine

Messaggio da Mario Vanoni »

Il problema che non controlli il valore di ritorno di scanf(1)!

Ricompilata la tua ultima versione, cancellato figu.txt.

Codice: Seleziona tutto

root@va2:~# cavolo
Il file non esiste! Che vuoi fare?
1:Crea Nuovo File
2:Esci
e
Segmentation fault
root@va2:~#
Almeno un
if (scanf("%d", &opt) == 1) prosegui
else segnala errore.

Gia` qui uno switch sarebbe pratico con
case 1:
...
break;
case 2:
...
break;
default:
messaggio di errore su stderr con exit non zero

Nei while, scanf, dando per scontato che ritorna 1,
non ritornando 1, mandano i while in loop.

Avatar utente
Blallo
Packager
Packager
Messaggi: 3302
Iscritto il: ven 12 ott 2007, 11:37
Nome Cognome: Savino Liguori
Slackware: 14.2 / 12.2
Kernel: 4.4.14-smp
Desktop: DWM
Località: Torino / Torremaggiore (FG)
Contatta:

Re: [Utilità del Cavolo] Programma Gestione Figurine

Messaggio da Blallo »

Mario Vanoni ha scritto:Il problema che non controlli il valore di ritorno di scanf(1)!

Ricompilata la tua ultima versione, cancellato figu.txt.

Codice: Seleziona tutto

root@va2:~# cavolo
Il file non esiste! Che vuoi fare?
1:Crea Nuovo File
2:Esci
e
Segmentation fault
root@va2:~#
Almeno un
if (scanf("%d", &opt) == 1) prosegui
else segnala errore.

Gia` qui uno switch sarebbe pratico con
case 1:
...
break;
case 2:
...
break;
default:
messaggio di errore su stderr con exit non zero

Nei while, scanf, dando per scontato che ritorna 1,
non ritornando 1, mandano i while in loop.
Grazie mille Mario, appena ho 5 minuti lo rielaboro con gli switch e ti faccio sapere.

Mario Vanoni
Iper Master
Iper Master
Messaggi: 3174
Iscritto il: lun 3 set 2007, 21:20
Nome Cognome: Mario Vanoni
Slackware: 12.2
Kernel: 3.0.4 statico
Desktop: fluxbox/seamonkey
Località: Cuasso al Monte (VA)

Re: [Utilità del Cavolo] Programma Gestione Figurine

Messaggio da Mario Vanoni »

jimmy_page_89 ha scritto: Grazie mille Mario, appena ho 5 minuti lo rielaboro con gli switch e ti faccio sapere.
Visto che correggi, non usare scanf(3), ma usa sscanf(3), ragione:
http://sourceforge.net/apps/mediawiki/c ... Scanf_woes
e
http://www.linuxsecurity.com/content/view/119087/171/

Codice: Seleziona tutto

 Example:

int main()
	{
	char buff[15]={0};
	printf(“Enter your name:”);
	scanf(buff,”%s”);
	}

In this example, program reads a string from the standard input but does not check strings length. If the string has more than 14 characters, then it causes a buffer overflow as scanf() tries to write the remaining character past buff’s end.

Note: One character is always reserved for a null terminator. 
Da 15 anni non uso piu` scanf(3), solo unicamente sscanf(3)!

Esempio pratico:

Codice: Seleziona tutto

root@va2:~# cavolo
Il file non esiste! Che vuoi fare?
1:Crea Nuovo File
2:Esci
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
Segmentation fault
root@va2:~# 

Avatar utente
j0kers
Linux 2.x
Linux 2.x
Messaggi: 418
Iscritto il: dom 22 lug 2007, 1:31
Slackware: 13
Kernel: 2.6.32
Desktop: xfce4

Re: [Utilità del Cavolo] Programma Gestione Figurine

Messaggio da j0kers »

Quoto Mario, meglio usare sscanf, inoltre i controlli sull'inserimento da input quando si creano programmi del genere bisogna sempre farli altrimenti questo è il risultato 8)

Avatar utente
Blallo
Packager
Packager
Messaggi: 3302
Iscritto il: ven 12 ott 2007, 11:37
Nome Cognome: Savino Liguori
Slackware: 14.2 / 12.2
Kernel: 4.4.14-smp
Desktop: DWM
Località: Torino / Torremaggiore (FG)
Contatta:

Re: [Utilità del Cavolo] Programma Gestione Figurine

Messaggio da Blallo »

Codice: Seleziona tutto

#include <stdio.h>
#include <stdlib.h>
#define N 734
#define TA 200

void print_menu();
void open_file(FILE **fp, char buf[TA], int *vect, int N);
void add(char buf[TA], int *vect);
void rem(char buf[TA], int *vect);
void check_less(int vect[N], int N);
void check_single(int vect[N], int N);
void gen_less(FILE **fp, int vect[N], int N);
void saving_all(FILE **fp, int vect[N], int N, int *chs);

int main()
{
    FILE *fp;
    char buf[TA];
    int vect[N];
    int chs=0, opt=0;

    open_file(&fp, buf, vect, N);
    while(chs==0)
	{
        print_menu(); //lo so che è inutile, ma mi piace mettere così :P
		fgets(buf, TA, stdin);
		sscanf(buf, "%d", &opt);
		switch(opt)
		{
		    case 1:
                add(buf, vect);
                break;
            case 2:
                rem(buf, vect);
                break;
            case 3:
                check_less(vect, N);
                break;
            case 4:
                check_single(vect, N);
                break;
            case 5:
                gen_less(&fp, vect, N);
                break;
            case 6:
                printf("Sto Salvando..\n");
                saving_all(&fp, vect, N, &chs);
                printf("Uscita\n");
                break;
            default:
                printf("Comando Errato\n");
                break;
		}
	}

}

void open_file(FILE **fp, char buf[TA], int *vect, int N)
{
    int opt, i=0, chk=0;

    if(((*fp)=open("figu.txt","r")) == NULL)
    {
        while(chk == 0)
        {
            printf("Il file non esiste! Che vuoi fare?\n");
            printf("1:Crea Nuovo File\n");
            printf("2:Esci\n");
            fgets(buf, TA, stdin);
            sscanf(buf, "%d", &opt);
            switch(opt)
            {
                case 1:
                    if(((*fp)=fopen("figu.txt","w"))==NULL)
                    {
                        printf("Errore Apertura File!\n");
                        exit(1);
                    }
                    fclose(*fp);
                    for(i=0;i<N;i++)
                        vect[i]=0;
                    chk=1;
                    break;
                case 2:
                    printf("Uscita\n");
                    chk=1;
                    break;
                default:
                    printf("Comando Errato\n");
                    break;
            }
        }
    }
    else
    {
        while((fscanf((*fp), "%d", vect[i])) == 1 && !feof(*fp))
            i++;
        fclose(*fp);
    }
}

void print_menu()
{
    printf("1:Aggiungi Figurine\n");
	printf("2:Rimuovi Figurine\n");
	printf("3:Figurine Mancanti\n");
	printf("4:Controlla Figurina\n");
	printf("5:Genera Mancanti\n");
	printf("6:Esci\n");
}

void add(char buf[TA], int *vect)
{
    int num, chk;

    printf("TAerminare con 0\n");
    while(chk == 0)
    {
        fgets(buf, TA, stdin);
        sscanf(buf, "%d", &num);
        if(num == 0)
            chk=1;
        else if(num > N)
            printf("Numero TAroppo Grande\n");
        else
        {
            if(vect[num-1] == 1)
                printf("Figurina Già Presente\n");
            else
                vect[num-1]=1;
        }
    }
}

void rem(char buf[TA], int *vect)
{
    int num, chk;

    printf("TAerminare con 0\n");
    while(chk == 0)
    {
        fgets(buf, TA, stdin);
        sscanf(buf, "%d", &num);
        if(num == 0)
            chk=1;
        else if(num > N)
            printf("Numero TAroppo Grande\n");
        else
        {
            if(vect[num-1] == 0)
                printf("Figurina Già Assente\n");
            else
                vect[num-1]=0;
        }
    }
}

void check_less(int vect[N], int N)
{
    int i, num=0;

	for(i=0;i<N;i++)
		if(vect[i] == 0)
			num++;

    printf("%d\n", num);
}

void check_single(int vect[N], int N)
{
    int num, chk=0;

    while(chk == 0)
    {
        fgets(buf, TA, stdin);
        sscanf(buf, "%d", &num)
        if(num==0)
            break;
        else if(num > N)
            printf("Numero TAroppo Grande\n");
        else
        {
          if(vect[num-1] == 1)
            printf("Presente\n");
          else
            printf("Assente\n");
        }
    }
}

void gen_less(FILE **fp, int vect[N], int N)
{
    int i;

    if(((*fp)=fopen("mancanti.txt","w"))==NULL)
    {
        printf("Errore Apertura File!");
        exit(1);
    }

    for(i=0;i<N;i++)
    if(vect[i]==0)
        fprintf((*fp), "%d ", i+1);

    fclose(*fp);
}

void saving_all(FILE **fp, int vect[N], int N, int *chs)
{
    if((fp=fopen("figu.txt","w"))==NULL)
    {
        printf("Errore Apertura File");
		exit(1);
    }

	for(i=0;i<N;i++)
        fprintf((*fp), "%d ", vect[i]);

    (*chs)=1;

    fclose(*fp);
}
mi sembra corretto, ma mi sputa alla compilazione

Codice: Seleziona tutto

/home/liguori/Downloads/Untitled1.c|7|error: expected ‘;’, ‘,’ or ‘)’ before numeric constant|
/home/liguori/Downloads/Untitled1.c|10|error: expected ‘;’, ‘,’ or ‘)’ before numeric constant|
/home/liguori/Downloads/Untitled1.c|11|error: expected ‘;’, ‘,’ or ‘)’ before numeric constant|
/home/liguori/Downloads/Untitled1.c|12|error: expected ‘;’, ‘,’ or ‘)’ before numeric constant|
/home/liguori/Downloads/Untitled1.c|13|error: expected ‘;’, ‘,’ or ‘)’ before numeric constant|
/home/liguori/Downloads/Untitled1.c|58|error: expected ‘;’, ‘,’ or ‘)’ before numeric constant|
/home/liguori/Downloads/Untitled1.c|158|error: expected ‘;’, ‘,’ or ‘)’ before numeric constant|
/home/liguori/Downloads/Untitled1.c|169|error: expected ‘;’, ‘,’ or ‘)’ before numeric constant|
/home/liguori/Downloads/Untitled1.c|191|error: expected ‘;’, ‘,’ or ‘)’ before numeric constant|
/home/liguori/Downloads/Untitled1.c|208|error: expected ‘;’, ‘,’ or ‘)’ before numeric constant|
e non capisco perchè!!!

Avatar utente
j0kers
Linux 2.x
Linux 2.x
Messaggi: 418
Iscritto il: dom 22 lug 2007, 1:31
Slackware: 13
Kernel: 2.6.32
Desktop: xfce4

Re: [Utilità del Cavolo] Programma Gestione Figurine

Messaggio da j0kers »

Non vorrei dire stubidagini ma a prima vista l'errore secondo me l'errore potrebbe essere quel "int N" che passi in ogni funzione.
N=734 quindi passeresti nelle funzioni void eccc....(....,int 734) che non ha senso secondo me
comunque appena posso provo a compilarlo e ti faccio sapere 8)

Rispondi