Προς το περιεχόμενο

text file wrapping


Stilewag

Προτεινόμενες αναρτήσεις

Δημοσ.

Exw ftiaksei ena programataki stin Pascal (pragmatika den paizei rolo an den kserete Pascal kai kserete C/C++, i erotisi mou einai thema logokis) pou pairnei san input ena text file me aperioristo megethos gramis (line) kai to kanei wrap (to anadiplwnei) se grames twn 60 xaraktirwn (i o xristis mporei na valei oso thelei).

 

Prospathisa na to epekteinw wste na kanei olo to arxeio wrap, alla ta "thalasonei" meta apo merikes grammes. Eimai ston dromo gia na to ftiaksw afto to provlima, alla ostosw thelw na kserw an idea mou einai swsti.

 

Ithela na mou peite an tropos pou skeftomai einai swstos:

 

1. Exwntas idi ena komati kwdika pou kanei wrap mia megali (theoritika aperiorista) grami se mikres twn 60 xaraktirwn, to ekana function wste na to kalw opote thelw.

 

2. "Saronw" to arxeio kai apothikevw se enan pinaka poies grames exoun parapanw apo 60 xaraktires

 

3. Arxizw apo to telos tou arxeiou kai paw se kathe mia grammi pou kserw oti exei panw apo 60 xaraktires kai tis kanw anadiplwsi (an ksekinaga apo tin arxi tha eixa provlima na entopisw tis grammes)

 

..Telika to lathos einai logikis?

Δημοσ.

swsti einai i logiki, bebaia isws tha borouse na einai kaluteri. Kapoio lathos kaneis pistevw me tin metakinisi tou pointer stin proigoumeni kathe fora mi epeksergasmeni grammi.

Δημοσ.

Ισως άν έδινες κάποια στοιχεία παραπάνω -ή και τον κώδικά σου- θα ήταν πιό εύκολο να βοηθήσουμε.

Κάποιες σκέψεις:

Μια και μιλάς για αρχεία κειμένου, υποθέτω ότι το αρχείο εξόδου είναι διαφορετικό. Τί σ' εμποδίζει, αφού διαβάσεις μια "γραμμή" να τη μεταφέρεις στο αρχείο εξόδου αναδιπλωμένη;

Αυτή η έννοια της γραμμής με προβληματίζει, σε συνδυασμό με αυτό που γράφεις ότι ta "thalasonei" meta apo merikes grammes.

Μήπως χρησιμοποιείς (για τη γραμμή) μεταβλητές τύπου string που περιορίζονται στους 255 χαρακτήρες; Αν ναί, δοκίμασε να διαβάσεις το κείμενο σε μεταβλητές τύπου Pchar που υποστηρίζουν null terminated strings.

Φιλικά ...

Δημοσ.

den exw skeftei tropo me pou diavazw tous xaraktires mias grammis na tous anadiplwnw

 

ti kanei o pirinas tous programmatos:

1. diavazei enan-enan tous xaraktires kai simeiwnei se enana array tis topothesies twn spaces (" ")

2. vriskei mia topothesia =< 60 (elegxei kati psila mipws oi epomenoi kai proigoumenoi xaraktires einai spaces kai aftoi kai pratei analogws)

3. grafei tin grammi mexri ekeini tin topothesia

4. opi perisepse to grafei stin epimeni grammi

 

(olo afto einai to function WrapLine)

 

o kwdikas (eimai ligo tsapatsoulis, sorry :| ):

 

>
PROGRAM wrap2;

{
some notices

1. seems to do the job only in certain situations, why?

2. something that i didnt took under consideration:
i will need to perform some operations only if the
next character is not EOLN.... in other words, there
is a question: if two lines (two very long lines )
do not have a void between them, then should i consider
them as the same line? maybe i should let the user
decide, but that will add a lot more complexity to
the code
}


