[ Anders Jensen ]
[ snip ]
> > > ofstream t_fil("TEMPUS FUGI.DAT,ios::trunc");
> > ^^ ^^ ^^
> > Dette vil ikke kompilere engang.
>
> Det kompiles fint under VC++ 6.0
Ah, riktig, så du *vil* lage en fil med navnet:
TEMPUS FUGI.DAT,ios::trunc
i tillegg til å ignorere std::. Beklager, jeg antok at du ville
trunkere filen dersom den fantes fra før av.
> Hele fuktionen er: (Undskyld skrivemåden)
Er det _så_ vanskelig å omformattere koden litegrann? Sånn at de
vanlige dødelige kan lese denne IOCCC kandidaten?
> void SKRIV_EN_FIL(void)
> {int x ;double a,b,ab;ab=5;
Definisjonen av ab var *ikke* med i den opprinnelige artikkelen.
Forstår du hvorfor det er viktig å formattere koden noenlunde
akseptabelt?
> x=0;ofstream t_fil("TEMPUS FUGI.DAT,ios::trunc");
> while (x!=10){ cin>>a>>b;if (cin.fail()){x=10;cout<<x;}
> else {t_fil.write((char *)&a,sizeof(ab));
> t_fil.write((char *)&b,sizeof(ab));}
Hvorfor oppgir du størrelsen av et annet objekt enn det du faktisk
skriver ut?
> }cout<<" slut "<<endl;cin.clear(0);}
For de mistroiske:
$ g++ bar.cpp
bar.cpp: In function `void SKRIV_EN_FIL()':
bar.cpp:7: `ofstream' undeclared (first use this function)
bar.cpp:7: (Each undeclared identifier is reported only once for each function
it appears in.)
bar.cpp:7: parse error before `(' token
bar.cpp:8: `cin' undeclared (first use this function)
bar.cpp:8: `cout' undeclared (first use this function)
bar.cpp:9: `t_fil' undeclared (first use this function)
bar.cpp:11: `endl' undeclared (first use this function)
Hvorfor nekter folk for det opplagte? Og dertil har du rettet opp noen
av feilene i den opprinnelige artikkelen. Nei, snutten kompileres ikke
(hva VC++ måtte akseptere får være dens sak. Heller ikke kompilatoren
var spesifisert i den opprinnelige artikkelen (ikke at det har noe å
si for svaret)).
[snip min kommentar til "t_fil.write((char *)&a,sizeof(ab)"]
> > skal dette gi mening?
>
> Ja - Faktisk
> Når man kommer ind i løkken kan man indskrive double-værdier i
> filen.
Ja, det er nå så. Men hvorfor kan ikke du skrive:
t_fil.write( (char *)&a, sizeof a );
heller enn å bruke størrelsen på en variabel som ikke har noe med a å
gjøre? Hva er vitsen med å ha variabelen ab som ikke skal brukes i
koden?
> Indtil der indtastes f.eks et bogstav, hvorefter man springer ud .
> Det fungere fint - Problemet er at funktionen kun virker en gang -
> Formodenligt pga cin.
Delvis, ja. Generelt: streams i C++ er ikke akkurat det jeg ville
kalle "enkelt". En meget omstendig og bra bok som forklarer hvordan
alt henger sammen er denne:
<URL:
http://www.langer.camelot.de/iostreams.htm>
Ta en titt.
> > kallet på fail() setter _aldri_ noen feilbit (kallet på fail()
> > returnerer true dersom failbit eller badbit er satt). Hvis du vil lese
> > så lenge begge disse betingelsene:
> >
> > 1) det er noe å lese igjen
> > 2) det er ikke oppstått feil under innlesing av elementene
>
> > er oppfylt, så er det basic_ios:
erator!()/basic_ios:
erator
> > void*() man bruker, slik jeg antydet over.
>
> Men det er jo netop meningen, at det skal opstår en fejl under
> indlæsning -så løkken brydes-Problemet opstår først når man vender
> tilbage for, at genbruge funktionen.
Ah, greit. Jeg gikk glipp av at funksjonen skulle kunne kalles flere
ganger.
Idet en man prøver å lese det første tegnet fra en stream og man
prøver å konvertere det tegnet til en double og det ikke går, settes
tilstanden til "fail" og tegnet forblir i input-bufferet. Neste gang
funksjonen kalles skjer nøyaktig det samme, da den feilaktige input'en
ikke ble fjernet (det "feilaktige" tegnet vil fremdeles være det som
leses først ved neste forsøk). Dersom man har linjevis input (hvilket
skjer ofte ved bruken av std::cin) går det an å ignorere all input
fram til og med '\n'. Dersom input'en ikke er linjebasert er det litt
mer vanskelig å si hva man skal "hoppe over".
Man kan gjøre ting fx. slik (ikke idiotsikkert, men det burde gi en
pekepinne):
$ cat zot.cpp
/*
*
* $Id$
*
* Copyright (C) 2001 by Igor V. Rafienko, <igorr@ifi.uio.no>
*
*/
#include <iostream>
#include <string>
#include <sstream>
#include <climits>
#include <fstream>
template <typename To, typename From>
To stream_cast(From const& from) {
std::stringstream stream;
stream << from;
To to;
stream >> to;
return to;
}
void
writeToFile( const std::string &name, std::istream &is )
{
using namespace std;
cout << "\tprocessing: " << name << endl;
ofstream ofs( name.c_str(), ios_base::trunc );
if ( !ofs )
exit( 1 );
double a, b;
while ( is >> a >> b ) {
ofs.write( (char*)&a, sizeof a );
ofs.write( (char*)&b, sizeof b );
}
ofs.flush();
ofs.close();
if ( is.fail() ) {
cerr << "stream failed";
// reached end of data while reading
if ( is.eof() ) {
cerr << " because of read past EOF\n";
is.clear();
}
// conversion failed. Ignore til end-of-line
else {
cerr << " because of erroneous input (ignoring)\n";
is.clear();
is.ignore( INT_MAX, '\n' ); // Mogens: ja, jeg er lat
}
}
else if ( is.bad() ) {
// stream is corrupted internally
cerr << "unrecoverable error while reading\n";
exit( 2 );
}
cout << "\tdone with: " << name << endl;
}
int
main( int argc, char *argv[] )
{
using namespace std;
int limit = stream_cast< int >( argv[ 1 ] ? argv[ 1 ] : "3" );
for ( int i = 0; i != limit; ++i ) {
string s = stream_cast< string >( i );
writeToFile( "datafile" + s, cin );
}
}
$ g++ zot.cpp
$ ./a.out 3
processing: datafile0
1 2
3 4
asdasd
stream failed because of erroneous input (ignoring)
done with: datafile0
processing: datafile1
5 6
stream failed because of read past EOF
done with: datafile1
processing: datafile2
8 9
stream failed because of read past EOF
done with: datafile2
$ ls -l datafile*
-rw------- 1 igorr igorr 32 Jul 31 18:58 datafile0
-rw------- 1 igorr igorr 16 Jul 31 18:58 datafile1
-rw------- 1 igorr igorr 16 Jul 31 18:58 datafile2
$
Jeg er ganske sikker på at det var et tilfelle jeg har glemt når det
gjelder håndtering av årsaker til hvorfor input fra is feil'et, men
ok, la gå.
> > Det er vanskelig å svare når du ikke engang har forklart hva du
> > vil oppnå. Det at koden kan _umulig_ kompileres gjør ikke saken
> > enklere.
>
> Det kan den altså........
Hvis jeg siterer standarden, vil du tro meg da? Koden som du oppga
trenger ikke å kunne kompileres. Og det gjør den ikke heller på en
rekke kompilatorer. "Det kan den altså" ikke.
> > > 2 ) Ved datainput cin>>a>>b skiftes der linie ved hvert enter,
> > > hvorledes undgårs det ???
> >
> > Hvorfor vil du ha det?
>
> Tro det eller lad være - Men det var for at få udskriften til "å se
> litt mindre jævlig ut "
Utskriften? Hva har input fra std::cin med _utskrift_ å gjøre?
*forvirret*...
ivr
--
You'd feel bad about not having a social life if only you could remember
what it was like to have one.
IB stress descriptors