Newsgroup: it.comp.lang.c++
Titolo: Errore Windows

Ciao a tutti.
Sono un programmatore VB6 e php ma, avendo bisogno di "una marcia in più" 
nella velocità, stavo cercando di realizzare un programmino da interfacciare 
al mio VB6.
Stavo tentando di caricare dei dati in un array e ho cominciato con la 
lettura di un archivio di testo.
Il sottostante codice mi dà un errore windows. Cosa c'è che non va?
#include <stdio.h>
#include <iostream.h>
int main(int argc, char *argv[])
{
int pippo;
int x;
int conta_righe;
char rigo;
int est[5000];
  FILE *afile;
  afile=fopen("archivio.txt","r");
  char c;
  while(c!=EOF)
  {
  conta_righe+=1;
  for (x==1;x<119;x++)
  {
      c=fgetc(afile);
       est[conta_righe] += c;
      rigo+=c;
  }
  cout<<est[conta_righe];
  }
  fclose(afile);
  cin>>pippo;
  return 0;
} 

   for (x==1;x<119;x++)
Tanto per cominciare dovrebbe essere x=1 e non x==1, il primo
rappresenta l'assegnazione mentre il secondo è un operatore booleano,
che in questo caso non serve a nulla.
Poi sappi che non stai contando righe, ma caratteri e, dato che usi un
array a dimensioni fisse di 5.000, non puoi leggere più di 5.000
caratteri da file senza andare in overflow.
Ah, tra l'altro, al primo ciclo la variabile "c" non è inzializzata.
Bye,
Andrea.

 caratteri da file senza andare in overflow.
Scusa, errore mio: stai contando misteriose righe di lunghezza 118 :P
Poi, dato che sommi tutti i caratteri di una "riga" per metterli
nell'array est[conta_righe] hai un limite di 5.000 righe, dico bene?
Andrea.

 ha scritto 
nel messaggio news:ecbtgm$p4m$2...@nnrp-beta.newsland.it...


esattamente.
Adesso provo a togliere ==
Grazie

 ha scritto 
nel messaggio news:ecbt9v$p4m$1...@nnrp-beta.newsland.it...
Salvatore Paci wrote:
Ah, tra l'altro, al primo ciclo la variabile "c" non č inzializzata.
La variabile c č inizializzata (char c;)
comunque, pur modificando il codice nel seguente modo...l'errore rimane :(((
#include <stdio.h>
#include <iostream.h>
int main(int argc, char *argv[])
{
int pippo;
int x;
int conta_righe;
char rigo;
  char c;
  int est[5000];
  FILE *afile;
  afile=fopen("archivio.txt","r");
  while(c!=EOF)
  {
  conta_righe+=1;
  for (x=1;x<119;x++)
  {
      c=fgetc(afile);
       est[conta_righe] += c;
      rigo+=c;
  }
  cout<<est[conta_righe];
  }
  fclose(afile);
  cin>>pippo;
  return 0;
}
Bye,
Andrea. 

 comunque, pur modificando il codice nel seguente modo...l'errore rimane :(((
Perche non leggi le righe intere con fgets() che è meglio? Nei tuoi 118
caratteri consideri anche i CR+LF? Sicuro che il tuo file non superi le
5.000 righe?
Ma soprattutto, ora che me ne rendo conto: la tua variabile conta_righe
non è inizializzata!!! Impostala a 0 se no è logico che quando accedi
all'array vai a disturbare la povera memoria a cui non hai accesso! Per
scrupolo magari controlla anche che si apra bene il file uscendo se
afile è == NULL dopo la fopen().
Andrea.

 Il sottostante codice mi dà un errore windows. Cosa c'è che non va?
