/ Forside / Teknologi / Udvikling / C/C++ / Nyhedsindlæg
Login
Glemt dit kodeord?
Brugernavn

Kodeord


Reklame
Top 10 brugere
C/C++
#NavnPoint
BertelBra.. 2425
pmbruun 695
Master_of.. 501
jdjespers.. 500
kyllekylle 500
Bech_bb 500
scootergr.. 300
gibson 300
molokyle 287
10  strarup 270
C++: Læsning og sammenligning
Fra : Bertel Lund Hansen


Dato : 19-09-04 12:58

Hej alle

Jeg skal læse i en fil, men for at finde det rigtige sted at
starte, skal jeg lede efter en given sekvens af tal, nemlig
0 25 0 0 2.

Jeg har prøvet med:

const string NEWMESSAGE = "\0\0x19\0\0\2";

string linje(NEWMESSAGE.length(),' ');
char ch[1];

while (linje!=NEWMESSAGE) {
groupfile.read(ch,1);
linje=linje.substr(1,4)+ch;
}

men det ser ikke ud til at virke.
Er jeg nødt til at teste værdierne én ad gangen?

--
Bertel
http://bertel.lundhansen.dk/   FIDUSO: http://fiduso.dk/

 
 
Bertel Brander (19-09-2004)
Kommentar
Fra : Bertel Brander


Dato : 19-09-04 13:45

Bertel Lund Hansen wrote:
>
> men det ser ikke ud til at virke.
> Er jeg nødt til at teste værdierne én ad gangen?
>

Problemet er at man ikke kan bruge std::string's !=
operator med andet end '\0' terminerede strenge.
Operatoren vil stoppe når den ser den første '\0'
hvilket er første tegn i dit tilfælde.

Du kan bruge en memcmp sammen med et array eller en vector.

--
What's in a name?
That which we call a rose by any other name would smell as sweet.
- Juliet
http://home20.inet.tele.dk/midgaard/

Anders J. Munch (19-09-2004)
Kommentar
Fra : Anders J. Munch


Dato : 19-09-04 14:40

"Bertel Brander" <bertel@post4.tele.dk> skrev:
> Bertel Lund Hansen wrote:
> >
> > men det ser ikke ud til at virke.
> > Er jeg nødt til at teste værdierne én ad gangen?
> >
>
> Problemet er at man ikke kan bruge std::string's !=
> operator med andet end '\0' terminerede strenge.
> Operatoren vil stoppe når den ser den første '\0'
> hvilket er første tegn i dit tilfælde.

Forkert. Man kan sagtens sammenligne std::string der indeholder '\0'
tegn. Hvis din implementation bruger strcmp, så har den en bug.

Konstruktion fra en nul-termineret streng er en anden sag. Bertel,
prøv at erstatte

> const string NEWMESSAGE = "\0\0x19\0\0\2";

med:

const char newmessage_c[] = {0,25,0,0,2};
const string NEWMESSAGE(newmessage_c, sizeof(newmessage_c));

mvh. Anders



Bertel Brander (19-09-2004)
Kommentar
Fra : Bertel Brander


Dato : 19-09-04 16:59

Anders J. Munch wrote:
> "Bertel Brander" <bertel@post4.tele.dk> skrev:
>
>>Bertel Lund Hansen wrote:
>>
>>>men det ser ikke ud til at virke.
>>>Er jeg nødt til at teste værdierne én ad gangen?
>>>
>>
>>Problemet er at man ikke kan bruge std::string's !=
>>operator med andet end '\0' terminerede strenge.
>>Operatoren vil stoppe når den ser den første '\0'
>>hvilket er første tegn i dit tilfælde.
>
>
> Forkert. Man kan sagtens sammenligne std::string der indeholder '\0'
> tegn. Hvis din implementation bruger strcmp, så har den en bug.
>

Du har ret, det kan man godt (jeg vil dog mene at det er
en lidt sær side effekt).

Jeg er ikke sikker på at følgende konstruktion er sikker:

char ch[1];

