|
||||
|
|
#1 (permalink) |
|
Nuovo della community ![]()
7 Messaggi
![]() |
Lettura da file delimited
salve ragazzi, un saluto a tutto il forum dato che sono nuovo,
ho un problema simile, avrei necessità di caricare una sequenza di numeri contenuti nel file di test "prova.txt" in un vettore. es. nel file di testo è contenuta la stringa: 32 65 98 98 54 21 35 e dovrei caricarli nel vettore "numeri" tale che: numeri[0] = 32 numeri[1] = 65 numeri[2] = 98 . . . ecc ecc potreste darmi una mano? grazie a tutti |
|
|
|
|
|
#2 (permalink) |
|
Moderatore Globale ![]() ![]()
319 Messaggi
![]() ![]() ![]() |
Benvenuto nel forum.
Accodare una richiesta ad un thread esistente, in genere, non è una buona idea. Lo è ancora meno quando il thread in oggetto risale al 2006. Consiglio di dare un'occhiata al nostro Regolamento. Riguardo al problema specifico, qual è la difficoltà riscontrata ? Proponi il codice che hai prodotto nello sforzo di risolvere il problema, e discutiamolo insieme.
__________________
Tutti gli utenti sono pregati di prendere visione del Regolamento del Forum e di rispettarlo. • "Die ganzen Zahlen hat der liebe Gott gemacht, alles andere ist Menschenwerk." (Leopold Kronecker) • "A Mathematician is a machine for turning coffee into theorems." (Pal Erdös) • Un plauso a Grisha Perelman, raro esempio di genuino anticonformismo umano e scientifico. |
|
|
|
|
|
#3 (permalink) |
|
Nuovo della community ![]()
7 Messaggi
![]() |
si scusa, non sono molto pratico sui forum, adesso accodo il codice
codice:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int numeri[100];
int importa_dati_file()
{
FILE *f = fopen("numeri.txt", "r");
if(f == NULL)
{
printf("Errore nel leggere il file!\n");
return 0;
}
fread (numeri,sizeof(int),100,f);
for(int i=0; i<10;i++)
printf("%c",numeri[i]);
fclose(f);
};
int main()
{
importa_dati_file();
system("PAUSE");
}
sul file ci sono i seguenti numeri: 32 65 98 54 87 21 6 32 5 ma in output mi spunta: 35 813 mmhaa...? ![]() Ultima modifica di M.A.W. 1968 : 23-01-2010 a 18:48. |
|
|
|
|
|
#4 (permalink) |
|
Nuovo della community ![]()
7 Messaggi
![]() |
ci sono riuscito... anche se la soluzione è un pò grezza, esegue alla perfezione il suo compito...
codice:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char numeri[100];
int num_dati;
char *vettore;
int vettoreint[100];
int importa_dati_file()
{
FILE *f = fopen("numeri.txt", "r");
if(f == NULL)
{
printf("Errore nel leggere il file!\n");
return 0;
}
num_dati = fread (numeri,sizeof(char),100,f);
vettore = strtok(numeri," ");
//converte da char a int i numeri
for(int i=0; vettore != NULL; i++)
{
vettoreint[i]=atoi(vettore);
vettore = strtok(NULL, " ");
}
//stampa vettore
for(int i=0; vettoreint[i]!=0; i++)
printf("\n%i",vettoreint[i]);
};
int main()
{
importa_dati_file();
system("PAUSE");
}
|
|
|
|
|
|
#5 (permalink) |
|
Moderatore Globale ![]() ![]()
319 Messaggi
![]() ![]() ![]() |
In effetti, il ricorso a strtok() è un escamotage probabilmente eccessivo, come d'altro canto è eccessiva (e inerentemente poco robusta) quella fread() dimensionata per 100 char.
Suggerisco di ripensare il codice e optare per una soluzione più elegante ed efficace che faccia uso di fgets(). Inoltre sarà molto didattico sperimentare soluzioni alternative alla strtok().
__________________
Tutti gli utenti sono pregati di prendere visione del Regolamento del Forum e di rispettarlo. • "Die ganzen Zahlen hat der liebe Gott gemacht, alles andere ist Menschenwerk." (Leopold Kronecker) • "A Mathematician is a machine for turning coffee into theorems." (Pal Erdös) • Un plauso a Grisha Perelman, raro esempio di genuino anticonformismo umano e scientifico. |
|
|
|
|
|
#6 (permalink) |
|
Nuovo della community ![]()
7 Messaggi
![]() |
si infatti, è stata allocata a 100 per una semplice prova, adesso sistemo il codice è metto qualcosa di meno osceno...
![]() il problema e che non riesco a leggere solamente i numeri, ma carattere per carattere... per adesso il programma si comporta nel seguente modo: 1) importa i dati e memorizza ogni singolo carattere in ogni cella dell'array "numeri" di tipo char. 2)divide tutta la stringa in "tok" ogni volta che trova il carattere spazio e memorizza tutti i tok in ogni cella dell'array "vettoreint" convertendoli prima in formato int. conoscete qualche metodo più elegante per fare il medesimo lavoro? Ultima modifica di M.A.W. 1968 : 24-01-2010 a 01:20. |
|
|
|
|
|
#7 (permalink) |
|
Moderatore Globale ![]() ![]()
319 Messaggi
![]() ![]() ![]() |
Ho buttato giù brevemente una possibile infrastruttura di test per sviluppare il discorso.
codice:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#define BUFF_SIZE 128
#define MAX_NUMERI 100
#define DELIMS " \t\n\r"
int PopolaArray1(const char *Buff, int *Array, const int Limite)
{
int i = 0;
char *p;
/*
Ai soli fini del test: la strtok() non è priva
di side effects, mentre a noi occorre riusare Buff.
*/
char *b = strdup(Buff);
p = strtok(b, DELIMS);
while ((NULL != p) && (i < Limite))
{
Array[i++] = atoi(p);
p = strtok(NULL, DELIMS);
}
return (i);
}
int PopolaArray2(const char *Buff, int *Array, const int Limite)
{
int i = 0;
int val = atoi(Buff);
/*
La atoi è molto potente anche da sola, ma ha una
notevole limitazione...
*/
while (0 != val)
{
Array[i++] = val;
while (isdigit(*Buff++));
val = atoi(Buff);
}
return (i);
}
int PopolaArray3(const char *Buff, int *Array, const int Limite)
{
return (0);
}
void StampaArray(int *Array, int Limite)
{
int i;
printf("# L'array letto contiene %d interi:\n", Limite);
for (i = 0; i < Limite; ++i)
{
printf("Array[%d] = %d\n", i, Array[i]);
}
}
int main(void)
{
FILE *fin;
char buff[BUFF_SIZE];
int numeri[MAX_NUMERI];
int tot_numeri;
puts("# Apertura del file");
fin = fopen("prova.txt", "r");
if (NULL == fin)
{
fputs("Errore durante l'apertura del file !", stderr);
return (1);
}
if (NULL == fgets(buff, BUFF_SIZE, fin))
{
fputs("Errore di lettura dal file !", stderr);
return (2);
}
fclose(fin);
printf("\n# Lettura, metodo 1\n# Buffer: [%s]\n", buff);
tot_numeri = PopolaArray1(buff, numeri, MAX_NUMERI);
if (tot_numeri)
{
StampaArray(numeri, tot_numeri);
}
printf("\n# Lettura, metodo 2\n# Buffer: [%s]\n", buff);
tot_numeri = PopolaArray2(buff, numeri, MAX_NUMERI);
if (tot_numeri)
{
StampaArray(numeri, tot_numeri);
}
printf("\n# Lettura, metodo 3\n# Buffer: [%s]\n", buff);
tot_numeri = PopolaArray3(buff, numeri, MAX_NUMERI);
if (tot_numeri)
{
StampaArray(numeri, tot_numeri);
}
getchar();
return (0);
}
In generale quindi si tende a separare i numeri tramite CR/LF (uno per riga), oppure usando quantità predefinite di caratteri di interpunzione come ';' o tabulazioni '\t', si cerca inoltre di comunicare all'inizio del file o per ogni linea quanti sono i dati (questo evita il ricorso a pesanti e macchinosi parser a due step)... Soprattutto, si tende ad usare file di dati in formati binari ben strutturati e non semplici file ASCII, ovunque possibile. Illustrare un sia pur semplice parser numerico talmente robusto da "macinare" senza errori le peggiori schifezze che l'utonto riesce ad infilare in un banale file di testo "delimited" va decisamente al di là delle possibilità del forum. Tuttavia, si possono prendere in considerazione un paio di soluzioni di base, che comunque - per robustezza, e stante la natura sostanzialmente low level del C - non possono esimersi dal procedere carattere per carattere nell'analisi del buffer di input. La terza soluzione, lasciata come semplice esercizio per il lettore interessato, prevede l'uso di sscanf().
__________________
Tutti gli utenti sono pregati di prendere visione del Regolamento del Forum e di rispettarlo. • "Die ganzen Zahlen hat der liebe Gott gemacht, alles andere ist Menschenwerk." (Leopold Kronecker) • "A Mathematician is a machine for turning coffee into theorems." (Pal Erdös) • Un plauso a Grisha Perelman, raro esempio di genuino anticonformismo umano e scientifico. |
|
|
|
|
|
#8 (permalink) |
|
Utente della community ![]() ![]()
219 Messaggi
![]() |
Ciao !
Oltre a quanto consigliato da M.A.W. 1968, potresti ricorrere alla comoda fscanf(); Se sai già quanti elementi ci sono nel file, e di che tipo (mi pare che sia il tuo caso), puoi impostare la fscanf() in modo che ti legga tutti i valori con una sola chiamata, quindi una cosa del tipo : codice:
fscanf(f,"%d %d %d %d %d %d %d",&numeri[0],numeri[1],numeri[2],numeri[3],numeri[4],numeri[5],numeri[6]); codice:
for(int i=0;!feof(f);++i){fscanf(f,"%d",&numeri[i]);}
Tuttavia una alternativa molto elastica potrebbe essere lo std::vector<> Lo std::vector è un vettore dinamico sul quale puoi con dei metodi appositi aggiungere o eliminare dinamicamente degli oggetti dalla coda del suddetto (inclusi quindi anche gli interi). Questo signigica che anche se non sai a priori quanti elementi dovrai caricare, puoi inserirglieli passo passo in una for, e farti stampare successivamente il contenuto trattandolo esattamente come un array convenzionale. Una cosa del tipo: codice:
#include<vector>
std::vector<int> numeri;
bool LeggiValori(char *path)
{
FILE *in=NULL;
if(!(in=fopen(path,"rt"))){return false;}
while(!feof(in))
{
int n;
fscanf(in,"%d",&n);
numeri.push_back(n);
}
fclose(in);
return true;
}
void StampaValori()
{
for(int i=0;i<numeri.size();++i){printf("elemento[%d] = %d\n",i,numeri[i]);}
}
void FastStampaValori()//versione ottimizzata della StampaValori() con l'ausilio degli iteratori
{
for(std::vector<int>::iterator it=numeri.begin();it!=numeri.end;++it){printf("%d\n",*it);}
}
E un buon reference sullo std::vector: vector - C++ Reference Spero di essere stato utile ![]() Ciao ! ps: Ho notato che la discussione a preso piega sul fatto di leggere i dati come caratteri (char %c), e convertirli poi ad interi (con l' atoi() consigliata da M.A.W.), tuttavia non ho capito se è proprio voluto o non riuscivi a farlo direttamente leggendoli come interi ... Nel caso chiedo scusa per il fraintendimento ![]()
__________________
__________________________________________________ ___________________ La programmazione è uno dei tanti modi di esprimere la propria creatività, ed è un'arte. In questo siamo comuni, dai pittori ai poeti, dagli scultori fino ai programmatori ... Di mente siamo completamente diversi, ma di anima siamo tutti CREATIVI ![]() Firmato : -Xardas Black Raven- Ultima modifica di xardas : 24-01-2010 a 13:33. |
|
|
|
|
|
#9 (permalink) |
|
Moderatore Globale ![]() ![]()
319 Messaggi
![]() ![]() ![]() |
Attenzione: la fscanf() assieme a sua cugina scanf(), è fortemente deprecata e non deve essere utilizzata.
La soluzione da te proposta, appropriatamente modificata per l'uso di sscanf(), costituisce in pratica una soluzione all'esercizio sopra assegnato per il terzo metodo di lettura. Allo stesso modo, l'utilizzo della sola feof() come condizione di permanenza in un loop può riservare delle sorprese (tipicamente letture duplicate) poiché la sua modalità di funzionamento implica una lettura oltre la fine del file. Infine "l'algoritmo di conteggio" al quale alludi è solo una dellle tante varianti basate su strtok() o su un parser ad hoc, e costituisce esattamente "il primo passo" di un parser a due step del quale accennavo sopra. Last, but not least: si parla di C, non hanno attinenza metodi e classi del C++. ![]()
__________________
Tutti gli utenti sono pregati di prendere visione del Regolamento del Forum e di rispettarlo. • "Die ganzen Zahlen hat der liebe Gott gemacht, alles andere ist Menschenwerk." (Leopold Kronecker) • "A Mathematician is a machine for turning coffee into theorems." (Pal Erdös) • Un plauso a Grisha Perelman, raro esempio di genuino anticonformismo umano e scientifico. |
|
|
|
|
|
#10 (permalink) |
|
Utente della community ![]() ![]()
219 Messaggi
![]() |
Beh, me la sono cercata... non avrei dovuto intromettermi
![]() Riguardo alla fscanf() e scanf() non sapevo fossero deprecate, le ho sempre usate senza problemi. ![]() Ad ogni modo l'ho voluta proporre perchè mi pare di aver capito che il problema di Simonemigliore sia che non riesce a caricare i numeri come formato int, ma solamente come carattere. Inoltre credo che i dati nel suo file file siano disposti ordinatamente, e il fatto di partire a leggere carattere per carattere rilevando gli spazi non sia per un fatto di 'parsing', ma una sorta di soluzione che a provato a mettere in atto non riuscendo a leggere direttamente i numeri come int. Non sono però sicuro di queste affermazioni, e come ho detto anche a fine del mio precedente post, aspettiamo conferma da parte di Simonemigliore ... Anche riguardo al linguaggio, avevo appunto notato che la discussione avesse preso piega sul C, ma dato che Simonemigliore non mi pare abbia specificato di stare programmando in C (ne da titolo, ne da suo primo post) ho pensato che non sarebbe stato un problema fornire soluzioni in parte di C++. (che si rivelano piuttosto comode) Ad ogni modo anche qui non sono sicuro, forse ho visto male io ... Da quel che ho capito poi questa discussione era stata attaccata in una del 2006, quindi forse era stato specificato prima che venisse correttamente tagliata. Spero solo che alcune soluzioni da me proposte possano tornare utili. Magari modificandole come ha suggerito M.A.W. 1968 ![]() Non mi resta che augurarvi buona continuazione. Ciao ! ![]()
__________________
__________________________________________________ ___________________ La programmazione è uno dei tanti modi di esprimere la propria creatività, ed è un'arte. In questo siamo comuni, dai pittori ai poeti, dagli scultori fino ai programmatori ... Di mente siamo completamente diversi, ma di anima siamo tutti CREATIVI ![]() Firmato : -Xardas Black Raven- |
|
|
|
![]() |
| Strumenti della discussione | |
| Modalità di visualizzazione | |
|
|
Tutti gli orari sono GMT +1. Attualmente sono le 17:36.
















Modalità lineare

