Home AMX User Forum NetLinx Studio

Can't remove comma, reading from CSV

Anyone know why my comma won't go away between columns? Remove string doesn't do the trick:
DEFINE_FUNCTION fnReadFile(CHAR cFILENAME[])
{
    LOCAL_VAR SLONG slFILE_VAL
    
    slFILE_VAL = FILE_OPEN(cFILENAME,FILE_READ_ONLY)
    IF(slFILE_VAL < 0)
    {
	SELECT
	{
	    ACTIVE(slFILE_VAL == -2):SEND_COMMAND dvTP_VTC,"'^TXT-604,0,Invalid Path'"
	    ACTIVE(slFILE_VAL == -3):SEND_COMMAND dvTP_VTC,"'^TXT-604,0,Invalid Value'"
	    ACTIVE(slFILE_VAL == -5):SEND_COMMAND dvTP_VTC,"'^TXT-604,0,I/O Error'"
	    ACTIVE(slFILE_VAL == -14):SEND_COMMAND dvTP_VTC,"'^TXT-604,0,Max Files Open'"
	    ACTIVE(slFILE_VAL == -15):SEND_COMMAND dvTP_VTC,"'^TXT-604,0,Invalid File Format'"
	}
    }
    IF(slFILE_VAL > 0)
    {
	LOCAL_VAR SLONG slVAL
	LOCAL_VAR INTEGER i
	LOCAL_VAR CHAR cBUFF[2048]
	
	slVAL = FILE_READ_LINE(slFILE_VAL,cBUFF,MAX_LENGTH_ARRAY(cBUFF))
	FOR(i=1;i<=MAX_LENGTH_ARRAY(uPRESETS);i++)
	{
	    uPRESETS[i].cNAMES = REMOVE_STRING(cBUFF,',',1)
	    SET_LENGTH_STRING(uPRESETS[i].nNUMBERS,LENGTH_STRING(uPRESETS[i].nNUMBERS)-1)
	    uPRESETS[i].nNUMBERS = cBUFF
	    
	    SEND_COMMAND dvTP_VTC,"'^TXT-',ITOA(499+i),',0,',uPRESETS[i].cNAMES" 
	    SEND_COMMAND dvTP_VTC,"'^TXT-',ITOA(603+i),',0,',uPRESETS[i].nNUMBERS"
	    slVAL = FILE_READ_LINE(slFILE_VAL,cBUFF,MAX_LENGTH_ARRAY(cBUFF))
	}
	FILE_CLOSE(slFILE_VAL)
    }
}

