Kan ikke finde ud af hvad der er galt med min kode :-s

Tags:    c++

<< < 12 > >>
Hej, jeg har lavet et lille program som skal "reparere" filer hvor indrykningerne er gået skævt...
Det bruges så ledes: fixtab (som jo er programmets navn) [filnavn] [-i] (som gør at den IKKE skal læse i komentarer (// og mellem /* og */)) [-m] (som gør at der IKKE bliver lavet mellemrum i de tomme linjer)
Mit problem er at af en eller anden grund virker min -i ikke.
Her er koden:

Fold kodeboks ind/udKode 


Håber i kan hjælpe...
/Jesper



16 svar postet i denne tråd vises herunder
1 indlæg har modtaget i alt 3 karma
Sorter efter stemmer Sorter efter dato
Hej Jesper,

Til Søren: Ved godt at der er en del fejl hvis der både er /* eller og { i linjen... Frygter det vil kræve en kæmpe ombygning af 3. del af min kode... Men jeg vil starte med at få dette tli at virke. :-)


Helt enig. Del problemerne op, og tag et ad gangen. Lad os få denne version til at virke først. Det var også derfor jeg spurgte først inden jeg kommer med andre problemer :-)

Hej, min far kom igår og hjalp mig med at få rettet lidt op på programmet og vi fik /* og */ til at virke desværre virker // ikke...

bemærk at den store ændring er i de to if sætninger...
Bemærk også at koden virker selvom man fjerner kommentarene i:
if((!iOption) || (!kommentaraaben)/* || ((kommentar != string::npos) && (nummer < kommentar))*/)
og/eller sætter kommentarer i denne:
if((!iOption) || (!kommentaraaben) || ((kommentar != string::npos) && (nummer2 < kommentar)))

Nogen der kan se hvad jeg gør galt nu?


Øhh, jeg forstår slet ikke den del du har tilføjet, altså
(kommentar != string::npos) &&
Den skal efter min opfattelse ikke være der.

Lad mig ridse op hvorfor:

Udtrykket
(!kommentaraaben)
er sandt, præcis når { eller } ikke er kommenteret ud af /* */, hvor vi skal rykke ind eller ud. Fint.

Tilsvarende var udtrykket i sidste del af if-betingelsen du havde før, hvor der blot stod
(nummer2 < kommentar)
sandt, præcis når { eller } ikke er kommenteret ud af //. Altså:
} sand, der skal rykkes ud.
} // sand, der skal rykkes ud.
// } falsk, der skal ikke rykkes ud.
Fint.

Det nye udtryk
(kommentar != string::npos) && (nummer < kommentar)
har følgende værdier:
} falsk
} // sand
// } falsk

Hvad skal det gøre godt for?


Her er der 2 falske værdier. Det gør det lidt bedre fordi det er de sande værdier der ødelægger håndteringen af /**/ i det samlede udtryk, når du nu har || istedet for && mellem de to udtryk der håndterer /**/ hhv. //.

Er der en speciel grund til at du har || mellem udtrykkene? Jeg gentager lige hvorfor jeg synes der skal stå &&:

De krøllede parenteser {, } skal forårsage ind og udrykning når de står uden for _både_ den ene slags kommentarer /* */ _og_ uden for den anden slags //.


En helt anden ting:
De variable i programmet som modtager værdier fra string::find, synes jeg skal være af type size_t. Det er typen string::find returnerer. (det er det samme som string::size_type, som du andet steds i programmet har haft fat i).

De variable som håndterer returværdierne er af type int og unsigned int. Det kan give problemer hvis værdierne string::find returnerer ikke kan være i variablene. Det er ikke garanteret at en size_t kan være i en unsigned int. Specielt ikke string::npos, som er en _stor_ værdi (den største?) af size_t.

I min compiler er size_t == unsigned int, men måske er det ikke i din.

Min compiler skriver:
warning: '=' : conversion from 'size_t' to 'unsigned int', possible loss of data

Du skal også have tungen lige i munden og vide hvad du gør, når du sammenligner unsigned og signed int, som du gør i f.eks. '(nummer2 < kommentar)'.
(eller rettere undgå at sammenligne dem).
Min compiler skriver:
warning: '<' : signed/unsigned mismatch
Så vidt jeg kan se er det ikke her problemet er. For værdierne med fortegn bliver konverteret tilbage til unsigned, som de var oprindeligt i dit program, inden sammenligningen foretages.

(Hvis jeg sætter
nummer2 = string::npos
kommentar = string::npos
bliver
nummer2 == -1
kommentar == 4294967295
Men
(nummer2 < kommentar) er falsk og
(nummer2 == kommentar) er sand. )

Nå, det blev en lang smøre. Blev det for langt? Hvis ja, så undskyld.
Hilsen Søren.




Øhh, jeg forstår slet ikke den del du har tilføjet, altså
(kommentar != string::npos) &&
Den skal efter min opfattelse ikke være der.

Lad mig ridse op hvorfor:

Udtrykket
(!kommentaraaben)
er sandt, præcis når { eller } ikke er kommenteret ud af /* */, hvor vi skal rykke ind eller ud. Fint.


Hej Søren

Ja nu hvor jeg læser det kan jeg godt se at de to sidste faktisk kan være ligemeget... Hvis kommentaraaben så læser man i dem, MEN jeg regner ikke med at man både bruger /* */ og // i samme linje.
I min tidligere version af programmet var (!kommentaraaben) der ikke så var det kun // der blev registreret, og der var kommentar != string::npos vigtig fordi at hvis der ikke var kommentarer i linjen ville jeg jo godt lave indrykninger...

