Announcement

Collapse
No announcement yet.

Chr$(-1) found in string

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

    Chr$(-1) found in string

    I was working on a parsing routine of mine, when I could not figure out a problem I was having, and started printing asc values of each character when I found in every string starts with chr$(-1)

    Is this normal? I usually never see this because I start parsing at the 1st character, not 0. (Example below how I can replicate this)
    Code:
    #COMPILE EXE
    #DIM ALL
    FUNCTION PBMAIN () AS LONG
    
        LOCAL TestString AS STRING
        LOCAL i AS LONG
        TestString = "Hello"
        REPLACE CHR$(-1) WITH "" IN TestString
    FOR i = 0 TO LEN(TestString)
         MSGBOX STR$(ASC(MID$(TestString, i, 1)))
    NEXT i
    IF INSTR(TestString, CHR$(-1)) THEN MSGBOX " -1 char found in TestString " + FUNCNAME$
    MSGBOX STR$(VARPTR(TestString))
    END FUNCTION
    An empty string does not have this starting "-1" character and I can not seem to replace the character with nothing, nor any other character????

    How do I get rid of it? It is causing problems in routines that I am purposely looking for a -1 as being the character returned (although I do not know what that character is called???)
    Engineer's Motto: If it aint broke take it apart and fix it

    "If at 1st you don't succeed... call it version 1.0"

    "Half of Programming is coding"....."The other 90% is DEBUGGING"

    "Document my code????" .... "WHYYY??? do you think they call it CODE? "

    #2
    Your starting position in the loop is zero. Although valid, this position can contain ?odd? characters.
    There are no atheists in a fox hole or the morning of a math test.
    If my flag offends you, I'll help you pack.

    Comment


      #3
      If I start at 1 (like I normally do) I do not see the -1, but if I do an instr for -1 it is there. (I never noticed it before)

      In other applications, -1 has special meaning, which in turn using a string would give a "False - Positive" in those applications.
      Engineer's Motto: If it aint broke take it apart and fix it

      "If at 1st you don't succeed... call it version 1.0"

      "Half of Programming is coding"....."The other 90% is DEBUGGING"

      "Document my code????" .... "WHYYY??? do you think they call it CODE? "

      Comment


        #4
        >REPLACE CHR$(-1) WITH "" IN TestString

        CHR$ with a parameter value of -1 returns an empty string for that parameter.
        So you want to replace all empty strings with... an empty string? But an empty string has no length, so it can never exist for replacment.

        I have to admit I cannot see any use for CHR$() to support anything but 0 to 255 in numeric arguments, but that's what it says in the help file.

        For whatever it's worth...
        >MID$(TestString, i, 1)))

        start& and length& are variables or expressions. As a function, MID$ returns a sub-string of string_expression that is length& characters long and starts at the start& character of string_expression...... If length& is negative, it is interpreted as LEN(string_expression)-ABS(length&).
        When I = 0, what it means is not documented. I would think it should return an error 5 at runtime, but have no idea if it does or not.

        MCM
        Michael Mattias
        Tal Systems (retired)
        Port Washington WI USA
        [email protected]
        http://www.talsystems.com

        Comment


          #5
          From help for ASC statement:

          If the string passed is null (zero-length) or the position is zero or greater than the length of the string, the value -1 is returned.
          From help for CHR$ statement:

          CHR$ complements the ASC function, which returns the ASCII code of a nominated character in a string. In addition, CHR$ with a parameter value of -1 returns an empty string for that parameter. For example, CHR$(65, -1, 66) returns "AB".
          From help for MID$ statement:

          If start& evaluates to a position outside of the string on either side, or if start& is zero, an empty string is returned.
          From help for INSTR statement:

          If MatchString is not found in the specified portion of MainString, or n& evaluates outside of MatchString, INSTR returns 0. If MatchString is null (an empty string), INSTR returns 1 (if n& not specified) or n& (if n& is specified).
          So let's look at some of your code.

          Code:
          REPLACE CHR$(-1) WITH "" IN TestString
          CHR$(-1) returns a null string so you are replacing a null string with a null string.

          Code:
          FOR i = 0 TO LEN(TestString)
               MSGBOX STR$(ASC(MID$(TestString, i, 1)))
          NEXT i
          Here the MID$ in the first iteration is looking at index 0 so it is returning a null string and the ASC function then returns -1 because it is looking at a null string.

          Code:
          IF INSTR(TestString, CHR$(-1)) THEN MSGBOX " -1 char found in TestString " + FUNCNAME$
          Here, CHR$(-1) is putting a null sting in the INSTR's match string paramenter so it is causing the INSTR function to return a 1, or true, because no starting index was provided.

          Hopefully that solves any confusion you might have been having.
          Jeff Blakeney

          Comment


            #6
            > I cannot see any use for CHR$() to support anything
            > but 0 to 255 in numeric arguments

            ASC/ASCII of an empty string returns -1, therefore CHR$(-1) returns an empty string. Makes sense to me.


            -- Eric
            "Not my circus, not my monkeys."

            Comment


              #7
              >ASC/ASCII of an empty string returns -1

              Well, there's your problem. That should return Error 5. But I guess someone succumbed to enough user requests to "don't make me test ERR when I forget to test LEN()" and now we're stuck with this.

              MCM
              Michael Mattias
              Tal Systems (retired)
              Port Washington WI USA
              [email protected]
              http://www.talsystems.com

              Comment


                #8
                Michael, kindly tell me which rule book says it must generate an error 5? The documentation is complete, excellent, and accurate. Read it and just follow the "rules"? Thank you

                Comment


                  #9
                  This reminds me of a whimsical little article that Lewis Carroll once wrote. He claims he can truthfully say:

                  All my uncles are millionaires.

                  because he has no uncles.

                  And I say:

                  Every PowerBasic program I ever wrote on the moon has worked perfectly.

                  It’s true. Every one.

                  It’s useful to think of the empty collection as a sub-collection of every collection. It makes contrapositives work the way they should:
                  ... All X are Y.
                  ... All not Y are not X.
                  are equivalent.

                  Here’s Professor Ludwig von Drake on the subject: “If X is nothing, then not X is everything, and clearly anything is among everything, and so nothing is among anything.”

                  OK duck, beat it.

                  A case could be made that the empty string should be found in every string, just as Lewis Carroll makes the case that his empty collection of millionaire uncles is found among his uncles. Indeed that’s the way the compiler works.

                  For any string A,
                  Instr(A,"") <> 0
                  (except, inconsistently I think, it = 0 when A = "").

                  The problem is, where is "" found? The compiler uses
                  Instr (A,"") = 1

                  [ADDED: As Jeff points out, the next two paragraphs of the original were wrong because I swapped the search string with the main string. I've replaced both paragraphs.]

                  Yet if A <> "" it's first character is not "".

                  Instr does double duty as both an indicator of existence and the position. If Instr is to be non-zero (existence) what is to be that number (position)?

                  A case could be made for infinity. Or –1.

                  Cliff,

                  Changing the compiler so Instr gives –1 would not solve the problem you encountered. Since per the help file Chr$ (-1) = "", interlarding a string with Chr$ (-1)s doesn’t do anything to it. Maybe you could use Chr$ (some rare number).
                  Last edited by Mark Hunter; 4 Oct 2009, 11:46 PM. Reason: as noted
                  Algorithms - interesting mathematical techniques with program code included.

                  Comment


                    #10
                    >which rule book says it must generate an error 5?

                    Oh, the documentation is correct; the product works as advertised.

                    It just don't work the way I think it should.

                    I simply cannot get my head around CHR$(negative number) or its 'logical' complement.

                    MCM
                    Michael Mattias
                    Tal Systems (retired)
                    Port Washington WI USA
                    [email protected]
                    http://www.talsystems.com

                    Comment


                      #11
                      Originally posted by Bob Zale View Post
                      Michael, kindly tell me which rule book says it must generate an error 5? The documentation is complete, excellent, and accurate. Read it and just follow the "rules"? Thank you
                      Bob, PB may do anything "non-standard" that they want. But don't you want what you do to make sense? As Michael said, CHR$(negative number) makes no sense.

                      In my case it is not going to matter one bit because I test for null, but doing things in as standardized way as possible is a benefit to your company, trust me.

                      I know you have some issues with some of the things Michael brings up, but if you just relax and takes notes, I think you will realize he is trying to improve your product.
                      Gary Peek, Industrologic, Inc.

                      Comment


                        #12
                        Gary,

                        If I cared about you I'd be annoyed to receive such a message. Who are you to say that I'm not relaxed. And what the hell does it mean, anyway?

                        The bums in the park look relaxed.

                        ADDED: Your sarcasm (below) misses the point. Like most forum readers, if a thread's topic interests me I read every post. Your post (above) -- with it's admonition for someone to be "relaxed" -- was unwarranted and annoying to the point of provoking a response. Go relax yourself.
                        Last edited by Mark Hunter; 30 Sep 2009, 10:56 AM.
                        Algorithms - interesting mathematical techniques with program code included.

                        Comment


                          #13
                          The argument of Chr$ is just a code, there’s no reason not to allow it to be negative as well as positive.

                          The problem is that someone happened to use –1 without looking at the documentation, which clearly states that Chr$ yields the empty string in that case, not a character that differs from all ordinary characters as he assumed.

                          And that is his problem, not the compiler's.

                          Now a comment on a separate issue that the above happened to bring up: How Instr treats the empty string.

                          This treatment is difficult to change after the compiler has been around a while because someone somewhere may be using Instr on empty strings expecting it to work the way it does. Anyway, if the compiler were rewritten the following two suggestions, which can be implemented separately, would be worth considering (see my first post above):

                          1. Instr (A, "") is always the same number, including when A = "".

                          2. That number is –1 (not 1).
                          Algorithms - interesting mathematical techniques with program code included.

                          Comment


                            #14
                            message was for Bob

                            Originally posted by Mark Hunter View Post
                            If I cared about you I'd be annoyed to receive such a message.
                            Mark, that message was for Bob. Perhaps I used the wrong configuration and caused the forum to respond to you.
                            Gary Peek, Industrologic, Inc.

                            Comment


                              #15
                              Cliff Nichols--

                              It's unfortunate that this thread has been hijacked a bit rather than really answer your question, so let me try to give you the correct overall information.

                              There is no character with the code of -1. That's a special value used to signify that there is no character located at the position you requested. It is returned when the string is nul (zero-length), the character position is less than one, or the character position is greater than the length.

                              ASC( "" ) returns -1
                              ASC( "abc", 0) returns -1
                              ASC( "abc", 4) returns -1

                              In PowerBASIC, all string character positions are numbered from 1, up to the max length of the string. Any other position is "invalid".

                              When the ASC(xxx$) function returns the value -1, it's simply an additional, convenient method to determine that xxx$ is nul (zero-length).

                              This concept is pretty much carried throughout all of the syntax of the compiler. If you try to create a new string with CHR$(-1), PowerBASIC simply returns a nul (zero-length) string because there is no character defined for that code.

                              Using a special value to flag an exceptional condition is very common throughout the industry. For example, the IEEE floating point standard specifies that the "maximum negative number" be used to flag an attempt to store an integer class value which is outside the range of the target variable. If you try to store the float value 99999.9 in a short integer variable, the FPU will substitute -32768 instead.

                              Best regards,

                              Bob Zale
                              PowerBASIC Inc.

                              Comment


                                #16
                                %THINKING = 1
                                -1 makes more sense than -%THINKING
                                Rod
                                In some future era, dark matter and dark energy will only be found in Astronomy's Dark Ages.

                                Comment


                                  #17
                                  With regards to the concept of error generation for a parameter "out-of-bounds" exception, let me once again point to the description in the PowerBASIC error documentation:

                                  "Unlike the DOS versions of PowerBASIC, Windows versions of PowerBASIC employ a completely different philosophy: to generate the smallest and fastest possible code. Consequently, error handling is placed firmly in the hands of the programmer.

                                  Processing an error/exception condition is extraordinarily expensive in terms of wasted time. Checking every value for minimum and maximum... interrupting program flow... transferring program control to an error handler... processing all of the code in the error handler... recording the error number and other possible info... transferring control to a retry operation... All of these things can waste a huge amount of processing time. While some may believe it's easier to do all this, it's contrary to the PowerBASIC philosophy of Faster-Smaller, Faster-Smaller, Faster-Smaller. Instead, we believe it's far more prudent to either validate parameters beforehand, or validate the result for an exceptional condition marker. This philosophy applies to virtually all operations where the programmer has the ability to do so.

                                  So, when are run-time errors/exceptions generated? When the programmer does not have the ability to do so with a high confidence level. You can't possibly anticipate things like "out of memory", "disk drive failure", "disk full", "network connections", and all the like failures. In all cases of this sort, PowerBASIC generates an exception and an error report. However, for trivial items like the size of a parameter? No, thanks, we leave that up to you. In most cases, you can have 100% certainty about the value of your parameters, so there's no need to check. In the rare cases you're unsure, you can easily check it far more quickly than the processing time for an error. That's the philosophy we've followed since PB/DLL 1.0, our very first compiler for Windows.

                                  That's the philosophy embraced by the vast majority of our friends and customers.

                                  Best regards,

                                  Bob Zale
                                  PowerBASIC Inc.

                                  Comment


                                    #18
                                    ... does not have the ability to do so with a high confidence level. You can't possibly anticipate things like "out of memory", "disk drive failure", "disk full", "network connections", and ...
                                    ..and 'data type overflow' (including intermediate values in expresssions)?

                                    The NFS for #DEBUG OVERFLOW ON is still on file. I hope it's not waiting me to develop some "high confidence" in my ability to test for overflow and underflow.


                                    MCM
                                    Michael Mattias
                                    Tal Systems (retired)
                                    Port Washington WI USA
                                    [email protected]
                                    http://www.talsystems.com

                                    Comment


                                      #19
                                      If you can't foresee the potential magnitude of values in an expression, it would likely be prudent to use a data type with a larger range of values. That's precisely why PowerBASIC offers so many different data types... so you can choose one which is appropriate. If Integer isn't large enough, use Long Integer...

                                      Best regards,

                                      Bob Zale
                                      PowerBASIC Inc.

                                      Comment


                                        #20
                                        I have to admit I cannot see any use for CHR$() to support anything but 0 to 255 in numeric arguments
                                        I think It could be useful.

                                        Code:
                                        IF nChar = -1 THEN PRINT #1, "" ELSE PRINT #1, CHR$(nChar)
                                        Code:
                                        PRINT #1, CHR$(nChar)
                                        nChar itself might be derived from a byte pointer or a .ini setting where the user is directed to set the ASCII number of the character they want to use for whatever purpose.

                                        The gain is pretty small, but little things add up.
                                        Erich Schulman (KT4VOL/KTN4CA)
                                        Go Big Orange

                                        Comment

                                        Working...
                                        X
                                        😀
                                        🥰
                                        🤢
                                        😎
                                        😡
                                        👍
                                        👎