Announcement

Collapse
No announcement yet.

Parsecount count

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

  • Parsecount count

    What am I missing here people?

    Code:
    #COMPILE EXE
    #DIM ALL
    
    GLOBAL line_input  AS STRING
    
    FUNCTION PBMAIN () AS LONG
    
    line_input ="x"
    PRINT PARSECOUNT(line_input,",")   'prints 1 and should be 0
    WAITKEY$
    
    line_input ="x,y"
    PRINT PARSECOUNT(line_input,",")    'prints 2 and should be 1
    WAITKEY$
    
    END FUNCTION
    PBCC(latest) and Windows 10

    [I]I made a coding error once - but fortunately I fixed it before anyone noticed[/I]
    Kerry Farmer

  • #2
    Without a comma (the delimiter in this case) there is one item, the "x". So parsecount returns 1.

    The second example has one comma and two items "x" and "y", so parsecount returns 2.

    Cheers,

    added- count items (numbers or strings) separated/IDed by delimiter. Not counting the delimiters.
    Dale

    Comment


    • #3
      line_input ="x,y"
      PRINT PARSECOUNT(line_input,",")

      it must be return 2 because in this way it works PARSE$



      Code:
      part1$=PARSE$(line_input,",",1)
      part2$=PARSE$(line_input,",",2)

      Comment


      • #4
        You misunderstand the purpose of PARSECOUNT. It returns the number of items, not the number of delimiters.

        >line_input ="x"
        >PRINT PARSECOUNT(line_input,",") 'prints 1 and should be 0

        Nope, there is ONE item, "the letter x", so PARSECOUNT should be ONE.

        >line_input ="x,y"
        >PRINT PARSECOUNT(line_input,",") 'prints 2 and should be 1

        Similarly, there are TWO items, the letters"x and "y" so PARSECOUNT should e TWO.

        Comment


        • #5
          Like Stuart has said
          PARSECOUNT returns the number of items (delimiters + 1). There is always an item even if $NUL or no length.
          TALLY returns the number of delimiters.
          Code:
          FUNCTION PBMAIN () AS LONG
           LOCAL s AS STRING
           s=""
           ? USING$("PARSECOUNT=# TALLY=#",PARSECOUNT(s$),TALLY(s$,","))  'PARSECOUNT=1  TALLY=0
          END FUNCTION
          https://www.tesla.com/roadster

          Comment


          • #6
            Duh!

            Thanks guys
            [I]I made a coding error once - but fortunately I fixed it before anyone noticed[/I]
            Kerry Farmer

            Comment


            • #7
              Originally posted by Kerry Farmer View Post
              Duh!

              Thanks guys
              There is an exception.
              If your list ends with your delimiter, it will be counted.
              This occurs even if there is no item following the delimiter.
              The world is strange and wonderful.*
              I reserve the right to be horrifically wrong.
              Please maintain a safe following distance.
              *wonderful sold separately.

              Comment


              • #8
                I don't think of that as an exception. Think in terms of .csv for a moment.

                A nul "field" in the "middle" of a record would cause two delimiters consecutively. A nul last field would cause a delimiter to be the last character on the line, but field count remains correct. If there simply were no more data then the delimiter would not be there either!

                Just IMO of course. Cheers,
                Dale

                Comment


                • #9
                  here is an exception.
                  If your list ends with your delimiter, it will be counted.
                  This occurs even if there is no item following the delimiter.
                  That is a good observation, but empty strings are items.

                  I agree with Dale and the last character can be a delimiter without exception.
                  If the last character is a delimiter it indicates a 0-length item after it
                  sData = "," will return a PARSECOUNT of 2 and TALLY of 1 if comma is the delimiter. Two, 0-length items.
                  https://www.tesla.com/roadster

                  Comment


                  • #10
                    Originally posted by Dale Yarker View Post
                    I don't think of that as an exception. Think in terms of .csv for a moment.

                    A nul "field" in the "middle" of a record would cause two delimiters consecutively. A nul last field would cause a delimiter to be the last character on the line, but field count remains correct. If there simply were no more data then the delimiter would not be there either!

                    Just IMO of course. Cheers,
                    Of course. That makes perfect sense.
                    The world is strange and wonderful.*
                    I reserve the right to be horrifically wrong.
                    Please maintain a safe following distance.
                    *wonderful sold separately.

                    Comment


                    • #11
                      Originally posted by Kerry Farmer View Post
                      What am I missing here people?
                      I had a related discussion years ago on this forum. Short version is that PARSECOUNT of an empty string is also always 1, and that is how it is designed.

                      Real programmers use a magnetized needle and a steady hand

                      Comment


                      • #12
                        I have discovered two things

                        One is that this matter was raised years ago - so I should have found that!

                        But secondly if you do a PARSE$ with an index greater that the number of fields it returns a blank. Very useful. It means you do not have to say "if number-of-fields = x then. whatever" and you do not have to initiate the receiving field. This simplified my program quite a lot actually. Ok it says all that in the help - but only as an afterthought.
                        [I]I made a coding error once - but fortunately I fixed it before anyone noticed[/I]
                        Kerry Farmer

                        Comment


                        • #13
                          Exiting on a blank item would not process the entire record.
                          What am I missing?
                          How do you know the number of items per record unless you check for them?
                          This example has 6 items and would exit on the 4th.
                          Code:
                          FUNCTION PBMAIN () AS LONG
                           LOCAL s AS STRING, x AS LONG
                           s = "Kerry,Farmer,19th Pine,,Somewhere,ST"
                           FOR x = 1 TO 100
                            IF LEN(PARSE$(s,x)) = 0 THEN ? STR$(X):EXIT FOR  '4
                           NEXT
                          END FUNCTION
                          https://www.tesla.com/roadster

                          Comment


                          • #14
                            Code:
                            #compile exe
                            #dim all
                            '
                            ' absolutely Mike
                            ' Try this Kerry, each string "s" may contain different number of items and won't
                            ' "trip over" an embedded nul.
                            function pbmain () as long
                             local s as string, x as long
                             s = "Kerry,Farmer,19th Pine,,Somewhere,ST" '<== contains 6 items,
                                                                        '    including one nul item.
                             for x = 1 to parsecount(s) ' <== 100 was, beyond real items, an embeded empty messes things
                                                                      '        up like Mike says.
                              if len(parse$(s,x)) = 0 then ? str$(X) ':EXIT FOR  '4 <== why? if you want all?
                             next
                            end function
                            ' Why do three things IF, LEN, EXIT to avoid one thing PARSECOUNT ?
                            ' For CVS or TBS (tab separated) only do PARSECOUNT once because all lines in file
                            ' have the same number of items (unless error in CVS/TBS)
                            Cheers,
                            Dale

                            Comment


                            • #15
                              Originally posted by Dale Yarker View Post
                              ' For CVS or TBS (tab separated) only do PARSECOUNT once because all lines in file
                              ' have the same number of items (unless error in CVS/TBS) [/CODE]Cheers,
                              That is not necessarily true. There is no "standard" for CSV/TBS files. ALL you can be sure of is that separate items will be separated by the appropriate character - apart from that, anything goes, including quoting/escaping characters and number of fields.

                              Unless you are sure of the detailed format of a specific file, you can't make any ssumptions.










                              Comment


                              • #16
                                Not quite sure what we are saying here

                                Here is a silly little check program

                                Code:
                                #COMPILE EXE
                                #DIM ALL
                                GLOBAL f1 AS STRING
                                
                                FUNCTION PBMAIN () AS LONG
                                f1 ="a,b,c,d"
                                
                                PRINT PARSE$(f1,",",1)   'a
                                PRINT PARSE$(f1,",",2)   'b
                                PRINT PARSE$(f1,",",3)   'c
                                PRINT PARSE$(f1,",",4)   'd
                                PRINT "m"+PARSE$(f1,",",5) + "n"   'mn
                                
                                f1 ="a,b,,d"
                                
                                PRINT PARSE$(f1,",",1)   'a
                                PRINT PARSE$(f1,",",2)   'b
                                PRINT  "x"+ PARSE$(f1,",",3)+"y"   'xy
                                PRINT PARSE$(f1,",",4)   'd
                                PRINT "m"+PARSE$(f1,",",5) + "n"   'mn
                                WAITKEY$
                                
                                END FUNCTION
                                When I said 'returns a blank' , I should have said 'returns an empty string' - we programmers should get stuff like that right!
                                [I]I made a coding error once - but fortunately I fixed it before anyone noticed[/I]
                                Kerry Farmer

                                Comment


                                • #17
                                  What is the advantage of trying to access 5 fields when there are 4 fields?
                                  An empty delimited field can be anywhere in the string and PARSECOUNT will count it.
                                  But secondly if you do a PARSE$ with an index greater that the number of fields it returns a blank. Very useful. It means you do not have to say "if number-of-fields = x then. whatever" and you do not have to initiate the receiving field. This simplified my program quite a lot actually. Ok it says all that in the help - but only as an afterthought.
                                  Code:
                                  FUNCTION PBMAIN () AS LONG
                                   LOCAL s AS STRING
                                   s ="a,b,c,d,,e" '6 items
                                   DIM sArr(1 TO PARSECOUNT(s)) AS STRING
                                   PARSE s,sArr()
                                   ? JOIN$(sArr(),$CR)  'items in array for easy processing
                                  END FUNCTION
                                  https://www.tesla.com/roadster

                                  Comment


                                  • #18
                                    [QUOTE=Mike Doty;n777949]What is the advantage of trying to access 5 fields when there are 4 fields?
                                    An empty delimited field can be anywhere in the string and PARSECOUNT will count it.

                                    [code]

                                    Oops I have not explained myself very well

                                    You can use PARSE$ even if you do not know (or more correctly do not previously count) the number of fields. So if your number of fields varies, you can PARSE$ and for the empty or nonexisten field you get an empty string. You do not even have to clear the field, PARSE$ empties it.
                                    [I]I made a coding error once - but fortunately I fixed it before anyone noticed[/I]
                                    Kerry Farmer

                                    Comment


                                    • #19
                                      Normally, you would want to parse the string into a string array.
                                      In that case, the null field would be a null string in the array.
                                      You could use the string as an array, using the PARSE statement, of course.
                                      That would require less memory, but could cost a bit in speed during access
                                      due to the processor overhead of the PARSE statement.
                                      Code:
                                      #COMPILE EXE
                                      #DIM ALL
                                      #DEBUG DISPLAY
                                      FUNCTION PBMAIN () AS LONG
                                       LOCAL s, sl() AS STRING, x, c AS LONG
                                       s = "Kerry,Farmer,19th Pine,,Somewhere,ST"
                                       x = PARSECOUNT(s, ",")
                                       REDIM sl(x - 1)
                                       PARSE s, sl(), ","
                                       FOR x = x-1 TO 0 STEP -1
                                          IF sl(x) <>"" THEN INCR c
                                       NEXT
                                       ? STR$(c) + " occupied fields"
                                      END FUNCTION
                                      The world is strange and wonderful.*
                                      I reserve the right to be horrifically wrong.
                                      Please maintain a safe following distance.
                                      *wonderful sold separately.

                                      Comment

                                      Working...
                                      X