Comments

  • Joe HebertJoe Hebert Posts: 2,159
    mjones2620 wrote: »
    Anyone know why my comma won't go away between columns? Remove string doesn't do the trick:

    Looks like this:
     uPRESETS[i].cNAMES = REMOVE_STRING(cBUFF,',',1)
     SET_LENGTH_STRING(uPRESETS[i].nNUMBERS,LENGTH_STRING(uPRESETS[i].nNUMBERS)-1)
    

    Should be this:
     uPRESETS[i].cNAMES = REMOVE_STRING(cBUFF,',',1)
     SET_LENGTH_STRING(uPRESETS[i].[b]cNames[/b],LENGTH_STRING(uPRESETS[i].[b]cNames[/b])-1)
    
  • mjones2620mjones2620 Posts: 86
    Joe Hebert wrote: »
    Looks like this:
     uPRESETS[i].cNAMES = REMOVE_STRING(cBUFF,',',1)
     SET_LENGTH_STRING(uPRESETS[i].nNUMBERS,LENGTH_STRING(uPRESETS[i].nNUMBERS)-1)
    

    Should be this:
     uPRESETS[i].cNAMES = REMOVE_STRING(cBUFF,',',1)
     SET_LENGTH_STRING(uPRESETS[i].[b]cNames[/b],LENGTH_STRING(uPRESETS[i].[b]cNames[/b])-1)
    

    AHHHH, overlooked the obvious mistake. Thank you sir!
  • GregGGregG Posts: 251
    I am the worst victim of copy-paste errors. So I made a meta-function to do this, since it is needed all the time:
    /////////////////////////////////////////////////////////////
    // Char[16000] Remove_String_Minus(Char cStr[], Char cMatch[], Integer nPos, Integer nMinusAmt)
    //
    // Works just like Remove_String() with the additional parameter
    // of how much to trim from the returned string, so it can be used
    // to automatically truncate off the delimeter in one function.
    //
    // eg- cTmp = Remove_String_Minus("'Hello.',13,10,'There.'","13,10",1,2)
    //	will just give back "'Hello.'" without the 13,10 and will leave
    // "'There.'" in the source string.
    //
    /////////////////////////////////////////////////////////////
    Define_Function Char[16000] Remove_String_Minus(Char cStr[], Char cMatch[],
                                                    Integer nPos, Integer nMinusAmt)
    {
    Stack_Var Char cTemp[16000]
    Stack_Var Integer nLen
    
    	cTemp = Remove_String(cStr,"cMatch",nPos)
    	nLen = Length_String(cTemp)
    
    	If(nMinusAmt<nLen)
    		nLen = nLen - nMinusAmt
    	Else
    		nLen = 0
    
    	Set_Length_String(cTemp,nLen)
    	Return cTemp
    }
    
  • a_riot42a_riot42 Posts: 1,624
    Shouldn't this:
    SET_LENGTH_STRING(uPRESETS[i].nNUMBERS,LENGTH_STRING(uPRESETS[i].nNUMBERS)-1)
    

    be this:
    SET_LENGTH_STRING(uPRESETS[i].nNAMES,LENGTH_STRING(uPRESETS[i].nNAMES)-1)
    
  • AMXJeffAMXJeff Posts: 450
    I use a String_Tokenizer (StringSplit)
    // Function : String_Tokenizer()
    // Purpose  : To count arg's, copy arguments, return number of errors
    // Params   : string , char to search for
    // Return   :
    // Notes    : This function counts variables and parses arguments.
    //          : Even though this function is named 'ParseArgument',
    //          : it copies, counts, and returns a value.
    // Further  : All of the valid arguments (non-zero-length)are saved off into
    //          : the command structure in their corresponding location 1-8
    DEFINE_FUNCTION INTEGER String_Tokenizer(CHAR cArguments[MAX_ARGS][], CHAR cSearchStr[255], CHAR cSeparator[])
    {
    	STACK_VAR INTEGER nArgs;
    	STACK_VAR CHAR cBuffer[1024];
    	STACK_VAR CHAR cArgstr[1024];
    
    	cBuffer = cSearchStr;
    
    	WHILE (LENGTH_STRING (cBuffer))
    	{
    		IF (FIND_STRING (cBuffer, "cSeparator", 1))
    		{
    			cArgstr = REMOVE_STRING (cBuffer, "cSeparator", 1)
    			SET_LENGTH_STRING (cArgstr, LENGTH_STRING (cArgstr) - LENGTH_STRING(cSeparator))
    		}
    		ELSE
    			cArgstr = GET_BUFFER_STRING (cBuffer, LENGTH_STRING (cBuffer))
    		//  INCREMENT nArgs
    		nArgs++
    
    		IF ((nArgs <= MAX_ARGS) && nArgs)
    			cArguments[nArgs] = cArgstr
    	}
    
    	RETURN nArgs;
    }
    
  • This is in SNAPI.axi and works pretty well for any standard csv data as well as SNAPI command parameters

    DEFINE_FUNCTION CHAR[DUET_MAX_PARAM_LEN] DuetParseCmdParam(CHAR cCmd[])

    // Name : ==== DuetParseCmdParam ====
    // Purpose: To parse out parameters from module send_command or send_string
    // Params : (1) IN/OUT - sndcmd/str data
    // Returns: Parse parameter from the front of the string not including the separator
    // Notes : Parses the strings sent to or from modules extracting the parameters.
    // A single param is picked of the cmd string and removed, through the separator.
    // The separator is NOT returned from the function.
    // If the first character of the param is a double quote, the function will
    // remove up to (and including) the next double-quote and the separator without spaces.
    // The double quotes will then be stripped from the parameter before it is returned.
    // If the double-quote/separator sequence is not found, the function will remove up to (and including)
    // the separator character and the leading double quote will NOT be removed.
    // If the separator is not found, the entire remained of the command is removed.
    // Command separating character assumed to be ',', Duet standard
    //
  • nickmnickm Posts: 152
    icraigie wrote: »
    This is in SNAPI.axi and works pretty well for any standard csv data as well as SNAPI command parameters

    DEFINE_FUNCTION CHAR[DUET_MAX_PARAM_LEN] DuetParseCmdParam(CHAR cCmd[])

    // Name : ==== DuetParseCmdParam ====
    // Purpose: To parse out parameters from module send_command or send_string
    // Params : (1) IN/OUT - sndcmd/str data
    // Returns: Parse parameter from the front of the string not including the separator
    // Notes : Parses the strings sent to or from modules extracting the parameters.
    // A single param is picked of the cmd string and removed, through the separator.
    // The separator is NOT returned from the function.
    // If the first character of the param is a double quote, the function will
    // remove up to (and including) the next double-quote and the separator without spaces.
    // The double quotes will then be stripped from the parameter before it is returned.
    // If the double-quote/separator sequence is not found, the function will remove up to (and including)
    // the separator character and the leading double quote will NOT be removed.
    // If the separator is not found, the entire remained of the command is removed.
    // Command separating character assumed to be ',', Duet standard
    //

    DuetParseCmdHeader() and DuetParseCmdParam() are some of the handiest, least utilized SNAPI functions available. I was so happy when I stumbled upon them so I could do away with my other SNAPI parsing routines..
  • nickm wrote: »
    DuetParseCmdHeader() and DuetParseCmdParam() are some of the handiest, least utilized SNAPI functions available. I was so happy when I stumbled upon them so I could do away with my other SNAPI parsing routines..

    Could you provide an example of how I'd use this for the code I posted earlier in this thread?
  • I use DuetParseCmdHeader and DuetParseCmdParam to handle commands sent to a module in the form <command>-<param1>,<param2>, etc.
    data_event[vdvDevice]
    {
        command: {
            stack_var cReceivedString[256] // the whole command string
            stack_var cCmd[16]             // the parsed command
            stack_var nParam               // the number of command parameters
            stack_var cCmdParam[16][16]    // array of parsed command parameters
    
            cReceivedString = data.text
            cCmd = DuetParseCmdHeader(cReceivedString)
            nParam = 0
            while (length_array(cReceivedString)) {
                nParam++
                cCmdParam[nParam] = DuetParseCmdParam(cReceivedString)
            }
            switch (cCmd) {
                // example of a command that requires at least one parameter
                case: 'IR' {
                    if (nParam) {
                        CmdQueuePush('get_IR', cCmdParam[1])
                    }
                    else {
                        ReturnMessage("'ERR-Not enough parameters for ', cCmd")
                    }
                }
            }
        }
    }
    
    Note that the command separator is assumed to be a short dash (-) and the parameter separator is assumed to be a comma (,) by these functions.

    DuetParseCmdParam takes the input string (in your case cBUFF) and, if it finds a comma, returns the string portion to the left of the comma. The input string has the parameter including the comma removed. If no comma is found, the function returns the entire string and the input string will be empty.

    Andy
Sign In or Register to comment.