Chi fa da sé fa per tre.
Hai due metodi:
1) costruisci un modello formale per il paradigma imperativo e cerchi di 
dimostrare che il programma è corretto (metodo sconsigliato).
2) usi un debugger (metodo consigliato).
Non si può pretendere di trovare l'errore semplicemente leggendo il 
codice, specialmente se complesso (e questo dipende dalle informazioni 
contenute nel codice e dalla preparazione/intelligenza di una persona).
Kiuhnm

 
A cosa ti servono poi "rigo" e "est[]"?
N.B. invece di fopen, fgetc e fclose (piu' C che C++) potresti usare gli 
fstream.
Dunque, vediamo se ho capito (ho un po' di febbre, quindi scusate se 
scrivo castronerie):
hai un file di testo con righe di 118 caratteri
e per ogni riga vuoi calcolare la somma dei valori ascii dei suoi caratteri?
-- 
Roal Zanazzi

 
NO, non e' inizializzata. Inizializzare una variabile vuol dire 
assegnarle un valore:
int pippo = 42;
-- 
Roal Zanazzi

 e per ogni riga vuoi calcolare la somma dei valori ascii dei suoi
caratteri?
No!
Voglio stampare ogni riga.
Ti spiego:
non sapendo programmare in C++ ( ci sto provando adesso) volevo inizare "a
poco a poco"
il risultato che vorrei ottenere è questo:
ho 5000 righe di 118 caratteri ciascuna
0501194587340159501817454982204332475733622532370411202118114532268308802418
420249791710525461124134861571400000000000
Vorrei caricare i dati in un array che, in VB6 è Est(1 to 5000, 11, 1 to 5)
as integer
Est(1,0,1) = 05  (le prime due cifre rappresentano il giorno)
Est(1,0,2) = 01 (il mese)
Est(1,0,3) = 1945 (l'anno)
Est(1,1,1) = 87 (primo estratto di bari)
ecc
ecc

 as integer
ah, quindi lo allochi da dentro il runtime di VB6 e lo passi 
alla routine C++.
A meno che non usi .net e dati managed vari, prendi atto delle 
profonde differenze (non semantiche di accesso, ma di 
implementazione interna) tra un array C++ (e C) e uno di VB.
In VB quando allochi un array, in realtà crei un contenitore 
piuttosto complesso, definito dallo standard di OLE2 (in vb6). 
Studiati bene cos'è effettivamente un array secondo OLE2 (è una 
struct con vari livelli di indirezione prima di giungere ai dati 
effettivi, e neppure una struct monolitica, dove stanno i veri 
dati, etc).
In C++ un'array è un oggetto di memoria (monolitico) molto 
semplice, dato che non ha infrastrutture intorno.
Ma se fai colloquiare i due, procedi con cautela. In particolare 
o decidi di aderire a OLE2 anche dentro il codice C++, oppure 
rinuncia a ridimensionare, spostare etc.
Se poi vuoi allocare memoria nello heap C++ e passarla al 
chiamante VB6, i casini sono anche peggio, perchè tutto sommato 
da C++ puoi vedere i dati esterni come preferisci, ma VB6 non 
puà vedere un array del C++ come tale. Allora devi ritornare il 
puntatore, la dimensione, e in VB allocare una copia a parte e 
andare subito di memcopy il più presto possibile (salvo il 
problema di chi si occuperà mai di liberare la memoria dello 
Heap C++ non più utile).
Penso però che siamo OT.
Sul NG di visual basic ci sono molti che fanno questi giochetti 
agevolmente, ti aiuteranno di più.
ciao
Soviet


 C++.
Mi dispiace che ti ho fatto perdere tutto questo tempo visto che, 
probabilmente, non sono stato molto felice nella spiegazione.
Io non voglio passare alcun array
voglio:
caricare in un array di c++ alcuni dati (leggendoli da un file di testo)
elaborarli
scriverli in un file di testo che poi verrà letto da VB6
il mio problema è caricare un array multidimensionale del tipo Est(1 to 


 concetto).
****
non è un problema di concetto.
con VB6 mi faccio pure il caffè :)))
il problema è che non so tradurre in c++
comandi
apri il file archivio.txt
riga = la prima riga
incremento contatore
est[contatore][0][1] = primi due caratteri della riga 'in VB sarebbe 
mid(riga,1,2) ma in C++ come si fa?
est[contatore][0][2] = terzo e quarto carattere della riga
ecc
ecc
il tutto fino a quando finisce il file
il codice che sto per allegare mi dà come errore "request for member 
'substr' which is non-aggregate type 'char'"
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
int main() {
    ifstream file("archivio.txt");
    string temp;
    char c;
    char pippo;
    int conta;
    int est[5001][11][6];
    while((c = file.get()) != EOF) {
    conta = conta + 1;
    est[conta][0][1] = c.substr(0,2);
    cout<<est[conta][0][1];
        }
    cin>>pippo;
    return 0;
}

 
Il codice seguente legge un file di testo (NON binario!)
una riga alla volta fino alla fine,
tiene il conteggio delle righe
e scrive su cout i primi 2 caratteri di ogni riga, senza interruzione 
(newline).
N.B.
line.substr(0,2)
restituisce una std::string, che e' diverso da char[2].
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
int main()
{
	ifstream file("archivio.txt");
	if(!file)
	{
		cerr << "Oops, non riesco ad aprire il file!" << endl;
		return 1;
	}
	int line_count = 0;
	string line;
	while(!file.eof())
	{
		++line_count;
		getline(file, line);
		cout << line.substr(0,2);
	}
	char pippo;
	cin >> pippo;
	return 0;
}
-- 
Roal Zanazzi

 ha scritto nel messaggio
