|
| 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 |
| | |
|
|