[c] esercizzio conteggio caratteri da stdin

luca981
con il linguaggio c
mi sono accorto di avere un programmino che conta i caratteri del file .
tipo cosi
FILE *fpSource;
   if((fpSource = fopen("righe.txt", "r")) != NULL)
   {
      codice
   }
   else
   {
      perror("Errore in apertura del file. \n");
   }

cosi ho provato ha fare la stessa cosa con lo stdin
ma dopo un po di prove ho dei problemi !
#include<stdio.h>
#define MAX_SIZE 60
main()
{
   int nc;                                /*conteggio dei caratteri*/
   char ca;                               /* carattere */
   char riga[MAX_SIZE] = "";              // prima stringa esterna di carica                                   usata da reset
   nc = 0;
   fgets(riga, MAX_SIZE, stdin);
   while ((ca=fgetc(riga)) != EOF)
   {
   ++nc;
   }
   printf("\ti caratteri sono :  %d\n", nc);
}

il tipo di errore e questo ...... deve essere uno sbaglio sui puntatori.
luca@luca-desktop:~/Scrivania/progetto$ gcc progetto7.c
progetto7.c: In function ‘main’:
progetto7.c:10: warning: passing argument 1 of ‘fgetc’ from incompatible pointer type
luca@luca-desktop:~/Scrivania/progetto$ 

qualcuno sa darmi una mano ?

Risposte
apatriarca
fgetc richiede un puntatore a FILE, mentre tu hai passato una stringa. Non mi è chiaro lo scopo di fgets(riga, MAX_SIZE, stdin) nel tuo codice. Il codice corretto dovrebbe essere:

#include <stdio.h>

int main()
{
    int nc = 0; /* numero di caratteri. */

    while(fgetc(stdin) != EOF) ++nc;

    printf("I caratteri sono: %d\n", nc);

    return 0;
}

luca981
#include <stdio.h>

int main()
{
    int nc = 0; /* numero di caratteri. */

    while(fgetc(stdin) != EOF) ++nc;

    printf("I caratteri sono: %d\n", nc);

    return 0;
} 

il programma non funziona !
perche quando scrivo la mia frase e schiaccio invio lo sterm legge invio ("\n" mi pare )
per capire la fine dello standart input devo per forza usare EOF
cosi sono costretto a dare EOF da terminale "ctrl-d" con linux

sono costretto a caricare la mia riga da terminale in una variabile con fgetc ?
probabilmente c'e qualcosa che mi sfugge
vi chiedo aiuto !
grazie

apatriarca
È sufficiente aggiungere la condizione che il valore letto non sia '\n' per fermarsi prima.

luca981
cioe al posto di EOF metto \n ?
no
per condizione si intende un if .
ci penso domani vado a dormire .

apatriarca
Intendo qualcosa come:
int c;

while ((c = fgetc(stdin)) != EOF && c != '\n') ++nc;

karhel
Direi che questo dovrebbe risolvere il tuo problema:
(nota la mia versione restituisce il risultato quando digiti lo spazio " ")

#include <stdio.h>
main()
{
 char c;
 int cont=0;
 do
 {
  c=getchar();   
  cont++;
 }
 while(c!=32);
 printf("\n la quantita' di caratteri digitati e': %d",cont);
}

mi domando, ma se leggi da stdin che bisogno hai di usare i comandi per la gestione dei file????
stdin è già letto come impostazione base da ogni funzione

cioè per capirci

la getchar() è una funzione che legge il file stdin e quando termina il file restituisce EOF


spero di esserti stato utile :D

luca981
avevo un vechio programmino che contava i caratteri da un file di testo
e ho provato a sccopiazzarlo .

non mi ero reso conto che la lettura di uno Stream
si puo arrestare in qualsiasi momento senza il bisogno di EOF
ad esempio posso arrestare il processo di lettura se la mia lettera letta e la "s"
questo mi sembra che funzioni bene :
#include <stdio.h>

int main()
{
int nc = 0; /* numero di caratteri. */
char c;
while ((c = fgetc(stdin)) != EOF && c != '\n') 
   ++nc ; 
printf("I caratteri sono: %d\n", nc);
}


la mia intenzione sarebbe quella di fare un programmino che carica da stdin e separa le "parole divise da uno spazio intendo"
a seconda di quante sono le memorizzo o in puntatori o in variabili variabile1 variabile2 variabile3 ecc ......
ma non so come fare . accetto consigli !

