How do I read something from stdin in gforth and store it in a variable? - forth

I've tried the following code after reading the docs:
create buff 128 allot
buff 128 stdin read-line throw
I was hoping that this would get me a char for each successive address of buff, but I'm getting this weird number in there:
buff # ok
. 3689349013085184353 ok
What am I missing here?

buff put the address of your buff variable on the (data) stack. The memory by that address contained the input received from stdin, something like this:
Address Value
------- -----
N+0 0x61
N+1 0x61
N+2 0x61
N+3 0x61
N+4 0x61
N+5 0x33
N+6 0x33
N+7 0x33
... ...
The # word transformed the address left by buff into an integer value by that address. But since you've (apparently) got a 64-bit gforth version, # returned a 64-bit, i.e. 8-byte, value starting at the given address, i.e. 0x3333336161616161, which is 3689349013085184353 in decimal. The . word just showed you that number.
If you want to fetch a particular byte, use c# instead of #:
buff c# .
That'll give you the code of the first character in the buffer (0x61 or 97). If you want to get the second item, increment the address before executing c#, like this:
buff 1+ c# .
Similarly, this will get you the sixth character's code:
buff 5 + c# .

Related

Lua string manipulatuion

A string '321#322#323#324#325'.
here number of digits in each number is 3 but it's not limited to 3 it could be any number.
here are 5 numbers in a string but this number could be anything.
task is to get 321,322,323,324,325 and store in a table so that any operation could be performed over them.
I have tried several string functions like c = c:gsub('%W','') to eliminate those non-alphanumeric characters, but nothing helped.
function encrypter()--FUNCTION 14
c=' '
print('Please enter your message!')
local message=io.read()
lengthOfString=string.len(message)--Inbuit function to get length of a string.
newLine()
print('Please enter your key. Remember this key, otherwise your message wont be decrypted')
newLine()
key=io.read()
key=tonumber(key)
largeSpace()
print("Encrypted message is")
for s=1,lengthOfString do
--print(encryptionFormula(string.byte(message,s),key))
--inbuilt function for converting character of a string to it's respective ASCII value. First place gets character or variable having string whereas second place gets position of that character in the given string.
b=encryptionFormula(string.byte(message,s),key)
c=c..tostring(b)..'#'
--print(c)
b=0
end
print(c)
largeSpace()
print("Now share this message along with the key to the receiver. Don't share your key with anyone, if you don't want your message to be read.")
end
What you're looking for is string.gmatch().
local input = "123#546514#13#548#2315"
local numbers = {}
for number in string.gmatch(input, '%d+') do
table.insert(numbers, number)
end
-- Output the numbers
for index, number in ipairs(numbers) do
print(index, number)
-- This prints:
-- 1 123
-- 2 546514
-- 3 13
-- 4 548
-- 5 2315
end
If you don't know how Lua patterns work, you can read about them in the reference manual or you can have a look at Programming in Lua (the first edition is available for free on their website)

Parse array of unsigned integers in Julia 1.x.x

I am trying to open a binary file that I have some knowledge of its internal structure, and reinterpret it correctly in Julia. Let us say that I can load it already via:
arx=open("../axonbinaryfile.abf", "r")
databin=read(arx)
close(arx)
The data is loaded as an Array of UInt8, which I guess are bytes.
In the first 4 I can perform a simple Char conversion and it works:
head=databin[1:4]
map(Char, head)
4-element Array{Char,1}:
'A'
'B'
'F'
' '
Then it happens to be that in the positions 13-16 is an integer of 32 bytes waiting to be interpreted. How should I do that?
I have tried reinterpret() and Int32 as function, but to no avail.
You can use reinterpret(Int32, databin[13:16])[1]. The last [1] is needed, because reinterpret returns you a view.
Now note that read supports type passing. So if you first read 12 bytes of data from your file e.g. like this read(arx, 12) and then run read(arx, Int32) you will get the desired number without having to do any conversions or vector allocation.
Finally observe that what conversion to Char does in your code is converting a Unicode number to a character. I am not sure if this is exactly what you want (maybe it is). For example if the first byte read in has value 200 you will get:
julia> Char(200)
'È': Unicode U+00c8 (category Lu: Letter, uppercase)
EDIT one more comment is that when you do a conversion to Int32 of 4 bytes you should be sure to check if it should be encoded as big-endian or little-endian (see ENDIAN_BOM constant and ntoh, hton, ltoh, htol functions)
Here it is. Use view to avoid copying the data.
julia> dat = UInt8[65,66,67,68,0,0,2,40];
julia> Char.(view(dat,1:4))
4-element Array{Char,1}:
'A'
'B'
'C'
'D'
julia> reinterpret(Int32, view(dat,5:8))
1-element reinterpret(Int32, view(::Array{UInt8,1}, 5:8)):
671219712

