Runerror(0) and Runerror(2) lazarus / 9-Editor ---------------------------------------------------------------------- Mr. Killer · 2010-09-23 22:27 Hi everybody. First time here, Anyways, I have problems with this small piece of code: Code: [Select]program project1; var    arch : text;    number : byte; begin      assignfile(arch,'Data1.txt');      reset(arch);      while not eof(arch) do      begin      readln(arch,number);      writeln(number);      end;      closefile(arch); end. what this program is supposed to do is just read a file (Data1.txt) which only has numbers in it and show them in the screen. Now, the problems are: 1) when I run the program, I get a Runerror(0) and it stops. 2)if I go step by step, the program stops at line 10 (the one that says reset(arch)) and I get a Runerror(2). The file is located with the program in the same place. I tried putting the whole route instead of just the name, but it doesn't work either. By the way, I have windows 7 home premium 32 bits. Perhaps a compatibility issue? Or is it perhaps just a noob mistake? (don't have too much experience with pascal). Any help would be appreciated. Thanks!! ---------------------------------------------------------------------- typo · 2010-09-23 22:38 Try this: Code: [Select]var    arch : TextFile; ---------------------------------------------------------------------- Mr. Killer · 2010-09-23 22:52 Quote from: typo on September 24, 2010, 12:38:35 amTry this: Code: [Select]var    arch : TextFile; it doesnt work either ---------------------------------------------------------------------- typo · 2010-09-23 22:54 Try to use TFileStream. Code: [Select]unit UTextFileStream; {$mode Delphi}{$H+} interface uses Classes, SysUtils, Dialogs; type   TTextFileStream = class(TFileStream)   private     FBuffer: string;     //FLineLength :integer;   public     function Eof: Boolean;     function WriteLn(Text: string):int64;     function ReadLn: string;     function Seek(const Offset: Int64; Origin: TSeekOrigin): Int64; override;     function RowCount: Integer;     function EditLine(Line :integer; NewText :string):string;   end; implementation { TTextFileStream } const   NewLine = #13#10; function TTextFileStream.Eof: Boolean; begin   Eof := Position - Length(FBuffer) = Size; end; function TTextFileStream.ReadLn: string; const   BufferLength = 10000; var   NewBuffer: string;   Readed: Integer; begin   Readed := 1;   while (Pos(#13, FBuffer) = 0) and (Readed > 0) do begin     SetLength(NewBuffer, BufferLength + 2);     Readed := Read(NewBuffer[1], BufferLength);     SetLength(NewBuffer, Readed);     FBuffer := FBuffer + NewBuffer;   end;   if Pos(#13, FBuffer) > 0 then begin     Result := Copy(FBuffer, 1, Pos(#13, FBuffer) - 1);     Delete(FBuffer, 1, Pos(#13, FBuffer) + 1);   end else begin     Result := FBuffer;     FBuffer := '';   end; end; function TTextFileStream.RowCount: Integer; begin   Result := 0;   FBuffer := '';   Seek(0, soBeginning);   while not Eof do begin     ReadLn;     Inc(Result);   end;   Seek(0, soBeginning); end; function TTextFileStream.Seek(const Offset: Int64;   Origin: TSeekOrigin): Int64; begin   if Origin = soCurrent then     Result := inherited Seek(Offset - Length(FBuffer), Origin)     else Result := inherited Seek(Offset, Origin);   FBuffer := ''; end; function TTextFileStream.WriteLn(Text: string):int64; begin   Result := 0;   Seek(0, soEnd);   if Seek(0, soCurrent) > 0 then     Write(NewLine, Length(NewLine));   Write(Text[1], Length(Text));   Result := RowCount; end; function TTextFileStream.EditLine(Line :integer; NewText :string):string; var   n :integer;   s :string;   Buffer :string;   BytesRead :integer;   FileLength :integer;   FilePos :integer; begin   Result := '';   n := 0;   s := '';   BytesRead := 1;   FilePos := 0;   while (n <= Line) and not Eof do   begin     s := Readln;     Inc(n);     FilePos := FilePos + Length(s) + Length(NewLine);   end;   if Line >= n then     raise Exception.Create('Line index out of bounds.');   //FilePos := Position;   FileLength := Seek(0, soEnd);   Seek(FilePos, soBeginning);   SetLength(Buffer, FileLength + Length(NewLine));   BytesRead := Read(Buffer[1], FileLength - FilePos);   SetLength(Buffer, BytesRead);   NewText := NewText + NewLine;   Seek(int64(FilePos) - int64(Length(s)) - int64(Length(NewLine)), soBeginning);   Write(NewText[1], Length(NewText));   Write(Buffer[1], BytesRead);   SetSize(FilePos - Length(s) - Length(NewLine) + BytesRead + Length(NewText));   Result := s; end; end.    Code: [Select]var   fs :TTextFileStream; begin   fs := TTextFileStream.Create('Data1.txt', fmOpenReadWrite);   try     fs.WriteLn('Text');   finally     fs.Free;   end; ---------------------------------------------------------------------- Mr. Killer · 2010-09-24 00:16 wow now that's a long code   ... thanks, I'll try that and see if it works. However, I still wonder why the original code didn't work ... I'll try to run the program in other computers with different operating systems, I dont know why but I have the feeling it's windows 7's fault. Once again, thanks a lot! ---------------------------------------------------------------------- typo · 2010-09-24 00:21 Because of backwards compatibility, there is a lot of Assign, AssignFile, Close, CloseFile, FileClose, spread on a lot of units and they are not always compatible with each other. ---------------------------------------------------------------------- Bart · 2010-09-25 08:55 This slightly modified version runs just fine Code: [Select]bart@simenon:~/LazarusProjecten/ConsoleProjecten> cat test.pp PROGRAM test; {$mode objfpc}{$H+} var    arch : text;    number : byte;    NumRead: Integer; //Counter for how many numbers we have read begin   AssignFile(arch, '/home/bart/LazarusProjecten/ConsoleProjecten/data1.txt');   reset(arch);   NumRead := 0;   while not eof(arch) do   begin     readln(arch,number);     Inc(NumRead);     writeln(NumRead:3,': ',number);   end;   closefile(arch); end. bart@simenon:~/LazarusProjecten/ConsoleProjecten> fpc test.pp Free Pascal Compiler version 2.4.0 [2009/12/28] for i386 Copyright (c) 1993-2009 by Florian Klaempfl Target OS: Linux for i386 Compiling test.pp Linking test 26 lines compiled, 0.4 sec The contenst of data1.txt: Code: [Select]bart@simenon:~/LazarusProjecten/ConsoleProjecten> cat data1.txt 1 11 123 255 $10 Now running the program: Code: [Select]bart@simenon:~/LazarusProjecten/ConsoleProjecten> ./test   1: 1   2: 11   3: 123   4: 255   5: 16 bart@simenon:~/LazarusProjecten/ConsoleProjecten> Some remarks If there is more then 1 number on a line, only the first one is readIf a line is not (or does not start with) a number, a runtime error 106 occurs upon reading that lineIf the number is out of range for byte, the behaviour depends on wether or not range checking is enabledAn empty line is read as 0 Anyhow, if the data is valid, and the you have read access to the file, your program should run just fine. It might however become more robust if you do not try to read the bytes directly, but read (readln) a string and then parse that string to see if there is a "valid byte" (you can use Val() or (Try)StrToInt() for that. If the data1.txt file is not too big you can also use a TStringList to read in the entire contents, then iterate the stringlist to get the bytes you want. An example: Code: [Select]bart@simenon:~/LazarusProjecten/ConsoleProjecten> cat test.pp PROGRAM test; {$mode objfpc}{$H+} uses sysutils, classes; var   SL: TStringList;   Count, ErrorCode: Integer;   B: Byte; begin   SL := TStringList.Create;   try     SL.LoadFromFile('/home/bart/LazarusProjecten/ConsoleProjecten/data 1.txt');     for Count := 0 to SL.Count - 1 {zero based index!} do     begin       Val(Sl.Strings[Count],B,ErrorCode);       if ErrorCode = 0 then         writeln(Count:2,': ',B)      else        writeln(Count:2,': Error: ',SL.Strings[Count],' is not a byte value');     end;   finally     //make sure we always free the memory     SL.Free   end; end. bart@simenon:~/LazarusProjecten/ConsoleProjecten> fpc test.pp Free Pascal Compiler version 2.4.0 [2009/12/28] for i386 Copyright (c) 1993-2009 by Florian Klaempfl Target OS: Linux for i386 Compiling test.pp Linking test 29 lines compiled, 1.2 sec The contenst of data1.txt: Code: [Select]bart@simenon:~/LazarusProjecten/ConsoleProjecten> cat data1.txt 1 11 123 255 $10 -1 AAA bart@simenon:~/LazarusProjecten/ConsoleProjecten> Now running the program: Code: [Select]bart@simenon:~/LazarusProjecten/ConsoleProjecten> ./test  0: 1  1: 11  2: 123  3: 255  4: 16  5: Error: -1 is not a byte value  6: Error: AAA is not a byte value bart@simenon:~/LazarusProjecten/ConsoleProjecten>  NB. I used Val() instead of TryStrToInt, because TryStrToInt expects a LongInt, not a Byte as the second parameter. Bart ---------------------------------------------------------------------- Mr. Killer · 2010-09-28 03:12 Hi again. Thanks for the alternative codes guys, but I really wanna know WHY the original code didn't work. I will be doing similar programs with similar codes in the near future, so I need to know why the code didn't work. I can't use the alternative codes you guys gave me yet. The reason is I'm taking a Pascal course at college and whenever we have to use a file, we must read/modify it the way it was shown in my original code. So far, I have the feeling it's windows 7's fault. If you guys have any idea, please post it here. Sorry for being this annoying but I must really know why the program is not working. Thanks! ---------------------------------------------------------------------- cdbc · 2010-09-28 04:33 Hi Here you'll find the error codes for pascal: http://www.frameworkpascal.com/helphtml/run_errors.htm or here: http://community.freepascal.org:10000/docs- html/user/userch14.html Maybe your problem is related to access rights, it seems your program cannot find the file...?!? (rte 2). hth - Regards Benny ---------------------------------------------------------------------- Bart · 2010-09-28 08:19 Your original code should run just fine as long as it can find the file (and the file has valid content). The way you assign the file 'Data1.txt' makes the program look for that file in the current directory, that is the directory from which the program was launched (or, if it is started from a windows shortcut, the directory that is specified in the appropriate field in that shortcut). I have no idea wether launching the program from within the IDE will correctly set the current directory to be the directory where your 'Data1.txt' resides. If 'Data1.txt' is not in the current directory, an IO Error occurs with errorcode 2. Because this error is not handled by you, this will trigger a Runtime Error (RTE) 2. I have no explanation for the RTE 0 that you have experienced. Bart ---------------------------------------------------------------------- typo · 2010-09-28 14:20 I have tried your code and have no runtime error. ---------------------------------------------------------------------- Mr. Killer · 2010-09-28 15:06 Quote from: typo on September 28, 2010, 04:20:41 pmI have tried your code and have no runtime error. what operating system are you using?? ... and yes, the data1 file is in the same directory as the program. like cdbc said, it may be an access rights issue, i'll look into that. ---------------------------------------------------------------------- typo · 2010-09-28 15:10 Windows XP, Lazarus 0.9.29 r24105 FPC 2.4.0 i386-win32-win32/win64. ---------------------------------------------------------------------- Bart · 2010-09-28 16:05 Quote from: Mr. Killer on September 28, 2010, 05:06:36 pm... and yes, the data1 file is in the same directory as the program. like cdbc said, it may be an access rights issue, i'll look into that. An access problem should give you a runtime error 5 (Access denied). The fact that your data file is in the same directory as the program is irrelevant. The data file must be in the current active directory, which so far you have not confirmed it is. Switch to a console (Start->Run->cmd.exe) cd to the directory that the datafile is in (and as you say, in your case, that is also where the executable is). Now from the commandline start the program and it should find your data file. If it does not the try something like: Code: [Select]  ...   writeln(ExpandFileName('Data1.txt'));   ... This tells you where your program thinks that 'Data1.txt' actually should be. (You need to use SysUtils unit for this function) There is also the very nice function FileExists() in SysUtils which will return True or False depending on wether the file is actually there or not. Code: [Select]   ...   if not FileExists('Data1.txt') then   begin     writeln('File not found: ',ExpandFileName('Data1.txt'));     Halt; //Stop the program   end;   ... Bart ---------------------------------------------------------------------- Mr. Killer · 2010-09-28 16:32 OK I tried placing the file in the current directory. No results. Then I tried opening the program from the console. It didn't work either. gonna try the expandfilename thing right now. thanks. ---------------------------------------------------------------------- Mr. Killer · 2010-09-28 17:41 Sorry for asking this, but could you tell me how to use SysUtils, or write the code for me?? I'm a complete noob at pascal ---------------------------------------------------------------------- typo · 2010-09-28 17:45 SysUtils is a unit, http://lazarus- ccr.sourceforge.net/docs/rtl/sysutils/index-5.html ---------------------------------------------------------------------- Mr. Killer · 2010-09-28 18:22 Ok I've just tried to use ExpandFileName. don't know if I did it the right way. this is the code I tried, please check if it's correct: Code: [Select]program project1; uses sysutils; var    arch : TextFile;    number : byte; begin      assignfile(arch,'Data1.txt');      writeln(ExpandFileName('Data1.txt'));      readln;      reset(arch);      while not eof(arch) do      begin      read(arch,number);      writeln(number);      end;      closefile(arch);      readln; end.               and this is what the screen shows: Code: [Select]C:\Users\username\Documents\ejercicios pascal\Data1.txt "ejercicios pascal" is the directory where the program and the file are located. This is the code used to see if the file can be found (again, don't know if it's correct ): Code: [Select]program project1; uses sysutils; var    arch : TextFile;    number : byte; begin      assignfile(arch,'Data1.txt');      if not FileExists('Data1.txt') then      begin      writeln('File not found: ',ExpandFileName('Data1.txt'));      readln;      end;      reset(arch);      while not eof(arch) do      begin      read(arch,number);      writeln(number);      end;      closefile(arch);      readln; end.  and what I get is: FILE NOT FOUND ---------------------------------------------------------------------- typo · 2010-09-28 18:33 Have you created the file? ---------------------------------------------------------------------- Mr. Killer · 2010-09-28 18:35 yes. the file has always been there since I started this thread. and what does Runerror(0) mean? I can't find it in the error table. ---------------------------------------------------------------------- typo · 2010-09-28 18:45 Direct accesss to files is rarely used in Lazarus. TFileStream is better. ---------------------------------------------------------------------- Mr. Killer · 2010-09-28 18:53 guess what: I've just found out what the error was. the file name was "Data1.txt". what I did is change the name to just "Data1", and then it worked (in the code, I'm still using "Data1.txt" as the file name though). I've always been taught that the file should have ".txt" at the end of its name, it worked in windows xp, but it seems that in windows7 you must avoid ".txt". ... I knew it was a stupid noob's mistake I apologize guys, I feel so stupid for making this mistake. This thread can be closed now. and thanks for all your patience and time trying to solve my problem. (I still wonder what runerror(0) means. probably something like: "you are a big noob") ---------------------------------------------------------------------- typo · 2010-09-28 18:58 They mean an I/O problem. http://www.lazarus.freepascal.org/index.php/topic,8724.0.html http://www.delphifaq.com/faq/delphi/delphi_ide/f153.shtml ---------------------------------------------------------------------- theo · 2010-09-28 19:06 Quote from: Mr. Killer on September 28, 2010, 08:53:45 pmI've always been taught that the file should have ".txt" at the end of its name, it worked in windows xp, but it seems that in windows7 you must avoid ".txt". The extension is probably just hidden in explorer. The filename you had before was probably "Data1.txt.txt" actually. ---------------------------------------------------------------------- Mr. Killer · 2010-09-28 19:10 Quote from: theo on September 28, 2010, 09:06:09 pmThe filename you had before was probably "Data1.txt.txt" actually. yeah that's what I was thinking. that doesn't happen in windows xp as far as I know. my pascal classes are always taught in windows xp, but I practice in a laptop with windows 7. well, you learn something new everyday i guess ---------------------------------------------------------------------- Bart · 2010-09-28 20:24 Glad you solved it. It's one of Windows quircks. By default the option "do not show file-extension for known filetypes" (don't know the exact frase in English) is turned on. It is the first thing I do in every Windows I have to work with: make Explorer show extensions on all files. Win7 is even worse. The filename you see in Explorer isn't even the real filename on disk (at least not always, especially in non-English versions) Back to coding. Try this (just for fun now): Code: [Select]  ...   AssignFile(Arch,ParamStr(1));   ... Now from the explorer drag and drop 'Data1.txt' (actually 'Data1.txt.txt') onto the executable (the file, not the running program) and see it being processed ... Magic huh? Bart ---------------------------------------------------------------------- lacuentadeolo · 2011-06-11 05:09 Quote from: Mr. Killer on September 24, 2010, 12:27:03 amHi everybody. First time here, Anyways, I have problems with this small piece of code: Code: [Select]program project1; var    arch : text;    number : byte; begin      assignfile(arch,'Data1.txt');      reset(arch);      while not eof(arch) do      begin      readln(arch,number);      writeln(number);      end;      closefile(arch); end. what this program is supposed to do is just read a file (Data1.txt) which only has numbers in it and show them in the screen. Now, the problems are: 1) when I run the program, I get a Runerror(0) and it stops. 2)if I go step by step, the program stops at line 10 (the one that says reset(arch)) and I get a Runerror(2). The file is located with the program in the same place. I tried putting the whole route instead of just the name, but it doesn't work either. By the way, I have windows 7 home premium 32 bits. Perhaps a compatibility issue? Or is it perhaps just a noob mistake? (don't have too much experience with pascal). Any help would be appreciated. Thanks!! alright, that means file was not found. do this: create a little program, program projec3t1; {$mode tp}{$x-} uses sysutils; var f1:text; begin assign (f1,'text.dat'); rewrite(f1); write(f1,'a'); close(f1); end. then runn it. go to your explorer browser, and browse text.dat it could be saved in a temporary folder. then you just have to copy your file data1.txt into that folder and try running it. i used to have the same problem ^^.