per questo non so se mi conviene usare subito fgets(riga, MAX_SIZE, stdin);
e poi dividere la variabile char riga , magari con uno scanf che legge fino allo spazio .

o usare tipo questo : per il coteggio delle parole e l'asegnamento
char c;
while ((c = fgetc(stdin)) != EOF && c != '\n' && c!=' ') 
   ++nc ;

mi tochera leggere ancora un po di roba !
spero di essermi spiegato
grazzie !

karhel
francamente non capisco!!!

qual'è l'esatto obiettivo che stai ponendo????

non ha senso dire leggo da tastiera, e poi divido le parole dallo spazio e le metto in n variabili!!!

se tu hai 500 parole non puoi creare 500 variabili è illogico oltre che enormemente sbagliato sia in termini programmativi
che come spazio occupato nella memoria che come tempo di calcolo.

al max posso immaginare una lettura da tastiera di una stringa e poi la gestione di questa a seconda dello scopo
che però non mi è chiaro.

luca981
scusate
cioe :
il programma dovrebbe fare cosi.
>> quali sono le parole ?
la 1 parola e : quali
la 2 parola e : sono
la 3 parola e : le
la 4 parola e : parole
la 5 parola e : ?
---------------------------
>>

Umby2
"luca98":
scusate
cioe :
il programma dovrebbe fare cosi.


mbè... piu' che "conteggio caratteri" mi sembra che si tratta di una separazione delle parole all'interno di un testo.

L'esercizio dovrebbe essere molto semplice:
1) Devi definire quali sono i separatori di parole " " (spazio) "(" ")" parentesi "," virgola "." punto..... e cosi' via

2) Leggere il testo un carattere alla volta, e quando incontri un separatore "chiudi" la parola e vai avanti cosi fino all' EOF finale.

luca981
bello ! non conoscevo la ctype.h l'header file
#include <stdio.h>
#include <ctype.h>
#define MAX 10

int main(int argc, char *argv[]) {
    int count = 0;
    char word[MAX];
    int i = 0;
    char c;
   
    while ((c = fgetc(stdin)) != EOF) {
        if (isspace(c)) {
            if (i > 0) {
                ++count;
                word[i] = '\0';
                printf("la %d^ parola e': %s\n", count, word);
                i = 0;
            }
        } else {
            if (i < MAX-1) {
                word[i++] = c;
            } else {
                while (!isspace(c = fgetc(stdin))) {
                }
                ++count;
                printf("la %d^ parola e' troppo lunga\n", count);
                i = 0;
                ungetc(c, stdin);
            }
        }
    }
    return 0;
}

adesso provo anche io !

luca981
perche si mette il punto escamativo ?
         while (!isspace(c = fgetc(stdin))) 
         {
         }

karhel
Credo che dire: "!" è la negazione logica sarebbe stato più semplice e immediato :D


Se A è l'affermazione positiva !A è la sua diretta negazione.


cmq va bene anche al tua hihihihi :)

luca981
vi chiedo ancora una cosa allora ....
se la mia stringa e "non ci sono nuvole"
e io collego un puntatore alla stringa al settimo carattere (7) per
collegare solo la parola "sono"
fino al 10 carattere quindi

si puo fare ?

karhel
"luca98":
vi chiedo ancora una cosa allora ....
se la mia stringa e "non ci sono nuvole"
e io collego un puntatore alla stringa al settimo carattere (7) per
collegare solo la parola "sono"
fino al 10 carattere quindi

si puo fare ?


francamente non si capisce quello che chiedi.
cosa significa collego un puntatore (che cmq al max sarà un indice visto che un puntatore è un riferimento alla memoria)
al 7° carattere per collegare la parola "sono"
la parola sono è già li se l'hai scritta in input

se invece la frase di input è "non ci "
allora puoi introdurla forzatamente nella stringa che verrà generata usando il comando di concatenazione
disponibile nella libreria delle stringhe del C
oppure inserendola tu carattere x carattere ricordando il terminatore.

spero di aver capito altrimenti fai un esempio di quello che vuoi fare.

luca981
cioe :
a me servono le singole parole della stringa letta
pero devo ricordarle tutte per poterle riutilizzare

