Newsgroup: it.comp.lang.c
Titolo: Algoritmo strano...

> Dobbiamo capire quanto vale N all'inserimento della prima riga in modo  da fargli inserire max N righe (visto che la matrice è N*N)
PS. da notare che quello che so io di C e che si presume sia sufficente
a realizzare questo programma è poco. Oltre alle librerie standard
(stdio.h e stlib.h) posso usare solo string.h (limitata alle funzioni
getchar, strcpy strcmp e strlen) e la libreria matematica. No puntatori
o funzioni esterne fuori dal Main.
credo di aver detto tutto.
allora, io ci ho provato ma mi rendo conto di aver commesso errori di
fondo... del tipo che si, sono riuscito teoricamente a leggere i valori
separandoli da spazi ecc, alla lettura prima riga ho reimpostato N e
messo la condizione del while principale in modo che arrivi max a N
 il problema è che per leggere i valori 1 a 1 ho usato getchar() che
in questa maniera mi legge un carattere e se l'utente inserisce 1 nel
vettore non avrò 1 ma 49 (ascii di 1)
allora ho pensato di togliere togliere 49 nel caso il carattere nn sia
uno spazio (=32) o Invio (=13) ... ma non so perchè non mi funziona,
c'è qualcosa che non va... boh
(si da per scontato che l'utente inserisca solo numeri e non lettere)
sapete aiutarmi???
Ciao e scusate il post lungo!
Grazie 100000000000000000 anticipati a chi risponde!

Ma tu sai in precedente N quanto è? E poi devi fare leggere tutti e
100 valori e li devi memorizzare come stringhe? O devi leggere N*N
valori che sono compresi tra 0 e 1000?

Allora, non mi sono spiegato, ....è sicuramente più difficiel
spiegare il problema che risolverlo.
allora, io so che dovrò riempire una matrice di MAX 6X6 ma è
probabile che l'utente voglia una matrice 4x4 o 3x3 o 5x5. Io so
dall'inizio che N potrà essere max 6 (cioè la matrice potrà essere
al max 6x6)
Io devo capire, dalla prima riga che inserisce l'utente (l'utente
inserisce i numeri senza dare invio ma solo separati da spazi) quanto
grande dovrà essere la matrice...
Es. l'utente inserisce:
6 100 56 89 (e subito dopo INVIO)
allora io devo capire che l'utente sta inserendo una matrice 4X4 e che
quindi IO DOVRò chiederglidi inserire solo 4 righe (ovvero adesso solo
altre 3 perchè 1 l'ha gia inserita) , cioè appena digita INVIO alla
quarta riga io devo passare all'elaborazione di questa matrice (la cui
elaborazione non è un problema).
Come posso fare dati i pochi strumenti che posso usare (elencati nel
mio primo post)?? 
Ciao!

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
int main()
{
  char stringa[100];
  int N = 0;
  char c;
  int i = 0, j;
  int matrice[6][6];
  while ((c = getchar()) != EOF)
  {
    if (isdigit(c))
      stringa[i++] = c;
    else if (c == ' ' || c == '\t')
    {
      stringa[i] = '\0';
      matrice[0][N++] = atoi(stringa);
      i = 0;
    }
    else if (c == '\n')
    {
      stringa[i] = '\0';
      matrice[0][N++] = atoi(stringa);
      break;
    }
  }
  for (i = 1; i < N; i++)
    for (j = 0; j < N; j++)
      scanf("%d", &matrice[i][j]);
  for (i = 0; i < N; i++)
  {
    for (j = 0; j < N; j++)
      printf("%d\t", matrice[i][j]);
    printf("\n");
  }
  return 0;
}
allora, questo codice funziona... ma ci sono diversi problemi da
risolvere (sempre meglio di niente)
per esempio i numeri devono essere saparati da un solo spazio e dopo
l'ultimo numero ci deve essere subito '\n', cmq è un'idea, vedi un
pò. Cmq forse ti converrebbe caricare la linea in un buffer con fgets
e poi la processi in loco... fammi sapere

grazie della tua disponibilità.... ma non posso usare né la libbreria
ctype ne tatnomeno atoi() di cui ignoro il funzionamento...
come potrei fare??
Grazie comunque!!

 Grazie 100000000000000000 anticipati a chi risponde!
Prego 99999999999999999..
Ciao
Matic

