Solved

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

Posted on 2002-05-26
5
176 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
ID: 7035938
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
ID: 7036723
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
ID: 7046673
please help me with this program expert.
0
 
LVL 1

Expert Comment

by:Fraction
ID: 7047583
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
ID: 9006878
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

Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

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…
Introduction The parallel port is a very commonly known port, it was widely used to connect a printer to the PC, if you look at the back of your computer, for those who don't have newer computers, there will be a port with 25 pins and a small print…
This Micro Tutorial hows how you can integrate  Mac OSX to a Windows Active Directory Domain. Apple has made it easy to allow users to bind their macs to a windows domain with relative ease. The following video show how to bind OSX Mavericks to …
Many functions in Excel can make decisions. The most simple of these is the IF function: it returns a value depending on whether a condition you describe is true or false. Once you get the hang of using the IF function, you will find it easier to us…

920 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

15 Experts available now in Live!

Get 1:1 Help Now