a seconda della parola , le scrivo su un file ad esempio
oppure la uso per una funzione
o ipotizzo se e un articolo (il lo....) gli do il valore di maschile o femminile ecc

non so come fare .
e se si puo fare .

karhel
concordo con Sergio quasi tutto si può fare
però ciò che scrivi continua ad essere un mistero


Se tu leggi una stringa non hai bisogno di ricordarla è già li nella stringa al max dovrai rileggerla
se poi ti servono le singole parole sarà un problema di controllo nella rilettura
cioè devi stabilire quali sono i terminatori delle parole e terminare la scansione al raggiungimento di questi caratteri.


esempio:

se tu scrivi: La mamma è andata a fare la spesa

la struttura che legge la tua stringa in input sarà formata da: "La mamma è andata a fare la spesa/0"

quindi a questo punto non dovrai fare altro che leggere la stringa un carattere alla volta e mettere da un'altra parte il risultato della scansione. (ricordando che /0 è il terminatore della stringa)

tipo che so crei una matrice di stringhe dove per ogni riga metti la tua scansione
La
mamma
è
andata
a
fare
la
spesa

poi potresti avere un vettore che ha n celle quante sono le n righe della tua matrice
e creare una legenda dove assegni valori ai singoli elementi.

che so: 0 maschile 1 femminile 2 plurale 3 blablabla... e così via

rileggendo le righe della matrice vedi che cos'è e in corrispondenza del vettore assegni il risultato

a questo punto hai ottenuto un indicatore grammaticale che al variare della parola assegna il tipo.

ma ovviamente dovrai poi creare una funzione che riconosce le parole e quindi dovrà essere struttura con tutte le regole della grammatica i casi particolari e compagnia bella (un lavoraccio enorme) che secondo me non è alla tua portata.


(ammesso che io abbia capito cosa intendi fare)

luca981
io pensavo una cosa simile a questa:
#include<stdio.h>

main()
{
   int lung=0;            
   int stri=0;          
   char c;         

   char input[20][20];
   input[stri][0] = '\0';
   while ((c = fgetc(stdin)) != '\n')
   {

      if (c == ' ')
      {
         lung=0;
         printf(">>%s \n", input[stri]);
         stri++;
      }
      input[stri][lung] = c;
      input[stri][lung+1] = '\0';
      lung++;
   }
   printf(">\n");
   printf(">\n");

   printf(">>%s \n", input[0]);
   printf(">>%s \n", input[1]);
   printf(">>%s \n", input[2]);
   printf(">>%s \n", input[3]);
   printf(">>%s \n", input[4]);
   printf(">>%s \n", input[5]);
// ecc...
}

ma non funziona proprio benissimo !

karhel
prova con:


#include<stdio.h>

main()
{
   int max_riga=20;
   int max_colonna=20;   
   int lung=0;           
   int stri=0;         
   char c;         

   char input[max_riga][max_colonna];
   input[stri][0] = '\0';
   while ((c = fgetc(stdin)) != '\n')
   {

      if (c == ' ')
      {
       lung=0;
       stri++;
      }
      else
      {
       input[stri][lung] = c;
       input[stri][lung+1] = '\0';
       lung++;
      } 
   }
   
   for(int i=0;i<stri+1;i++)
    printf("\n >>%s", input[i]);
}




direi che ora funziona!!! o meglio fa quello che dovrebbe fare il codice che hai scritto =)

ps: questo vale ovviamente solo per la prima riga, se vuoi che lo faccia per tutto il file dovrai cambiare il while

luca981
perfetto !!
funziona !!
non so se da solo sarei arrivato !
grazie !!!
:)
#include<stdio.h>

main()
{
   int max_riga=20;
   int max_colonna=20;   
   int lung=0;           
   int stri=0;         
   char c;         
   int i;

   char input[max_riga][max_colonna];
   input[stri][0] = '\0';
   while ((c = fgetc(stdin)) != '\n')
   {

      if (c == ' ')
      {
       lung=0;
       stri++;
      }
      else
      {
       input[stri][lung] = c;
       input[stri][lung+1] = '\0';
       lung++;
      }
   }
   printf("\n");
   for(i=0;i<stri+1;i++)
   printf(">>%s\n", input[i]);
} 

Rispondi
Per rispondere a questa discussione devi prima effettuare il login.