Buffer Overflow Not Overflowing Return Address

Below is the C code
#include <stdio.h>
void read_input()
{
char input[512];
int c = 0;
while (read(0, input + c++,1) == 1);
}
int main ()
{
read_input();
printf("Done !\n");
return 0;
}
In the above code, there should be a buffer overflow of the array 'input'. The file we give it will have over 600 characters in it, all 2's ( ex. 2222222...) (btw, ascii of 2 is 32). However, when executing the code with the file, no segmentation fault is thrown, meaning program counter register was unchanged. Below is the screenshot of the memory of input array in gdb, highlighted is the address of the ebp (program counter) register, and its clear that it was skipped when writing:
LINK
The writing of the characters continues after the program counter, which is maybe why segmentation fault is not shown. Please explain why this is happening, and how to cause the program counter to overflow.
This is tricky! Both input[] and c are in stack, with c following the 512 bytes of input[]. Before you read the 513th byte, c=0x00000201 (513). But since input[] is over you are reading 0x32 (50) onto c that after reading is c=0x00000232 (562): in fact this is little endian and the least significative byte comes first in memory (if this was a big endian architecture it was c=0x32000201 - and it was going to segfault mostly for sure).
So you are actually jumping 562 - 513 = 49 bytes ahead. Than there is the ++ and they are 50. In fact you have exactly 50 bytes not overwritten with 0x32 (again... 0x3232ab64 is little endian. If you display memory as bytes instead of dwords you will see 0x64 0xab 0x32 0x32).
So you are writing in not assigned stack area. It doesn't segfault because it's in the process legal space (up to the imposed limit), and is not overwriting any vital information.
Nice example of how things can go horribly wrong without exploding! Is this a real life example or an assignment?
Ah yes... for the second question, try declaring c before input[], or c as static... in order not to overwrite it.

How read a pchar using ReadProcessMemory

