* hep@worldonline.dk
[snip]
> Jeg har lavet dette program, men kan ikke bruge funktionerne find, remove,
> insert, programmet skal indlæse en tækst i 20 Strings objekt, en for hver
> linei, det har jeg klaret, med de der funktioner, de driller, tekstes står
> efter programmet.
I og med at størrelsen på datastrukturen er kjent på forhånd, vil man
greie seg med en array. Dog jeg greier ikke å overbevise megselv om
dens fordeler, så vi prøver en løsning basert på vector.
> #include <iostream.h>
> #include <conio.h> //getch
> #include <tstring.h>
> #include <String.h>
> #include "String.h"
> #include <fstream.h>
_ingen_ av disse er en C++ header.
#include <iostream>
#include <string>
#include <fstream>
og siden vi skal leke med vectors:
#include <vector>
> //#include <iomanip.h>
> //#include "textlib.h" //setreal
> //#include <stdlib.h>
>
> int main()
> {
> const int str = 20;
> String linie[str];
using namespace std;
const size_t length = 20UL;
vector< string > lines( length );
Altså, std::string, ikke String.
> ifstream input_fil("kladde.dat");
ifstream ifs( "scratch.data" );
if ( !ifs ) {
cerr << "failed to open datafile\n";
exit( 1 );
}
> for(int a = 1; a<=20; a++)
> {
> getline(input_fil, linie[a],'\n');
Du trenger ikke å oppgi '\n' eksplisitt.
> //while(linie[a].find("#01",3)!=-1)
> //linie[a].remove (0,1);
>
> linie[a].find("#01",0);
> linie[a].remove (0,0);
Dette er meningsløst for std::string, da "remove" ikke finnes.
> linie[a].insert(0,"henrik");
>
> cout <<linie[a] <<endl;
> }
Akkurat her er det flere muligheter for å løse problemet.
1) generate_n (fra istream_iterator til vector) + transform (vector
til ostream_iterator)
2) transform (av istream_iterator til ostream_iterator)
3) vanlig while løkke (kjedelig, men det funker)
1)
generate_n( lines.begin(),
lines.size(),
bind1st( getline, cin ) );
+
transform( lines.begin(),
lines.end(),
ostream_iterator< string >( cout, "\n" ),
make_replacement );
std::string
make_replacement( const std::string &s )
{
std::string tmp = s;
std::string::size_type index = tmp.find( "#01" );
if ( index == std::string::npos )
return s;
tmp.erase( index, 3 );
tmp.insert( 0UL, "henrik" );
return tmp;
}
2)
transform( line_iterator< string >( cin ),
line_iterator< string >(),
ostream_iterator< string >( cout, "\n" ),
make_replacement );
"line_iterator" kan rappes rett fra Matt Austern sin bok.
3)
for ( size_t i = 0; i != 20UL; ++i ) {
getline( cin, lines[i] );
string::size_type j = lines[i].find( "#01" );
if ( j == string::npos )
continue ;
lines[i].erase( j, 3 );
lines[i].insert( 0UL, "henrik" );
}
Jeg innbiller meg at erase på npos er ganske så veldefinert, men det
må nok sjekkes nærmere i TC++PL3ed eller standarden.
> return 0;
> getch();
Er ikke det litt meningsløst å ha setninger som kontrollen aldri
kommer til?
Om du skal erstatte alle "#01" med "henrik", og alle "#02" med noe
tilsvarende, kan dette også ordne seg, men da må man jobbe litt mer.
Du kan om du vil bruke denne:
void
replace( std :: string &src,
const std :: string &replacee,
const std :: string &replacement )
{
std :: string :: size_type pos = 0;
while ( (pos = src.find( replacee, pos )) != std :: string :: npos )
src.replace( pos, replacee.size(), replacement );
}
(ja, den er dum, men jeg gidder ikke å skrive en litt mer generisk sak
for tiden).
ivr
--
Death by snoo-snoo
|