Solved

urgent, separated text file and do manipulation string in text file

Posted on 2002-05-26
5
173 Views
Last Modified: 2010-04-04
hi expert
i would like to ask you about manipulating string in text file.

sample of Cdr.txt file
03-05-2002 00:00:32,03-05-2002 00:01:26, 00054,02,02,01, 56,112223, 000, 1162281681873,00

03-05-2002 00:01:49,00-00-0000 00:00:00, 00000,02,33,01, 60,1112223,11000000024,126242125108,53

03-05-2002 00:04:06,00-00-0000 00:00:00, 00000,02,39,03, 14,0823106688,4400000003,1362823138571,53

03-05-2002 00:27:15,00-00-0000 00:00:00, 00000,02,32,05, 24,0818000001,00000000,1462818213077,53

03-05-2002 00:29:15,00-00-0000 00:00:00, 00000,02,06,00, 00,0000000000,44000001,08127738962,52

here's is my problem:
- i gotta open my cdr.txt and read the cdr.txt file

cdr.txt file has format structure like this:
date1 time1,  date2 time2, xxxxx, code incoming, code outgoing, xx, xx, xxxxxxx, xxx, xx, BNum, xx

here is the example of the cdr.txt content. this file has 100.0000 row or more :
date1 time1,         date2 time2,          xxxxx,
03-05-2002 00:00:32, 03-05-2002 00:01:26,  00054,

code incoming code out outgoing, xx, xx, xxxxxxx, xxx,
     02,     02,              01, 56, 1112223, 000,

   BNum,       xx  
1162281681873,  00

-convert code incoming
as u can see from the cdr.txt above the all code incoming is 02 so we have to find it as code incoming
format in below.
 
code incoming format
if in BNum i find code 11 (2 digit from left), code incoming wills still 02  

if in BNum i find code 12 (2 digit from left), code incoming from 02 will change into 10    

if in BNum i find code 13 (2 digit from left), code incoming from 02 will change into 08

if in BNum i find code 14 (2 digit from left), code incoming wills still 02  

if in BNum we cant find the same format like above it still remain the same like the old 1.txt

this BNum will always change and updatetable

-after  that save the new change into a new txt file
with the same structure except there is a changing in the code incoming according the 2 digit from the left that we find in BNum.

result save in cdrnew.txt
03-05-2002 00:00:32,03-05-2002 00:01:26, 00054,02,02,01, 56,112223, 000, 1162281681873,00

03-05-2002 00:01:49,00-00-0000 00:00:00, 00000,10,33,01, 60,1112223,11000000024,126242125108,53

03-05-2002 00:04:06,00-00-0000 00:00:00, 00000,08,39,03, 14,0823106688,4400000003,1362823138571,53

03-05-2002 00:27:15,00-00-0000 00:00:00, 00000,02,32,05, 24,0818000001,00000000,1462818213077,53

03-05-2002 00:29:15,00-00-0000 00:00:00, 00000,02,06,00, 00,0000000000,44000001,08127738962,52

with the help of the expert in here,the program is running very fast. i need the speed in processing because its very critical and the CDR file is more then 2 mb. here is the code:

procedure TForm1.AdjustString2(var txt1Line: string);
VAR posCodeIncoming, posBNumStart: integer;
    ch1, ch2: char;