I'm using the ReadProcessMemory function to read the content of an external running app, I have a memory address which points to a PChar(UNICODE). I'm wondering which is the proper way to get that value back to a string variable?
Now i'm using this code, but is not working
var
c : char;
repeat
if not ReadProcessMemory(ph, Address, #c, sizeof(c), BytesRead) then
raise exception.create(syserrormessage(getlasterror));
result:=result+c;
Address:=pointer(integer(address)+sizeof(c));
until (c=#0#0) or (BytesRead<>sizeof(c));
This error is raised
Only part of a ReadProcessMemory or WriteProcessMemory request was
completed
You are reading past the string: you are not reading bytes but chars, so compare the null terminator with a char, that is:
until (c=#0) or (BytesRead<>sizeof(c));
#0 is already 2 bytes,#0#0 is 4 bytes (it cannot be equal to any Char).
When you read past the string and "into an area of the process that is inaccessible" (as per the documentation) an error is returned.

Read numbers following a keyword into an array in Fortran 90 from a text file

I have many text files of this format
....
<snip>
'FOP' 0.19 1 24 1 25 7 8 /
'FOP' 0.18 1 24 1 25 9 11 /
/
TURX
560231
300244
70029
200250
645257
800191
900333
600334
770291
300335
220287
110262 /
SUBTRACT
'TURX' 'TURY'/
</snip>
......
where the portions I snipped off contain other various data in various formats. The file format is inconsistent (machine generated), the only thing one is assured of is the keyword TURX which may appear more than once. If it appears alone on one line, then the next few lines will contain numbers that I need to fetch into an array. The last number will have a space then a forward slash (/). I can then use this array in other operations afterwards.
How do I "search" or parse a file of unknown format in fortran, and how do I get a loop to fetch the rest of the data, please? I am really new to this and I HAVE to use fortran. Thanks.
Fortran 95 / 2003 have a lot of string and file handling features that make this easier.
For example, this code fragment to process a file of unknown length:
use iso_fortran_env
character (len=100) :: line
integer :: ReadCode
ReadLoop: do
read (75, '(A)', iostat=ReadCode ) line
if ( ReadCode /= 0 ) then
if ( ReadCode == iostat_end ) then
exit ReadLoop
else
write ( *, '( / "Error reading file: ", I0 )' ) ReadCode
stop
end if
end if
! code to process the line ....
end do ReadLoop
Then the "process the line" code can contain several sections depending on a logical variable "Have_TURX". If Have_TRUX is false you are "seeking" ... test whether the line contains "TURX". You could use a plain "==" if TURX is always at the start of the string, or for more generality you could use the intrinsic function "index" to test whether the string "line" contains TURX.
Once the program is in the mode Have_TRUX is true, then you use "internal I/O" to read the numeric value from the string. Since the integers have varying lengths and are left-justified, the easiest way is to use "list-directed I/O": combining these:
read (line, *) integer_variable
Then you could use the intrinsic function "index" again to test whether the string also contains a slash, in which case you change Have_TRUX to false and end reading mode.
If you need to put the numbers into an array, it might be necessary to read the file twice, or to backspace the file, because you will have to allocate the array, and you can't do that until you know the size of the array. Or you could pop the numbers into a linked list, then when you hit the slash allocate the array and fill it from the linked list. Or if there is a known maximum number of values you could use a temporary array, then transfer the numbers to an allocatable output array. This is assuming that you want the output argument of the subroutine be an allocatable array of the correct length, and the it returns one group of numbers per call:
integer, dimension (:), allocatable, intent (out) :: numbers
allocate (numbers (1: HowMany) )
P.S. There is a brief summary of the language features at http://en.wikipedia.org/wiki/Fortran_95_language_features and the gfortran manual has a summary of the intrinsic procedures, from which you can see what built in functions are available for string handling.
I'll give you a nudge in the right direction so that you can finish your project.
Some basics:
Do/While as you'll need some sort of loop
structure to loop through the file
and then over the numbers. There's
no for loop in Fortran, so use this
type.
Read
to read the strings.
To start you need something like this:
program readlines
implicit none
character (len=30) :: rdline
integer,dimension(1000) :: array
! This sets up a character array with 30 positions and an integer array with 1000
!
open(18,file='fileread.txt')
do
read(18,*) rdline
if (trim(rdline).eq.'TURX') exit !loop until the trimmed off portion matches TURX
end do
See this thread for way to turn your strings into integers.
Final edit: Looks like MSB has got most of what I just found out. The iostat argument of the read is the key to it. See this site for a sample program.
Here was my final way around it.
PROGRAM fetchnumbers
implicit none
character (len=50) ::line, numdata
logical ::is_numeric
integer ::I,iost,iost2,counter=0,number
integer, parameter :: long = selected_int_kind(10)
integer, dimension(1000)::numbers !Can the number of numbers be up to 1000?
open(20,file='inputfile.txt') !assuming file is in the same location as program
ReadLoop: do
read(20,*,iostat=iost) line !read data line by line
if (iost .LT. 0) exit !end of file reached before TURX was found
if (len_trim(line)==0) cycle ReadLoop !ignore empty lines
if (index(line, 'TURX').EQ.1) then !prepare to begin capturing
GetNumbers: do
read(20, *,iostat=iost2)numdata !read in the numbers one by one
if (.NOT.is_numeric(numdata)) exit !no more numbers to read
if (iost2 .LT. 0) exit !end of file reached while fetching numbers
read (numdata,*) number !read string value into a number
counter = counter + 1
Storeloop: do I =1,counter
if (I<counter) cycle StoreLoop
numbers(counter)=number !storing data into array
end do StoreLoop
end do GetNumbers
end if
end do ReadLoop
write(*,*) "Numbers are:"
do I=1,counter
write(*,'(I14)') numbers(I)
end do
END PROGRAM fetchnumbers
FUNCTION is_numeric(string)
IMPLICIT NONE
CHARACTER(len=*), INTENT(IN) :: string
LOGICAL :: is_numeric
REAL :: x
INTEGER :: e
is_numeric = .FALSE.
READ(string,*,IOSTAT=e) x
IF (e == 0) is_numeric = .TRUE.
END FUNCTION is_numeric

Resources