VAR
LineBytes,ELLength,SpacePos,SpaceLoc,i,j,k,m,r: integer;
inF,outF,Log: text;
Ch,ChX,Ch2,ChDebug: char;
Line,ExtraLine: string[61];
SpaceLocations: array[1..100] of integer;
DontChangeLine: integer; { ;-) }
FileSize: integer;
NumberOfLines,NumberOfLineChars: integer;
FileLinesLengths: array[1..100] of integer;
LinesStartPos: array[1..100] of integer;

FUNCTION GotoLine(LineNumber: integer): integer;
begin
  reset(inF);
  for m:=1 to LineNumber do readln(inF);
end;

FUNCTION GotoByte(Byte: integer): integer;
begin
  reset(inF);
  for m:=1 to Byte do read(inF,Ch);
  writeln(Log,'i am now in char ',Ch);
end;

PROCEDURE WrapLine; { i may need to correct this because i already have read a character }
begin;
   DontChangeLine:=0;
   for j:=1 to NumberOfLineChars do {while not eoln(inF) do}
   begin;
     if DontChangeLine=1 then writeln(outF);
     DontChangeLine:=1;
     LineBytes:=0;
     for i:=1+ELLength to 61 do { reads chars from position of previous extra line to 61 }
     begin
        LineBytes:=LineBytes+1;
        read(inF,Ch);
        Line[i]:=Ch;
     end;
     for i:=1 to 61 do { it finds spaces positions in the line }
     begin
        if (Line[i]=' ') then
        begin
           SpacePos:=SpacePos+1;
           SpaceLocations[spacePos]:=i;
        end;
     end;
     for i:=1 to SpacePos do { finds the optimal position and location of space }
     begin
        if SpaceLocations[i]<=60 then SpaceLoc:=SpaceLocations[i];
     end;
     SpacePos:=0;
     ELLength:=0;
     for i:=SpaceLoc+1 to 61 do { stores what is left into extra line }
     if Line[i]<>' ' then { dont store in extra line char1 is = space }
     begin
        ELLength:=ELLength+1;
        ExtraLine[ELLength]:=Line[i];
     end;
     for i:=1 to SpaceLoc-1 do write(outF,Line[i]); { writes line to output }
     for i:=1 to ELLength do Line[i]:=ExtraLine[i]; { stores extra line to line but doesnt store spaces }
  end;
  write(outF,' ');
  for i:=1 to ELLength do if (ExtraLine[i]<>char(26)) then write(outF,ExtraLine[i]); { writes the (remaining) extra line: }
end;

BEGIN; {------------------------------------------------------------------}
writeln;writeln;writeln;writeln;
assign(inF,'in2.txt');reset(inF);
assign(outF,'out.txt');rewrite(outF);
assign(Log,'log.txt');rewrite(Log);

reset(inF);
while not eof(inF) do { count file size }
begin
  read(inF,Ch);
  FileSize:=FileSize+1;
end;

reset(inF);
while not eof(inF) do { count number of lines }
begin
  readln(inF);
  NumberOfLines:=NumberOfLines+1;
end;

reset(inF);
for k:=1 to NumberOfLines do { store the length of each line to an array }
begin
  NumberOfLineChars:=0;
  while not eoln(inF) do
  begin;
     read(inF,Ch);
     NumberOfLineChars:=NumberOfLineChars+1;
  end;
  readln(inF);
  FileLinesLengths[k]:=NumberOfLineChars;
end;

reset(inF);
r:=0;
for k:=1 to FileSize do { store the specific byte that each line starts }
begin
  read(inF,Ch);
  if EOLN(inF) then
  begin
     r:=r+1;
     LinesStartPos[r]:=k;
     {write('found at byte ',k,' stored at position ',r);readln;}
  end;
end;

{ write to log the byte (location) that each line starts }
writeln(Log,'bytes that each line starts: ');
for k:=1 to NumberOfLines do
begin
  GotoByte(LinesStartPos[k]-FileLinesLengths[k]+1);
  writeln(Log,LinesStartPos[k]-FileLinesLengths[k]+1,' - ',Ch);
end;

