2019-10-03 17:26:41

I have a file that I would like to contain information for 3 arrays.

name, description, and money

Backslash determines name, carrot determines description, and ampersand determines money.

hello \Andrea^a beautiful young girl&2000
another person \Bob^a fat man&1000

Anything you write before the backslash is ignored. How can I split this file into the 3 arrays easily?

2019-10-03 17:41:10

this should go to dev room

2019-10-03 21:27:23

I don't know how that happened. Thanks for moving the topic. I deleted the dupicated topic in the dev room

2019-10-03 21:59:48 (edited by Rastislav Kish 2019-10-04 15:19:28)

Rofl.
Okay, to the actual solution, I think read_until method on file class is what you're searching for.
You just need to do something like:

string input=reader.read_until("\\^&\n", false);
if (input=="")
return;
string type=input[input.length()-1];

while (true)
{
input=reader.read_until("\\^&\n", false);
input=string_replace(input, "\r", ""); //I hope I wrote parameters in right order, check it in documentation if it doesn't work, i don't remember what was the exact declaration

if (input=="")
break;

string content=string_trim_right(input, 1);
if (type=="\\") //WE have a name
names.insert_last(content);
else if (type=="^") //We have a description
descriptions.insert_last(content);
else if (type=="&") //There is a money value
moneys.insert_last(content); //You will most likely have to parse here if moneys is array of ints, I don't remember how this was done in bgt, so you'll have to do it yourself. :)

type=input[input.length()-1];
}

I think it should work just fine, although I would myself make rather one array of classes, however, that's another topic. smile

Best regards

Rastislav

2019-10-03 23:08:52

what is the input.reader, and the char types thing?

Are they already declared for me?

May I have a better understandin of the functions of this code?

2019-10-04 07:11:11

first question, what type of variable is char type? I'm guessing string.

second question:

Line: chartype=input[input.lenght-1];
Error: 'lenght' is not a member of 'string'

Input is a string variable, but you are calling it as if it were an array index.

third question:

Line: if (type=='\\') //WE have a name
Error: 'type' is not declared

I am guessing this is also a string variable

2019-10-04 15:21:42 (edited by Rastislav Kish 2019-10-04 15:25:50)

Hi,
hmm, okay, I have forgotten that bgt doesn't have the char type, you are right of course.
In other languages, char is a well known type representing one character, it can be one byte in size as in C++ or two bytes, so it can hold unicode characters like in C#. Strings are then internally just arrays of char type, so you can access any character using its index.
Bgt works internally in the same way, that's why you can access characters in strings using indexes i.e.

string message="Mammoths like chocolate.";
alert("Announcement", "Chocolate starts with "+message[14]+". What a surprise.";

Just in bgt you don't receive char type, but another string containing one character, for some mysterious reason.
The length is meaned to be the string length, although again just meaned as bgt doesn't represent this with a property, but with a method, plus I have written lenght instead of length, dumb me.
So instead of input.length, there should be input.length().

reader is an instance of file class, i.e.

file reader;
reader.open("filetoread.txt", "r");

I didn't specified it explicitly as I was mentioning the file class in connection to read_until method, you can find both in bgt's documentation.

And of course, as you work with strings, ignore my apostrophes and use quotes instead.

Sorry for these mistakes, I haven't worked with bgt for a quite long time, so I have forgotten some details about it. smile
I have edited my post, with fix of all of these.

Best regards

Rastislav

2019-10-05 06:52:44

Hi, your new code works. Thank you so much for helping. One question. I thought read_until only reads the first occurrance and not the whole file. I have always been nervous to use the read_until because I am unsure of whether it finds each occurrance or only the first one

2019-10-05 16:33:34

I would just have read the entire file, used string_split to break it into lines[1], then split the lines around the separators. I'd normally use one separator, and have the arguments in the same order, but there's no reason you can't have more than one.
Alternatively, use string_contains to find the index of the separators, and string_left, string_right, and string_mid to get the parts you want.
[1] Windows line-breaks had to be different from everyone else, so this is more annoying than it needs to be. I can never remember which text editors are \n, \r, \n\r, or \r\n, so I just string_replace \r to \n. All the Real Programmers™ will probably be along shortly to point out how uncool this makes me, but whatever.

If you got the read_until strategy working without issues, feel free to ignore this. I just find it easier to work with the whole thing at once.

看過來!
"If you want utopia but reality gives you Lovecraft, you don't give up, you carve your utopia out of the corpses of dead gods."
MaxAngor wrote:
    George... Don't do that.

2019-10-05 17:59:06

Hi there,
@8: I'm glad that it helped. smile
Well, you can imagine reading from a file like getting water from a watertank using a tap. You open it, let the water flow, and close after some time, and do it again and again, being less and less water in the tank until it definitely get empty.
Situation with the file reading is the same. When you call read_until, file is being read until a position of string, which you're searching for is approached.
Then whole read content is returned to you. When you call it again, it continues from that position to another occurrance of searched string, again returning to you what has been read.
When you call this again and again, as you can see in the while loop, then you will one time get to end of the file i.e. there is nothing more to read, and empty string is returned. Like in the watertank, you were getting water by parts and when you get all of it, there is nothing more to take.
Also read method works in the same fashion, only difference is that it doesn't search for a string, but get as parameter number of characters to read. So if you have a 50 characters long file, you can call read method with 10 characters 5 times until you get everything from the file.

This approach of getting data in chunks from some continuous source is called stream, and is widely used in many programming languages like C/C++, C#, Python etc. for example to retrieve user input from a console, to communicate with a bluetooth device, to have a streamed internet communication etc.

@9: yup, that would work as well, assuming that every line contains all three signs in exact expected order.
In other case, to solve mixed order it would be necessary to a. create a signs map for every row, which would find out used order of signs or b. check both strings after splitting if they contain next character to split by.
First option would be easier, although still bit messy to do something to prevent arrays nesting caused by output of the string_split function called in a loop.
In this light, searching for indexes and copying seems more elegant, if made properly it should work quite well.
it's infact the same approach as the stream way. I personally like streams more in this case, but it's a personal subjective choice.
Sadly it won't work in case that the list is received by network, as bgt doesn't have a memorystream, so in that case, string_mid would be really only efficient solution how to do it.

Best regards

Rastislav