while (linje!=NEWMESSAGE) {
groupfile.read(ch,1);
linje=linje.substr(1,4)+ch;

Bør sidste linie ikke være:

linje=linje.substr(1,4)+ch[0];

--
What's in a name?
That which we call a rose by any other name would smell as sweet.
- Juliet
http://home20.inet.tele.dk/midgaard/

Mogens Hansen (19-09-2004)
Kommentar
Fra : Mogens Hansen


Dato : 19-09-04 18:26


"Bertel Brander" <bertel@post4.tele.dk> wrote in message
news:414daca7$0$303$edfadb0f@dread16.news.tele.dk...

[8<8<8<]
> Du har ret, det kan man godt (jeg vil dog mene at det er
> en lidt sær side effekt).

Jeg ville muligvis overveje at benytte "deque" i stedet for "string":

template <typename T, typename FwdIt>
std::istream& search_past(std::istream& is, FwdIt first, FwdIt last)
{
const std::deque<T> ref_seq(first, last);
std::deque<T> read_seq;
T t;
while(read_seq.size() != ref_seq.size() && is >> t) {
read_seq.push_back(t);
}
while(read_seq != ref_seq && is >> t) {
read_seq.pop_front();
read_seq.push_back(t);
}

return is;
}

som bruges
const char newmessage[] = {0,25,0,0,2};
search_past<char>(file, &newmessage[0], &newmessage[sizeof(newmessage)]);

Det bliver måske ikke kortere, men jeg syntes måske det er tydeligere.
Noget af den øgede størrelse skyldes at man slipper for antagelsen om at
start sekvensen findes i filen og forudsætningen om at startsekvensen ikke
må bestå af et bestemt mønster.

[8<8<8<]
> Bør sidste linie ikke være:
>
> linje=linje.substr(1,4)+ch[0];

Jo.
Men er det ikke simplere at skrive
char ch;
while(...) {
groupfile >> ch;
line = line.substr(1,4)+ch;
}

Venlig hilsen

Mogens Hansen



Bertel Lund Hansen (19-09-2004)
Kommentar
Fra : Bertel Lund Hansen


Dato : 19-09-04 22:48

Bertel Brander skrev:

>Du har ret, det kan man godt (jeg vil dog mene at det er
>en lidt sær side effekt).

Jeg har da hele tiden opfattet det som en central pointe at når
man opgiver 0-termineringen, kan en streng indeholde en vilkårlig
værdi.

--
Bertel
http://bertel.lundhansen.dk/   FIDUSO: http://fiduso.dk/

Bertel Brander (19-09-2004)
Kommentar
Fra : Bertel Brander


Dato : 19-09-04 23:18

Bertel Lund Hansen wrote:
> Bertel Brander skrev:
>
>
>>Du har ret, det kan man godt (jeg vil dog mene at det er
>>en lidt sær side effekt).
>
>
> Jeg har da hele tiden opfattet det som en central pointe at når
> man opgiver 0-termineringen, kan en streng indeholde en vilkårlig
> værdi.
>

Jeg ville mene at det logiske var at en std::string indeholdt en
streng, og en streng er i min optik (efter at have programmeret
i C i mange år) en række karakterer, afsluttet af et '\0'.
Jeg er så med denne tråd blevet belært om at det ikke er
tilfældet i C++, her er en streng en række char's og
intet andet.

--
What's in a name?
That which we call a rose by any other name would smell as sweet.
- Juliet
http://home20.inet.tele.dk/midgaard/

Michael Rasmussen (19-09-2004)
Kommentar
Fra : Michael Rasmussen


Dato : 19-09-04 23:57

On Mon, 20 Sep 2004 00:17:57 +0200, Bertel Brander wrote:

> Jeg ville mene at det logiske var at en std::string indeholdt en streng,
> og en streng er i min optik (efter at have programmeret i C i mange år)
> en række karakterer, afsluttet af et '\0'. Jeg er så med denne tråd
> blevet belært om at det ikke er tilfældet i C++, her er en streng en
> række char's og intet andet.
Skyldes det i sagens natur ikke, at C++ ikke har en specifikation af en
string. Jeg mener så absolut ikke, at en string skal være
null-termineret i C++, hvilket skyldes, at klassen string indeholder en
privat member variabel, der har oplysninger om stringens længde. Metoden
sting.length() returnerer indholdet af denne variabel, hvorfor en
string-klasse i C++ ikke behøver at læse til \0. Anderledes forholder
det sig i C, hvor der ikke findes nogen definition af en string, hvilket
betyder, at man har måttet indfører et reserveret tegn for at indikere
afslutning på tegnsekvensen.

--
Hilsen/Regards
Michael Rasmussen

Get my public GnuPG keys:
mir <at> datanom <dot> net
http://search.keyserver.net:11371/pks/lookup?op=get&search=0xE501F51C
mir <at> miras <dot> org
http://search.keyserver.net:11371/pks/lookup?op=get&search=0xE3E80917
--------------------------------------------------------------
Format a program to help the reader understand it.
- The Elements of Programming Style (Kernighan & Plaugher)



Bertel Lund Hansen (20-09-2004)
Kommentar
Fra : Bertel Lund Hansen


Dato : 20-09-04 08:02

Bertel Brander skrev:

>Jeg ville mene at det logiske var at en std::string indeholdt en
>streng, og en streng er i min optik (efter at have programmeret
>i C i mange år) en række karakterer, afsluttet af et '\0'.

Du er miljøskadet af C. Jeg lærte C på et sent tidspunkt og
skulle vænne mig til at arbejde med 0-terminerede strenge og de
små ulemper det gav - bl.a. at et nul midt i strengen pludselig
klippede den i smadder.

--
Bertel
http://bertel.lundhansen.dk/   FIDUSO: http://fiduso.dk/

Bertel Brander (20-09-2004)
Kommentar
Fra : Bertel Brander


Dato : 20-09-04 18:46

Bertel Lund Hansen wrote:
> Bertel Brander skrev:
>
>
>>Jeg ville mene at det logiske var at en std::string indeholdt en
>>streng, og en streng er i min optik (efter at have programmeret
>>i C i mange år) en række karakterer, afsluttet af et '\0'.
>
>
> Du er miljøskadet af C.

Måske...

> Jeg lærte C på et sent tidspunkt og
> skulle vænne mig til at arbejde med 0-terminerede strenge og de
> små ulemper det gav - bl.a. at et nul midt i strengen pludselig
> klippede den i smadder.
>

Jeg synes netop at det ville være naturligt at hvis
man indsætter en '\0' midt i en std::string, så
ender strengen der.

--
What's in a name?
That which we call a rose by any other name would smell as sweet.
- Juliet
http://home20.inet.tele.dk/midgaard/

Mogens Hansen (19-09-2004)
Kommentar
Fra : Mogens Hansen


Dato : 19-09-04 18:24


"Bertel Lund Hansen" <nospamius@lundhansen.dk> wrote in message
news:5lsqk0h75h5ueuvgh8k0lu7h1j3cc5phg4@news.stofanet.dk...
> Hej alle
>
> Jeg skal læse i en fil, men for at finde det rigtige sted at
> starte, skal jeg lede efter en given sekvens af tal, nemlig
> 0 25 0 0 2.

Hvis du kan tillade dig at læse filens indhold ind i en "vector", så kan du
bruge "search". Det skal læses ind i en "vector" idet "search" er en
multipass algoritme, hvilket ikke er kompatibelt med istream_iterator.

istream_iterator<char> file_end;
vector<char> file_content(istream_iterator<char>(file), file_end);

const char newmessage[] = {0,25,0,0,2};
vector<char>::iterator iter =
search(
file_content.begin(), file_content.end(),
&newmessage[0], &newmessage[sizeof(newmessage)]);



Venlig hilsen

Mogens Hansen



Bertel Lund Hansen (19-09-2004)
Kommentar
Fra : Bertel Lund Hansen


Dato : 19-09-04 22:49

Mogens Hansen skrev:

>Hvis du kan tillade dig at læse filens indhold ind i en "vector", så kan du
>bruge "search".

Tak for dine tips. Jeg kikker på det.

--
Bertel
http://bertel.lundhansen.dk/   FIDUSO: http://fiduso.dk/

Søg
Reklame
Statistik
Spørgsmål : 177580
Tips : 31968
Nyheder : 719565
Indlæg : 6409076
Brugere : 218888

Månedens bedste
Årets bedste
Sidste års bedste