View Full Version : Getting info to and from textfiles
06 June 2003, 11:57 AM
Having fun with writing to textfiles.
With some help I got the reading in bit sorted.
I've reread and reread the help file but can't work out how you write back to a file.
Attached are the ideas and functions.
The reason for the array is so that I can easily change scopes later for rollouts etc.
The variables will be all sorts of different sorts - strings, integers and floats.
The main reason for this is to implement a load and save defaults function in a rollout.
v_count is just so I can easily add and delete variables without changing the loops.
06 June 2003, 12:17 PM
A fast an easy way to store settings with your script are the setINISetting and getINISetting commands.
If you still want to use your method:
createFile returns the handler to the created file (just like openFile, so you don't need to call openFile afterwards).
So, in your case you could say:
-- you need the fileStream value to read/write a file
-- <fileHandler> is just a variable-name I made up
fileHandler = createFile savname
-- createFile returns undefined if the file
-- could not be created
if fileHandler != undefined then
format "Some String..\n" to:fileHandler
-- close the file when all writing is done..
) else (
messagebox "Unable to create file!"
Hope this helps
06 June 2003, 03:10 PM
OK here's my take on this for the saving of an array to a tab delimited text file - still not working :(
Had a look at the INI method but need the flexibility of an open array for now.........until the whole floater is completed and I know the total variable structure.
Here's the error message:
-- Error occurred in def_save()
-- v_array: #(1, 2, 3, 4)
-- No "map" function for 4
06 June 2003, 03:26 PM
Please post the script again so I can see what the def_save() function does.
06 June 2003, 03:31 PM
oops here it is:
06 June 2003, 03:45 PM
There's a little typo in this line:
for i in v_array.count do
for i = 1 to v_array.count do
or you could change the loop as follows:
for i in v_array do
format "%\t" (i as string) to:fh
I've attached a quickly adapted script..
06 June 2003, 10:01 AM
That seems to work. I've now got an array of values in v_array.
As part of the load defaults section, whats the best way to get these back into a floater as say spinner values across two rollouts?
At this point all the values in v_array are strings. I'm interested in how you would structure the script in terms of variable scope, and making sure that v_array is able to be updated and then saved out again.
I've tried this several ways including using structures for the variables and am getting very confused, so its principles that are needed at this stage.
06 June 2003, 10:30 AM
To convert your string <v_array> to an actual array, you can use:
v_array = execute v_array
note: the execute statement can slow down your script when used repeatedly
Another way to read the value from the file and directly convert it to a string:
(i suppose you now use readLine to read your file)
This reads AND evaluates the next MAXScript expression from the file..
So if your file looks like:
#(false, false, true, false)
and you read the file using readExpr, it will return the actual arrays, NOT strings
fileHandler = openFile "test.txt"
while not (eof fileHandler) do
-- read the string and evaluate it, the result
-- is stored in <v_array>
v_array = readExpr fl
for the readExpr statement to work properly, your file has to be formatted like a regular script (statements seperated by a ; or a CRLF)..
06 June 2003, 10:48 AM
Thanks again Martijn,
I'll check out the readExpr stuff. In the meantime here is a script which shows a bit better what I am trying to do.
I think there are problems with the way I have structured it in terms of scope as well as the problem of getting the variables to and from the array(s)
06 June 2003, 11:24 AM
One thing about global versus local variables; globals are stored through an entire max-session, while locals only exist in the scope in which they were created.
in the line:
global defname = getOpenFileName ...
you don't need to use a global variable here, as it is only used in the scope it is created in:
local defname = getOpenFileName ...
about your script;
- put the structure definitions outside of the script scope (put it above the first '('.
- use locals instead of globals where possible.
- v_array is an empty array and doesn't get filled anywhere in the script, so the save function will always output an empty file.. You'll probably want to fill the array with the vvmvars variables before saving the file..
06 June 2003, 11:56 AM
OK I get the difference between global and local and broadly the scope of each of these. Where I am getting confused is the the use of the structure instance. I presume that when a spinner is changed the new value is stored in the instanced structure. There are two of these, so the question then becomes which to use or how to combine them. (or use them at all - go back to using a list of locals at the start of the script?
I'm beginning to think that the use of a structure for the variables is causing more harm than good! Why does it need to be outside the main scope of the script? Should I call a single instance at the start rather then one for each rollout?
Whats the best way of filling the array with an uptodate list of the variables (and making sure that these in turn are kept up to date in one place)?
06 June 2003, 02:53 PM
For the functions def_parse and def_save I wouldn't use structs because it doesn't add any functionality..
I've attached a modified script... It's not the most efficient way to do this though...
The vvmvars structure holds all variables.. BUT, the UI items ALSO hold all variables... so basically you store the vars 2 times.. Instead, you also could save the UI values directly, and get rid of the vvmvars structure.....
Also, in your case I think it's best to use setINIsetting & getINIsetting.
06 June 2003, 11:27 AM
Thanks again Martijn,
I've tried using the getpropnames function on the structure instance and for some reason it messes up the order of the variables - any ideas.
06 June 2003, 03:29 PM
Getting too complicated to manage when scaled up so I've gone down the ini file route.............just a quick question:
the getINISetting command returns a string.....whats the best way of converting this to a boolean value apart from using an if statement and return?
06 June 2003, 08:55 PM
Originally posted by Alex Morris
whats the best way of converting this to a boolean value apart from using an if statement and return?
myValue = "true"
myValue = execute myValue
06 June 2003, 05:25 PM
Getting a Boolean value from an .ini file.
setINIsetting "D:\\temp\\tester.ini" "Catagory" "DataItem" (TrueorFalse as string)
a=( getINIsetting "D:\\temp\\tester.ini" "Catagory" "DataItem" == "true" )
One of many....
06 June 2003, 02:35 PM
You can also do;
a = execute (getINISetting...)
06 June 2003, 11:05 PM
QUOTING FROM MAXSCRIPT BOOK
INI files I/O
INI files are easier to manage through MaxScript because you will not need to worry about opening and closing files. All you will need to do is ask MaxScript to read or write the information you need and it will be written using the INI command.
The two commands used to manipulate INI files are getinisetting and setinisetting. They need the filename, the section, and the key. This is how an INI file looks:
key01 = value01
key02 = value02
For example, getinisetting (getdir #maxroot + "\\3dsmax.ini") "Render Dialog Position" "Dimension" returns the position and dimension of the render dialog box, which is saved to the INI file.
You can create INI files to store your script's date. For example, setinisetting(getdir #plugcfg + "\\sample.cfg") "settings" "reload" "true" creates a new file and writes the specified data to it.
Sorry if this is offtopic. Just thought it would help
01 January 2006, 11:00 AM
This thread has been automatically closed as it remained inactive for 12 months. If you wish to continue the discussion, please create a new thread in the appropriate forum.