Magnifico, questo è quello che probabilmente si avvicina di + a quello
che cercano...
ma anche qui ci sono dei comandi che io non conosco e che quindi non
dovrei poter usare... a cominciare da fgets, sizeof (che credo si possa
sostituire con una costante) e stdin....
puoi spiegarmi brevemente il funzionamento di fgets e stdin??
Grazie per la disponibilità, siete grandi!

 
Non sono comandi.
sizeof(tipo) e' un operatore che restituisce la dimensione del tipo 
specificato e si, puo' essere sostituito da una costante come in effetti 
potrebbe succedere in fase di compilazione, ma non va fatto perche' 
perderesti la portabilita' del codice.
fgets(char *str, int dim, FILE *stream) legge al massimo dim-1 caratteri 
da stream e li mette in str. Si ferma prima di dim-1 caratteri se 
incontra '\n' (che viene comunque aggiunto alla fine di str) o EOF. 
Aggiunge '\0' alla fine della stringa str.
stdin e' il flusso di input standard, e' di tipo FILE* e quindi puo' 
essere usato come ultimo argomento di fgets.
Esempio:
#include <stdio.h>
#include <string.h>
int main()
{
   char stringa[5];
   fgets(stringa,5,stdin);
   return 0;
}
Questo programma legge da tastiera (a meno che tu non abbia usato un 
redirect dell'input) al massimo 4 caratteri e li mette in stringa.
Comunque per imparare veramente bene dovresti studiare un manuale... 
credo che sia l'unico modo.
-- 
Devaraja (Xdevaraja87^gmail^c0mX)
Linux Registerd User #338167
http://counter.li.org

si, si, sul fatto che debba studiare il manuale ci siamo, lo sto
studiando, ma l'esercizio che mi è stato assegnato doveva essere
svolto con quello che sapevo fino ad allora... quindi era una
limitazione forzata e non che io non volessi usare istruzioni che non
conoscevo. Mi era proprio richiesto di non usre altri meccanismi al di
fuori di quelli che conoscevo...
Comunque grazie dell'impegno!
Ciao!

 
Buona fortuna!


thedog ha scritto:

Visto che era un po' di tempo che non facevo pratica con le stringhe ho 
colto l'occasione.. se vuoi vedere come e' venuto a me guarda qui 
http://phpfi.com/97729
Io pero' non ho tenuto conto delle limitazioni sui puntatori e le 
funzioni utilizzabili ;-)


 c'è qualcosa che non va... boh
Visto che non vuoi/puoi usare funzioni di libreria oltre alla getchar
si puo` anche adottare l'algoritmo che descrivi sopra. E` pratica comune
leggere il un numero come carattere ASCII e quindi sottrarre il valore
del carattere '0'.
Non usare mai esplicitamente il valore numerico del carattere, usa
sempre il carattere stesso che e` molto piu` chiaro e portabile (il
compilatore usa il valore appropriato anche se la codifica non e` quella
ASCII).
Il ciclo per leggere un numero potrebbe essere questo:
int num = 0;
int c;
while(1) {
        c = getchar();
        if (c == EOF || (c < '0' || c > '9'))
                break;
        num = num * 10;
        num += c - '0';
}
Quindi per leggere una riga:
int num;
int c;
int count = 0;
while(1) {
        num = 0;
        while(1) {
                c = getchar();
                if (c == EOF || (c < '0' || c > '9'))
                        break;
                num = num * 10;
                num += c - '0';
                count++;
        }
        if (c == EOF)
                fine_input();
        if (c == ' ')
                /* Altro numero sulla stessa riga */
                continue;
        if (c == '\n')
                /* Nuova riga */
                break;
        /* Carattere non valido */
        errore(); 
}
Luca
-- 
Home: 
http://kronoz.cjb.net
Il coraggio non mi manca.
E` la paura che mi frega...

specificato
Attenzione che sizeof non si applica solo ai tipi, ma agli "oggetti"
presenti in memoria, in generale.  In tal caso, è possibile omettere
le parentesi.  Ad esempio, si può scrivere:
sizeof "pippo"
oppure
sizeof a
Se a è una variabile di qualunque tipo.

 
Ciao ciao

 funzioni utilizzabili ;-)
Scusami vorrei chiederti una cosa...è uguale utilizzare al posto di 
"while(!isspace(*pt)) pt++;", questa: "pt = strpbrk (pt+sizeof(int)/2, 
CIFRE);". Il funzionamento sembra lo stesso ma non ho esperieze dirette.
Grazie!

Will ha scritto:

Non credo che sia lo stesso perche' il ciclo while salta tutte le cifre 
fino a trovare uno spazio di qualunque tipo, mentre quel codice che hai 
scritto tu cerca una cifra qualunque partendo da sizeof(int)/2 caratteri 
dopo la posizione corrente e non c'e' nessuna garanzia che il numero sia 
gia' finito li'. Per esempio:
324634657  225 237487
^
pt
La prima chiamata a strpbrk ha fatto puntare pt a questa cifra. 
Ipotizzando che sizeof(int)==4, sizeof(int)/2==2 e quindi
pt = strpbrk (pt+sizeof(int)/2,CIFRE) non farebbe altro che cercare una 
cifra a partire da pt+2. Questo significherebbe che al ritorno della 
funzione pt punterebbe a
324634657  225 237487
   ^
   pt
e non e' questo che vogliamo. Invece se usi while(!isspace(*pt)) pt++; 
ottieni questo:
324634657  225 237487
          ^
          pt
e la successiva chiamata a strpbrk(pt,"CIFRE"); causerebbe questo:
324634657  225 237487
            ^
            pt