news:44eb60d3$0$13719$5fc...@news.tiscali.it...
Sto facendo tesoro di quanto mi hai scritto.
Stanotte farò delle prove e ti (VI) farò sapere.
Intanto...grazie 1000

Sono partito dal tuo codice.
Il seguente listato produce un XXX=17 che č corretto.
Infatti la 3774^ riga contiene come primi due caratteri proprio 17
se invece di
est[conto][0][1] = line.substr(0,2);
scrivo
est[conto][0][1] = line.substr(2,2);
non funziona + nulla. Perché?
Anche se scrivo est[conto][0][2] = line.substr(0,2); non funziona piů nulla.
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
int main()
{
ifstream file("archivio.txt");
if(!file)
{
cerr << "Oops, non riesco ad aprire il file!" << endl;
return 1;
}
int line_count = 0;
string line;
int conto;
conto=0;
string est[5001][11][6];
while(!file.eof())
{
++line_count;
conto = conto + 1;
getline(file, line);
//cout << line.substr(2,2)<<"\r\n";
//est[conto][0][1] = line.substr(0,2);
est[conto][0][1] = line.substr(0,2);
}
char pippo;
cout<<"xxx="<<est[3774][0][1];
cin >> pippo;
return 0;
}

errato corrige
se scrivo se scrivo est[conto][0][2] = line.substr(0,2); e stampo
est[conto][0][2] = line.substr(0,2); FUNZIONA

 
Bene, sono felice che funzioni, ma ancora non ho capito csa vuoi ottenere...
-- 
Roal Zanazzi

 ha scritto nel messaggio
news:44ecb248$0$13729$5fc...@news.tiscali.it...


 
La domanda che dovresti porti e':
perche' i dati in memoria ti servono sotto forma di array 
multidimensionali (che in C++ forse ti sarai accorto, sono BEN diversi 
da Visual Basic)?
Non sarebbe molto piu' comodo pensare e mettere in pratica un livello di 
astrazione un pochino piu' elevato e:
- definire una struttura che contenga tutti i dati per un giorno (come 
fosse un record di una tabella su database), esempio (scusa per 
l'inglese, e' abitudine):
struct DataItem
{
	unsigned short day;
	unsigned short month;
	short year;
	<tipo dato> dataserie[55];
	// oppure puoi separare dataserie in 11 array...
};
- implementare una funzione che riceve in input una stringa 
corrispondente alla riga su file, ne fa il parsing e restituisce un 
"oggetto" di tipo DataItem.
- dichiarare un oggetto "contenitore" per tutti i DataItem letti dal 
file, esempio:
std::vector<DataItem> DataList;
Questo e' uno dei tanti modi, ma devi essere tu a pensare come sarebbe 
meglio strutturare i dati per velocizzare le successive analisi.
Ad esempio, se l'analisi dei dati necessita di una indicizzazione veloce 
per data sarebbe piu' opportuna una std::map<> con la data (composta in 
qualche modo ordinabile) come chiave e i 55 dati come valore.
Un errore purtroppo diffuso e' quello di tentare di scrivere codice in 
un linguaggio B (C++) come se si stesse programmando con il linguaggio A 
(Visual Basic). Cosi' si ottengono il piu' delle volte dei risultati 
fallimentari ("Il C++ non e' poi tanto piu' veloce di Visual Basic!"... 
Palle! Se fai le cose male non puoi ottenere risultati accettabili).
-- 
Roal Zanazzi

 Visual Basic)?
***
Me ne sono accorto!
Tempo fa avevo utilizzato Delphi per questo lavoro.
Mi accorsi subito che gli array con Delphi erano ESATTAMENTE AL CONTRARIO 
rispetto a VB
est(1,2,3) diventava est[3,2,1] però.... tutto sommato... Caricando al volo 
il file binario nell'array...tutto andava bene.
ecco quella parte di codice:
begin
//form1.Visible := False;
  AssignFile(F,'archivio.dat');
  Reset(F,1);
  BlockRead(F,Estrasioni,sizeof(Estrasioni));
  CloseFile(F);
  for x := 1 to 5000 do
   begin
      for y := 0 to 10 do
        begin
          for z := 1 to 5 do
            begin
              Estrazioni[x,y,z] := Estrasioni[z,y,x];
              //ShowMessage(inttostr(estrasioni[z,y,x]));
            end;
        end;
    end;