begin
// note: these lines are looking for the beginning of BNum
// if the fields have fixed length, you can set the index right away! (much faster!)
    posBNumStart := Length(txt1Line)-5; //
    WHILE (txt1Line[posBNumStart-1] >= #48) AND ((txt1Line[posBNumStart-1] <= #57)) DO DEC(posBNumStart);

    posCodeIncoming := 47;
    IF (txt1Line[posBNumStart] = '1') THEN BEGIN
         IF (txt1Line[posBNumStart+1] = '2')     THEN BEGIN ch1 := '1'; ch2 := '0'; END
         ELSE IF (txt1Line[posBNumStart] = '1') THEN BEGIN ch1 := '0'; ch2 := '8'; END
         ELSE IF (txt1Line[posBNumStart] = '3') THEN BEGIN ch1 := '0'; ch2 := '2'; END
         ELSE IF (txt1Line[posBNumStart] = '4') THEN BEGIN ch1 := '0'; ch2 := '2'; END
         ELSE EXIT;
         txt1Line[posCodeIncoming] := ch1;
         txt1Line[posCodeIncoming+1] := ch2;
    END;
end;

Here's a method that converts a file:
procedure TForm1.Button2Click(Sender: TObject);
    VAR f1, f2: textfile;
    startTime: integer;
    line: string;
begin
    AssignFile(f1, Edit3.Text);
    AssignFile(f2, Edit4.Text);
    Reset(f1);
    Rewrite(f2);
    startTime := GetTickCount;
    WHILE NOT (EOF(f1)) DO BEGIN
         readln(f1, line);
         AdjustString2(line);
         writeln(f2, line);
    END;
    ShowMessage('conversion took ' + IntToStr(GetTickCount-startTime) + ' ms');
    CloseFile(f1);
    CloseFile(f2);
end;

but now i need a little help again, i hope the expert would help me again :
-how to separated the code incoming formatted into a text file separate from the program?
-and save it to a new file  
-(how can i browse the CDR file in a folder and do it with no display from the form, and then save the file with changing in the code incoming. )
 
still the same case but now it changing a bit.
previously we only count the position for the incoming code in the Orginical CDR and changing into the incoming code formatted  and save it to the cdrnew.txt file.

now the code incoming formatted is written in a new file called codeincoming.txt file.

codeincoming.txt file only have  formatted like below :
BNum    codeincoming
11     02
12     10
13     08
14     02
15     ..
..     ..    
..     ..
and etc // it change be change also it can be added.

after that we read the Original CDR and convert it and save it to the cdrnew.txt file

so how can we convert it from the codeincoming.txt file also compare and write the incoming code formatted from the program that its written above with the same position like in the program and do the manipulation string and then save it to the cdrnew.txt file?

speed also critical. no display of the form requirement. and how to open and save the CDR file without using the open dialog or save dialog function but we can still changing the path of the folder that content our program?


thank you expert for your attention and also helping me with this problem. if u need the original Cdr file please contact me at bf_4evr@yahoo.com.
please help me i need to solve the problem ASAP.
 
Sincerely
Denox
 

0
Comment
Question by:denox
5 Comments
 
LVL 1

Expert Comment

by:Fraction
Comment Utility
I suggest using a filestream to read large files.
I.E: stream := TFileStream.Create('Cdr.txt', fmOpenRead);
0
 
LVL 9

Accepted Solution

by:
ITugay earned 300 total points
Comment Utility
hi Denox,

I think that you can use this sample to solve your task. It doesn't tested, I'm failed to sent you e-mail. But I hope that it's not too difficult to explore my code and correct bugs.

I use class to keep and parse current line. I suppose that it should't affect productivity because file operation take more time that processing.

-----
Igor.

//******* how to use **********

var
  R: TCDRLine;
.....

  R := TCDRLine.Create;
  R.Convert('cdr.txt', 'outcdr.txt', 'codeincoming.txt');

// you can use passed to application parameters
// R.Convert(paramstr(1), paramstr(2), paramstr(3));

  R.Free;
....  

//******* how to implement **********


unit u2;

interface

uses
  windows, classes, sysutils;

type
  TCDRLine = class(TObject)
  private
    FCrossTab: array[0..255] of byte;
    procedure SetLine(const S: String);
    function GetLine: String;
  protected
    DateTime1: String;
    DateTime2: String;
    CodeIn: Integer;
    CodeOut: Integer;
    BNum: Integer;
    Dummy: array[0..6] of String;
    property Line: String read GetLine write SetLine;

    procedure Convert;
    procedure LoadCrossTab(const FName: String);
  public
    // main converting procedure
    // FNameIn - file name of input file
    // FNameOut - file name of output file
    // FNameCross - file name of conerting cross table
    procedure Execute(const FNameIn, FNameOut, FNameCross: String);
  end;

implementation



procedure TCDRLine.SetLine(const S: String);

var
  I, E: Integer;
  function Next: String;
  begin
    Result := '';
    while (I <= Length(S)) and (S[I] <> ',') do
    begin
      Result := Result + S[I];
      inc(I);
    end;
    while (I <= Length(S)) and (S[I] in [',', ' ']) do
      inc(I);
  end;

begin
  I := 1;
  DateTime1 := Next;
  DateTime2 := Next;
  Dummy[0] := Next;
  Val(Next, CodeIn, E);
  Val(Next, CodeOut, E);
  Dummy[1] := Next;
  Dummy[2] := Next;
  Dummy[3] := Next;
  Dummy[4] := Next;
  Dummy[5] := Next;
  Val(copy(Dummy[5], 1, 2), BNum, E);
  Delete(Dummy[5], 1, 2);
  Dummy[6] := Next;
end;

function TCDRLine.GetLine: String;
begin
  Result := Format('%s,%s,%s,%.2d,%.2d,%s,%s,%s,%s,%.2d%s,%s',
   [DateTime1, DateTime2, Dummy[0], CodeIn, CodeOut, Dummy[1], Dummy[2],
    Dummy[3], Dummy[4], BNum, Dummy[5], Dummy[6]]);
end;

procedure TCDRLine.LoadCrossTab(const FName: String);
var
  L: TStrings;
  I, J: Integer;
begin
  for I := 0 to 255 do
    FCrossTab[I] := I;
  L := TStringList.Create;
  L.LoadFromFile(FName);
  for I := 0 to L.Count - 1 do
  begin
    J := Pos(' ', L[I]);
    FCrossTab[StrToInt(Copy(L[I], 1, J))] := StrToInt(Trim(Copy(L[I], J + 1, 10)));
  end;
  L.Free;
end;

procedure TCDRLine.Convert;
begin
  CodeIn := FCrossTab[BNum];
end;

procedure TCDRLine.Execute(const FNameIn, FNameOut, FNameCross: String);
var
  FI, FO: Text;
  S: String;
begin
  LoadCrossTab(FNameCross);
  Reset(FI);
  Rewrite(FO);
  while not EOF(FI) do
  begin
    Readln(FI, S);
    Line := S;
    Convert;
    Writeln(FO, Line);
  end;
  Close(FI);
  Close(FO);
end;

end.
0
 

Author Comment

by:denox
Comment Utility
please help me with this program expert.
0
 
LVL 1

Expert Comment

by:Fraction
Comment Utility
I'm sorry I missunderstood the quetion, I'm not sure if I understand the question now, but I think you want a method to parse values, and for that I suggest the Pos command:

procedure readfile;
var
  f1: textfile;
  i: integer;
  line, s: string;
  list: tstringList;
begin
  assignfile(f1, 'cdr.txt');
  reset(f1);
  list := tstringlist.create;
  while not(eof(f1)) do begin
    readln(f1, line);
    repeat
      i := pos(',', line);
      if i>0 then begin
        s := copy(line, 1, i-1); // parse data...
        list.add(s);             // ...into a stringlist
        delete(line, 1, i);
      end;
    until i=0;
  end;
  closefile(f1);
  { and do whatever you like with the stringlist }
end;
 
0
 
LVL 1

Expert Comment

by:pnh73
Comment Utility
No comment has been added lately, so it's time to clean up this TA.
I will leave a recommendation in the Cleanup topic area that this question is:

Accept answer from ITugay

Please leave any comments here within the next seven days.
 
PLEASE DO NOT ACCEPT THIS COMMENT AS AN ANSWER!
 
Paul (pnh73)
EE Cleanup Volunteer
0

Featured Post

IT, Stop Being Called Into Every Meeting

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

Join & Write a Comment

A lot of questions regard threads in Delphi.   One of the more specific questions is how to show progress of the thread.   Updating a progressbar from inside a thread is a mistake. A solution to this would be to send a synchronized message to the…
The uses clause is one of those things that just tends to grow and grow. Most of the time this is in the main form, as it's from this form that all others are called. If you have a big application (including many forms), the uses clause in the in…
Illustrator's Shape Builder tool will let you combine shapes visually and interactively. This video shows the Mac version, but the tool works the same way in Windows. To follow along with this video, you can draw your own shapes or download the file…
This demo shows you how to set up the containerized NetScaler CPX with NetScaler Management and Analytics System in a non-routable Mesos/Marathon environment for use with Micro-Services applications.

744 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

13 Experts available now in Live!

Get 1:1 Help Now