che e' proprio quello che voglio. Spero che sia tutto chiaro (e giusto, 
dato che ho passato la giornata a studiare e sono fuso).


 gia' finito li'.
[CUT]
Eh si si, tutto chiarissimo! Ti ringrazio per la precisa spiegazione.
In effetti nella mia costruzione ( "pt = strpbrk 
(pt+sizeof(int)/2,CIFRE)" ) il senso di fare sizeof(int)/2 era di 
prendere ogni volta 2 byte che corrispondono poi alla lunghezza di un 
int. Teoricamente (anche se non ho provato) in caso di double sarebbe 
bastato fare sizeof(int) direttamente. Cmq se dopo lo studio ti vuoi 
rilassare :) prova a ricompilare il tuo esempio con il mio codice ( "pt 
= strpbrk (pt+sizeof(int)/2,CIFRE)" ), perchè da quanto ho potuto 
riprovare io andava bene.
Cmq è solo per curiosità perchè già la tua soluzione va perfettamente, 
giusto se hai voglia e tempo.
Grazie cmq!

 Grazie cmq!
Fatto! E non funziona se inserisco numeri piu' lunghi di 2 cifre :-) Ora 
ti spiego perche': forse non ti e' chiaro che sizeof restituisce la 
dimensione in *byte* (sul significato di byte c'era stato un thread 
interessante su comp.lang.c, comunque per ora non ti preoccupare di 
questa cosa) di un tipo e non la dimensione "su schermo". Quindi se io 
assegno a un int x il valore 345, sizeof x non sara' di certo 3, ma 
rimarra' costante a 4 (sul mio computer). E poi hai fatto casino con la 
dimensione dei tipi: non capisco perche' devi usare sizeof(int) per 
trovare la dimensione di un double... il mio consiglio e' di rivedere le 
basi, perche' hai le idee un po' confuse. Spero che la spiegazione sia 
comprensibile perche' non sono tanto piu' riposato di prima ;-)


 comprensibile perche' non sono tanto piu' riposato di prima ;-)
Si, giusto hai ragione. Insistevo sul fatto di fare sizeof(int)/2 in 
quanto ero convinto che gli int fossero 2 byte anzichč 4. Si sono 
arrivato ad una conclusione assurda ( se si scrive sizeof(int) ci sarą 
un motivo :) ).
Ok spiegazione assimilata. Grazie!

 un motivo :) ).
Occhio, temo che ti sia sfuggito il nocciolo della questione, che non e`
sizeof(int).
Quando leggo da tastiera una riga con fgets, quello che ottengo e` un
array di char. Se inserisco la stringa "123" e la leggo con qualcosa
come:
char buf[100];
fgets(buf, sizeof(buf), stdin);
l'array buf verra` riempito cosi`:
{'1', '2', '3', '\n', '\0', <undefined>}
Quindi quello che ho a disposizione sono dei *char* (il cui valore
numerico corrisponde alla rappresentazione delle tre cifre 1, 2, 3,
secondo una qualche tabella di codici), non degli *int*. Le funzioni di
IO come fgets, scanf, ecc. operano su char; sta poi al programmatore,
noto il dominio applicativo, intepretare correttamente tali sequenze di
caratteri; nel nostro caso la conversione da sequenza di char a int e`
il passo seguente dell'algoritmo.
Se la tua espressione strpbrk(pt + sizeof(int), CIFRE) voleva essere
usata per trovare il primo carattere numerico successivo a quello
corrente allora basta fare:
pt = strpbrk(pt + 1, CIFRE);
Luca
-- 
Home: 
http://kronoz.cjb.net
Soltanto un istante...
tuffarsi nell'infinito...
annegare senza pensieri

 pt = strpbrk(pt + 1, CIFRE);
Allora il mio scopo era quello di leggere l'intero di qualunque numero 
di cifre fosse composto (1, 2, 3, ecc). Ora avevo pensavo che potevo 
risolvere il problema del numero cifre variabile andando a leggere 
dirattamente i 4 byte di cui è formato l'interno (int) (anche se 
erroneamente ho scritto 2: sizeof(int)/2).
Ora, grazie a tuo intervento e a quello di DevarajA, mi sono reso conto 
che il mio errore era quello di spostarmi all'interno di una array di 
caratteri e non all'interno di una sezione di memoria. Cioè facendo pt = 
strpbrk(pt + sizeof(int), CIFRE); non faccio altro che andare di 4 
posizioni avanti all'array pt. Quindi, a ragion veduta, la soluzione di 
DevarajA è quella giusta.
Vorrei aggiungere una cosa che non c'entra col il discorso. Mi ha fatto 
molto piacere poter discutere con voi, ho postato anche altre volte su 
questo ng e ho sempre ricevuto risposte correte e molta disponibilità. 
Devo dire che è davvero un piacere poter discutere in questo modo con 
voi appassionati o professionisti di C. Motivo in più per poter porre 
altre questioni in seguito. Grazie mille a tutti :)