Detecting end of string character

Previous topic - Next topic

FutureCow

This is just for interest reasons. I'm wondering why the following doesn't work (assuming all you typed was the enter key)
Code (glbasic) Select
input string$,0,0
if mid$(string$,0,1) = CHR$(0)

...

but the following will work
Code (glbasic) Select
input string$,0,0
if mid$(string$,0,1) = "\0"


The second option is fine for my code, but I'm curious as to why the first one won't work as well.

Moru

Don't rely on zero terminated strings in basic :-)

FutureCow

I'm not relying on it, but my text input routine is checking for it as an end of string character. Why does one command pick it up but the other one not?

Moru

Mabe you are testing behind the end of the string and it just happens to be a zero there at the moment?

Kitty Hello

the ="\0" will compare to an empty string.

FutureCow

Sorry Gernot, I don't understand what you mean. The "\0" is being added by the 'INPUT' command when you hit the enter key.

Here's some test code.
Try it as is, then swap the comment on these two lines. When the comparrison is "CHR$(0)" the \0 character isn't detected and the code thinks you've typed an invalid character, but it works if you change it to check for '\0'

These are the lines to swap the comment on
Code (glbasic) Select
IF Char$ = CHR$(0)
// IF Char$ = "\0"


Test code
Code (glbasic) Select
TestFunc()

FUNCTION TestFunc:
LOCAL FinalString$
LOCAL MyString$
LOCAL Char$
LOCAL Loop

PRINT "Type in a string",0,0
INPUT MyString$,0,50
FOR Loop = 0 TO LEN(MyString$)
Char$=MID$(MyString$,Loop,1)
IF Char$ = CHR$(0)
// IF Char$ = "\0"
PRINT "\\0 found",0,150
SHOWSCREEN
SLEEP 2000
RETURN 2
ELSEIF Char$ < "0" OR Char$ > "9"
PRINT "Error - illegal character " + Char$ + " found at position " + (Loop+1) + ". Only 0-9 accepted.\n",0,100
PRINT "ASC = " + ASC(Char$) + "\n",0,200
SHOWSCREEN
SLEEP 2000
RETURN 1
ELSE
FinalString$=FinalString$ + Char$
ENDIF
NEXT
PRINT "Final String = "+FinalString$,0,200
SHOWSCREEN
SLEEP 2000
ENDFUNCTION


Kitty Hello

   FOR Loop = 0 TO LEN(MyString$)


must be LEN(MyString$) - 1. You have a string:
"012", length=3. Character at position 3 = '\0', but that's just to be compatible with C APIs.

FutureCow

All good - but isn't '\0' the same as CHR$(0)? That was why I was confused - I thought both would have detected the NUL character.

Kitty Hello

OK.
INPUT does not append a chr$(0) to your string. Internally there is this character to ensure you can use the string pointer as a C string as it is required in many C functions (sprintf e.g.).
On the GLBasic side of the code, there is no "\0" character. The string "012" is 3 characters long "0", "1" and "2". That's it. Accessing anything beyond that will not work.
Now, MID$("012", 3, 1) will return "" (empty string), and if you compare that to chr$("\0"), the C function strcmp will return 0 (equal) because both strings are 0 length and thus equal.
It might be bad to use strcmp in the first place, because chr$(0) actually is a binary "string" that really is 1 character long - my fault here.

Could you follow this far?

Back to your problem: INPUT does not append any newline character. If you press the enter key, INKEY$() will return "\n", though. But not INPUT.

What are you trying to achieve in detail?

Hatonastick

#9
I'd written a program myself to work out what was going on and had just written a long reply when the forum system informed me there were two replies.  Reading Gernots made my post completely moot.  Oh well.  It was a fun exercise all the same. :)

I'm guessing it relates to this post?
http://www.glbasic.com/forum/index.php?topic=4086.0

FutureCow

Thanks Gernot (and Hatonastick!) That explaination makes my issue make a lot more sense now.

What I was trying to achieve : For my boardgame's network mode I wrote a little function to parse an IP address you type in. The input is received from the user using the "INPUT" command (it's not the way I wanted to do it as it stops the rest of the program while it waits for input, but it was quicker to implement than writing my own function with INKEY$() and I needed something in a hurry - the deadline for the competition is close after all!  =D).

My code does a character by character check to make sure that the string you typed in is in the right format (a.b.c.d), that you have only typed in numbers for a/b/c/d, and that a/b/c/d are in the range 0-255. It loops across each of the characters using "LEN(MyString$)" so it was reading a '\0' character at the end. I'd tried searching for '\n' thinking that was the character that wasn't matching my comparrisons (0-9 or '.') - but eventually found it was the '\0' character.

As I'd originally tried checking if the character was a 'CHR$(0)' character and that didn't work, I was wondering why it didn't work but a check for '\0' did as they should effectively be the same thing.

It's all good now, I just wanted to know why there was a difference between the two. Is this likely to change (ie. are you likely to change from using strcmp?) as otherwise I might add something to the online notes about it.

Moru

Strings in basic is never supposed to be zero-terminated so I think you can safely add something to the online notes that comparing strings with chr$(zero) in them is not recommended in GLBasic :-)

Kitty Hello

OK, just a few suggestions:

1) Use Splitstr(inp$, array$[], "."); IF LEN(array$[]) <> 4 THEN erro("wrong IP"); then parse the 4 ip tokens.
2) Ignore any characters, just connect. You can connect to "PC-GF", since that resolves to 192.168.178.23 on my LAN.
3) Use DDGui for input:
     ip$ = DDgui_input$(ip$, FALSE);
   
or make your own dialog (if you don't want the keyboard)
Code (glbasic) Select

DDgui_pushdialog(0,0,400,400)
ddgui_widget("", "Enter the IP")
ddgui_text("tx_ip", ip_default$, 300)
ddgui_button("bt_ok", "OK")
while true
   ddgui_show()
   showscreen
   if ddgui_get("bt_ok", "CLICKED") then break
wend

the_ip$ = ddgui_get("tx_ip", "TEXT")


Really, DDgui as ugly as it may seem, is very easy to use.


Moru

I'm using DDGui for just this reason in one of my network tests. Possible Scribble. I just allow anything since the connect string can be either an IP-number, domain address or just a computer name on your local lan. Or localhost for testing on the same computer.