Min umildbare løsning er at lave endnu en if inde i iffen er dog ikke sikker på hvordan den skal formes men det finder jeg nok ud af...


Ang. size_t så har jeg aldrig prøvet at bruge size_t men den er sat på listen over ting der skal gøres ;-)



Lad os et øjeblik kikke på:
Fold kodeboks ind/udKode 

Hvilket betyder:
hvis ikke iOption eller ikke kommentaraaben eller // starter efter {

Hvis kommentaraaben er falsk vil udtrykket være sand, uanset kommentar.

Du skal have en && noget i stil med:
Fold kodeboks ind/udKode 


Du bør sætte kommentar til string::npos ikke 255 ved initiering, det er vigtigt hvis iOption ikke sættes.


Tja jeg er helt enig hvor problemet er Men... din løsning virker ikke!




Hej igen Jesper,

Tja jeg er helt enig hvor problemet er Men... din løsning virker ikke!


Hvad med mit forslag:
if((!iOption) || ((!kommentaraaben) && (nummer2 < kommentar))) antalIndRyk=antalIndRyk-1; //Tæl antalIndRyk en ned
og
if((!iOption) || ((!kommentaraaben) && (nummer < kommentar))) antalIndRyk=antalIndRyk+1; //Tæl antalIndRyk en op

virker det? Det virker hos mig, altså rykker ind og ud ved hhv. { og } som det skal. (altså bortset fra det med hvis der er {, }, /*, */ og // på samme linie, og at der er andre indrykninger vi endnu ikke har kikket på).

Men programmet vil jo indrykke kommentarer til aktuelle indryknings-niveau. Er det det der er galt?

Hvis du vil bevare kommentarernes indrykning fra før programmet blev kørt, kan du ikke gøre det med den nuværende opdeling af programmet i afsnit 1,2,3. For i afsnit 2 fjerner du jo alle mellemrum i starten af linierne, også i kommentarlinierne.

For at bevare indrykningen af kommentarerne uændret, vil jeg foreslå at slå afsnit 2 og 3 sammen. Eller rettere flytte mellemrum-sletningen ned i afsnit 3.
Så kan du lade mellemrummene være i kommentarlinier, dvs. når 'kommentaraaben' er sand eller der optræder // som første ikke-mellemrum på linien.

Hilsen Søren.



Hej igen Jesper,

Tja jeg er helt enig hvor problemet er Men... din løsning virker ikke!


Hvad med mit forslag:
if((!iOption) || ((!kommentaraaben) && (nummer2 < kommentar))) antalIndRyk=antalIndRyk-1; //Tæl antalIndRyk en ned
og
if((!iOption) || ((!kommentaraaben) && (nummer < kommentar))) antalIndRyk=antalIndRyk+1; //Tæl antalIndRyk en op

virker det? Det virker hos mig, altså rykker ind og ud ved hhv. { og } som det skal. (altså bortset fra det med hvis der er {, }, /*, */ og // på samme linie, og at der er andre indrykninger vi endnu ikke har kikket på).

Men programmet vil jo indrykke kommentarer til aktuelle indryknings-niveau. Er det det der er galt?

Hvis du vil bevare kommentarernes indrykning fra før programmet blev kørt, kan du ikke gøre det med den nuværende opdeling af programmet i afsnit 1,2,3. For i afsnit 2 fjerner du jo alle mellemrum i starten af linierne, også i kommentarlinierne.

For at bevare indrykningen af kommentarerne uændret, vil jeg foreslå at slå afsnit 2 og 3 sammen. Eller rettere flytte mellemrum-sletningen ned i afsnit 3.
Så kan du lade mellemrummene være i kommentarlinier, dvs. når 'kommentaraaben' er sand eller der optræder // som første ikke-mellemrum på linien.

Hilsen Søren.


Hej Søren,

Jo det er meningen at den skal rykke kommenterede linjer ind...
I dit forslag, hvad hvis kommentar er npos?
Kan det ikke skabe en del problemer med en uendelig while?



Hej igen,

I dit forslag, hvad hvis kommentar er npos?
Kan det ikke skabe en del problemer med en uendelig while?


Jeg ved ikke helt i hvilke af mine forslag, og hvilken while-løkke, du mener. Men jeg prøver at svare alligevel:

Hvis 'kommentar' er npos i mit forslag:
if((!iOption) || ((!kommentaraaben) && (nummer2 < kommentar))) antalIndRyk=antalIndRyk-1; //Tæl antalIndRyk en ned
og
if((!iOption) || ((!kommentaraaben) && (nummer < kommentar))) antalIndRyk=antalIndRyk+1; //Tæl antalIndRyk en op

vil '(nummer2 < kommentar)' og '(nummer < kommentar)' være sande fordi 'nummer2' og 'nummer' er egentlige positioner i linien og ikke npos (det bliver checket i if sætningen inden) og fordi npos og dermed 'kommentar' er garanteret at være et tal > enhver mulig position i en string. (det er en egenskab ved npos som c++ giver).

Det kan ikke ændre på at while-løkken der løber gennem linierne stopper. Den slutter jo når der ikke er flere linier i filen.

Men det er vist ikke det du mener? Så må du spørge igen.

Hilsen Søren.



<< < 12 > >>
t