Adesso con C++ ho una serie di problemi.
Esempio:
Oltre al grande libro che è Internet...ho comprato
Guida al C++ di Herbert Schildt (McGrawHill)
cercavo il corrispondente in C++ della funzione VB mid(stringa,1,2)
che parte dalla stringa, comincia dal carattere 1 e prende 2 elementi.
Ebbene... nel libro non esiste.
Si parla di strcpy() esempio riportato strcpy(str,"ciao");
di strcmp()
di strlen() e...
e..
e... basta!
Non c'è altro sulle operazioni sulle stringhe.

 lettura di un archivio di testo.
Per velocizzare un programma Visual Basic con una routine scritta in 
C++, ti consiglio di non scrivere un intero programma in C++, ma di 
scrivere una DLL in C++, che puoi richiamare dal programma VB.
In tal modo, eviti il problema di scambiare i dati tra i due programmi, 
e rendi piu' veloce lo scambio di dati.
Per passare un array da VB a C++ basta passare il primo elemento per 
riferimento dalla parte di VB e ricevere un puntatore dalla parte del C++.
-- 
     Carlo Milanesi
 
http://digilander.libero.it/carlmila

 
'azz... fa cosi' schifo? Non immaginavo fino a questo punto.
in C++:
#include <string>
std::string tutto("ciao mondo");
std::string pezzo = tutto.substr(5, 2); // pezzo == "mo"
in C (che puoi usare anche in C++):
#include <string.h>
char* tutto = "ciao mondo";
char pezzo[3];
strncpy(&tutto[5], pezzo, 2);
pezzo[2] = '\0'; // le "stringhe" char* devono essere terminate con 0
Su internet trovi tutto, basta cercare.
Ad esempio: 
www.cppreference.com
 o 
www.cplusplus.com
, tanto per iniziare.
Il problema maggiore, ripeto, e' NON pretendere di programmare in C++ 
come fosse VB.
E finalmente ho capito cosa sono quei dati: storici delle estrazioni del 
lotto! :-P
-- 
Roal Zanazzi

 forse, purtroppo, piu' pubblicizzati).
Mi potresti consigliare un ottimo libro su C++?
Se non è un mattone da 2000 pagine è meglio ancora.
Ciao

 Se non è un mattone da 2000 pagine è meglio ancora.
http://www.emagsoftware.it/faqcpp.htm#7
EMG
--
EMAG Software Homepage:     
http://www.emagsoftware.it
The EMG's ZX-Spectrum Page: 
http://www.emagsoftware.it/spectrum
The Best of Spectrum Games: 
http://www.emagsoftware.it/tbosg
The EMG Music page:         
http://www.emagsoftware.it/emgmusic
 

 Mi potresti consigliare un ottimo libro su C++?
Penso che Thinking in C++ di Bruce Eckel non sia male. Cercalo su
google, è scaricabile liberamente.
Andrea.

 ha scritto
nel messaggio news:ecmntp$mtn$1...@nnrp-beta.newsland.it...


 ***
Ho pensato fosse giusto riportare il frutto dei miei sforzi. Si tratta
soltanto di caricare su un array un archivio composto da N righe di 118
caratteri ciascuna:
#include <string>
#include <iostream>
#include <fstream>
int main()
{
int indice_estrazione = 0;
int ruota = 1;
int i = 0;
int conta_carattere = 0;
int conta_estratti = 0;
int estratto;
int ultima_estrazione;
string pluto;
string est[5001][12][6];
ifstream inputFile;
inputFile.open("archivio.txt");
string s;
while (!inputFile.eof()) {
      inputFile >> s;
      if(!inputFile.eof())
      indice_estrazione++;
      est[indice_estrazione][0][1] = s.substr(0,2);
      est[indice_estrazione][0][2] = s.substr(2,2);
      est[indice_estrazione][0][3] = s.substr(4,4);
      for(ruota = 1; ruota < 12; ruota++){
      for(estratto = 1; estratto < 6; estratto++){
      est[indice_estrazione][ruota][estratto] = s.substr(ruota * 10 +
estratto * 2 - 4,2);
      }
      }
}
inputFile.close();
ultima_estrazione = indice_estrazione;
//cout << est[3780][11][1] << "." << est[3780][11][2] << "." <<
est[3780][11][3] << "." << est[3780][11][4] << "." << est[3780][11][5];
//cin >> pluto;
  return 0;
}