{ this is the core }
{ it doesnt matter that i didnt put "downto", it matters to make the proper number of loops }
for k:=NumberOfLines downto 1 do
begin
  if FileLinesLengths[k]>60 then
  begin
     writeln(Log);
     writeln(Log,'*** I will go to byte: ',LinesStartPos[k]-FileLinesLengths[k]);
     GotoByte(LinesStartPos[k]-FileLinesLengths[k]);
     WrapLine;
  end;
end;


{
1. from last to first line (reverse)
2. check the number of characters in each line
3. if number of chars > 60 then perform WrapLine, but keep in
mind that it might be necessary to reposition the cursor
}


{
goes to the last byte of the line and then

last byte of the line - line length (thus is goes to one character beafore
line's first character

alternatively, i can order gotoByte to go to the previous line than the one
i want to process

loop as many times as the lines number
go to the byte of each line's start and then perform the wrap line
do this from bottom to top, so that byte-locations will not change
}

(*
for k:=NumberOfLines downto 1 do // this is the processing core/kernel
begin
  if FileLinesLengths[k]>60 then
  begin
     {GotoLine(k);}
     {WrapLine;}
     read(inF,Ch);
     writeln('processing line #',k);
     writeln('first character of line is ',Ch);
     writeln;
  end;
  {write(FileLinesLengths[k],',');}
end;
*)

writeln;
{write('press ENTER to exit');readln;}

close(Log);
close(inF);
close(outF);
END. {----------------------------------------------------------------------}


 

o parapanw kwdikas doulevei. Tha lavei san input ena text file me mia seira, oso megali kai na einai (hmm... isws kai oxi) kai tha tin "kopsei" stous 60 xaraktires

 

-----

 

o parakatw kwdikas... den doulevei :(

 

>
PROGRAM wrap2;

{
some notices

1. seems to do the job only in certain situations, why?

2. something that i didnt took under consideration:
i will need to perform some operations only if the
next character is not EOLN.... in other words, there
is a question: if two lines (two very long lines )
do not have a void between them, then should i consider
them as the same line? maybe i should let the user
decide, but that will add a lot more complexity to
the code
}


VAR
LineBytes,ELLength,SpacePos,SpaceLoc,i,j,k,m,r: integer;
inF,outF,Log: text;
Ch,ChX,Ch2,ChDebug: char;
Line,ExtraLine: string[61];
SpaceLocations: array[1..100] of integer;
DontChangeLine: integer; { ;-) }
FileSize: integer;
NumberOfLines,NumberOfLineChars: integer;
FileLinesLengths: array[1..100] of integer;
LinesStartPos: array[1..100] of integer;

FUNCTION GotoLine(LineNumber: integer): integer;
begin
  reset(inF);
  for m:=1 to LineNumber do readln(inF);
end;

FUNCTION GotoByte(Byte: integer): integer;
begin
  reset(inF);
  for m:=1 to Byte do read(inF,Ch);
  writeln(Log,'i am now in char ',Ch);
end;

PROCEDURE WrapLine; { i may need to correct this because i already have read a character }
begin;
   DontChangeLine:=0;
   for j:=1 to NumberOfLineChars do {while not eoln(inF) do}
   begin;
     if DontChangeLine=1 then writeln(outF);
     DontChangeLine:=1;
     LineBytes:=0;
     for i:=1+ELLength to 61 do { reads chars from position of previous extra line to 61 }
     begin
        LineBytes:=LineBytes+1;
        read(inF,Ch);
        Line[i]:=Ch;
     end;
     for i:=1 to 61 do { it finds spaces positions in the line }
     begin
        if (Line[i]=' ') then
        begin
           SpacePos:=SpacePos+1;
           SpaceLocations[spacePos]:=i;
        end;
     end;
     for i:=1 to SpacePos do { finds the optimal position and location of space }
     begin
        if SpaceLocations[i]<=60 then SpaceLoc:=SpaceLocations[i];
     end;
     SpacePos:=0;
     ELLength:=0;
     for i:=SpaceLoc+1 to 61 do { stores what is left into extra line }
     if Line[i]<>' ' then { dont store in extra line char1 is = space }
     begin
        ELLength:=ELLength+1;
        ExtraLine[ELLength]:=Line[i];
     end;
     for i:=1 to SpaceLoc-1 do write(outF,Line[i]); { writes line to output }
     for i:=1 to ELLength do Line[i]:=ExtraLine[i]; { stores extra line to line but doesnt store spaces }
  end;
  write(outF,' ');
  for i:=1 to ELLength do if (ExtraLine[i]<>char(26)) then write(outF,ExtraLine[i]); { writes the (remaining) extra line: }
end;

BEGIN; {------------------------------------------------------------------}
writeln;writeln;writeln;writeln;
assign(inF,'in2.txt');reset(inF);
assign(outF,'out.txt');rewrite(outF);
assign(Log,'log.txt');rewrite(Log);

reset(inF);
while not eof(inF) do { count file size }
begin
  read(inF,Ch);
  FileSize:=FileSize+1;
end;

reset(inF);
while not eof(inF) do { count number of lines }
begin
  readln(inF);
  NumberOfLines:=NumberOfLines+1;
end;

reset(inF);
for k:=1 to NumberOfLines do { store the length of each line to an array }
begin
  NumberOfLineChars:=0;
  while not eoln(inF) do
  begin;
     read(inF,Ch);
     NumberOfLineChars:=NumberOfLineChars+1;
  end;
  readln(inF);
  FileLinesLengths[k]:=NumberOfLineChars;
end;

reset(inF);
r:=0;
for k:=1 to FileSize do { store the specific byte that each line starts }
begin
  read(inF,Ch);
  if EOLN(inF) then
  begin
     r:=r+1;
     LinesStartPos[r]:=k;
     {write('found at byte ',k,' stored at position ',r);readln;}
  end;
end;

{ write to log the byte (location) that each line starts }
writeln(Log,'bytes that each line starts: ');
for k:=1 to NumberOfLines do
begin
  GotoByte(LinesStartPos[k]-FileLinesLengths[k]+1);
  writeln(Log,LinesStartPos[k]-FileLinesLengths[k]+1,' - ',Ch);
end;

{ this is the core }
{ it doesnt matter that i didnt put "downto", it matters to make the proper number of loops }
for k:=NumberOfLines downto 1 do
begin
  if FileLinesLengths[k]>60 then
  begin
     writeln(Log);
     writeln(Log,'*** I will go to byte: ',LinesStartPos[k]-FileLinesLengths[k]);
     GotoByte(LinesStartPos[k]-FileLinesLengths[k]);
     WrapLine;
  end;
end;


{
1. from last to first line (reverse)
2. check the number of characters in each line
3. if number of chars > 60 then perform WrapLine, but keep in
mind that it might be necessary to reposition the cursor
}


{
goes to the last byte of the line and then

last byte of the line - line length (thus is goes to one character beafore
line's first character

alternatively, i can order gotoByte to go to the previous line than the one
i want to process

loop as many times as the lines number
go to the byte of each line's start and then perform the wrap line
do this from bottom to top, so that byte-locations will not change
}

(*
for k:=NumberOfLines downto 1 do // this is the processing core/kernel
begin
  if FileLinesLengths[k]>60 then
  begin
     {GotoLine(k);}
     {WrapLine;}
     read(inF,Ch);
     writeln('processing line #',k);
     writeln('first character of line is ',Ch);
     writeln;
  end;
  {write(FileLinesLengths[k],',');}
end;
*)

writeln;
{write('press ENTER to exit');readln;}

close(Log);
close(inF);
close(outF);
END. {----------------------------------------------------------------------}

 

Simeiosi: to LOG.TXT dinei xrisimes plirofories. Panta vazw log otan vriskw ta skoura :)

Αρχειοθετημένο

Αυτό το θέμα έχει αρχειοθετηθεί και είναι κλειστό για περαιτέρω απαντήσεις.

  • Δημιουργία νέου...