12-07-2009 08:05 AM
Hi im using sscanf , is there any other function I can use besides sscanf.
Im using sscanf in this sense below
items = sscanf(cmd,"%s%s%d",tmpString, tmpString2,&value);
*************************************************************
basically my goal is to make and error exception for the string cmd that comes in, I want to check to see if the correct number of items
there on a certain line in a script file.
I notice using this sscanf function it only checks for anything less not anything more. I want a function to be able to check for both options.
for an example: say for instance in a script file I have line 1 to originally to be ,
FRUIT, NUMBEROFFRUITS, 16
and someone make a simple mistake and put more items than there suppose to be like below. I want to make a error checking for the correct rnumber of items
sscanf only checks for anything less really from what I discover.
FRUIT, NUMBEROFFRUITS, 16, 57
************************************************
reguarding the same thing, now Im want to make a check for a correct interger
say for intance the user makes a mistake and put anyting other than a number on the line below, I want to make an exception for that also.
I was using isdigit, and I really dont think im using this in the right way for my context. the code below is how im using it
FRUIT, NUMBEROFFRUITS, 1w
long Send_DAS3000_Command(char *sCommand)
{
strcpy(sCmd,sCommand);
strtok(sCommand,SCRIPT_SEPARATORS);
strcpy(sFunction,strtok(NULL,SCRIPT_SEPARATORS));
iScriptErrorNumber=strcmp(sFunction,SETFILE);
if(iScriptErrorNumber!=0)
{
iStatusChecking=iScriptErrorNumber;
goto ScriptCondition;
}
strcpy(scriptLine,sCmd);
items = sscanf(scriptLine,"%s%s",tmpString, tmpString2,&value);
if (items != 2)
{
iScriptErrorNumber=-2;
goto ScriptCondition;
}
iStatusChecking=isdigit (value);
if(iStatusChecking<0)
{
return FAILURE;
}
12-07-2009 09:33 AM
For your first query, you could always have a sscanf string which was looking to convert, say, 4 items even if you are only expecting 3. That way, you can check the return value was exactly 3 items and successfully trap the condition that someone entered too many. Along the same lines, I would be tempted to read all the items in as strings, and convert them to numbers as appropriate outside of the sscanf function. This would be a tad more forgiving if a string was accidentally entered when a number was expected.
isdigit() takes an ASCII character as a parameter, not a numeric value already converted by sscanf. Use one approach or the other, not both. Personally I would make use of atof() on the strings that I expect to be numbers.
Making a script approach like this completely bulletproof is a challenge!
JR
12-07-2009 12:40 PM
if you see below, im using sscanf. but the variable sCmd saids reads DAS, FRAMES, 16, 50 which is four items.
when i step over the sscanf function below that im calling, the return value is 3, which is not true in a sense because i have four items. do you have a idea whats going on?
strcpy(sCmd,sCommand);
strtok(sCommand,SCRIPT_SEPARATORS);
strcpy(sFunction,strtok(NULL,SCRIPT_SEPARATORS));
iScriptErrorNumber=strcmp(sFunction,FRAMES);
if(iScriptErrorNumber!=0)
{
iStatusChecking=iScriptErrorNumber;
goto ScriptCondition;
}
strcpy(scriptLine,sCmd);
items = sscanf(scriptLine,"%s%s",tmpString, tmpString2,&value);
if (items != 3)
{
iScriptErrorNumber=-2;
goto ScriptCondition;
}
iStatusChecking=isdigit (value);
if(iStatusChecking<0)
{
return FAILURE;
}
12-07-2009 04:01 PM
I can see an evident typo your sscanf line of code: the format string actually asks for 2 elements while you are passing 3 arguments. With such a line you will get a "Too many parameters" error. But as I said this surely is only a typo.
items = sscanf(scriptLine,"%s%s",tmpString, tmpString2,&value);
Now passing to your question, there is nothing wrong in a sscanf line that extracts 3 items out of a 4 item line: you will get a return value of 3 which is exactly what the command is doing; extra characters in the source string are ignored and this is no error.
To address the problem you are facing you could switch from ANSI C sscanf to Scan from the Formatting and I/O Library: I am suggesting this to you since you can use NumFmtdBytes from the same library to obtain the number of bytes scanned from the string; comparing this to the string lenght permits you to know if there are extra bytes in the string that are not treated by the function (i.e. the string is not correct with reference to your standards).
err = Scan (sCmd, "%s%s%d", tmpString1, tmpString2, &value);
err = NumFmtdBytes ();
if (NumFmtdBytes () < strlen (sCmd)) {
MessagePopup ("Warning", "Excess characters in string.");
}
12-07-2009 11:21 PM
Thanks roberto, i didnt think about that. I suck. yeah that was a typo. but my point exactly if someone makes a typo in the scriptfile i want to catch it.
now with the same situation, I want to throw a test in for character handling.
example in the script file if someone make a typo and put ascii character, I want to be able to catch that also which is the 1w.
how can i make an exception for that, checkinh for a valid interger. i tried the isdigit, atoi. checking the return values, but they only grab the one.
do you know anything else i can do for that situation
FRUITS, ORANGES, 1w
12-08-2009 02:48 AM
As jr already suggested, the best approach is to scan the string into substrings and check the characters in the item which you know are numeric ones. strspn () function can help you in this matter: read the documentation about this function as it will help you in understanding how to use it. Here a code snippet to perform the check for numeric values: I am considering 'string' as your item to check and 'set' as the set of characters allowed in a numeric field.
strcpy (string, "12.35");
strcpy (set, "-0123456789.");
if (strspn (string, set) < strlen (string)) {
MessagePopup ("Warning", "Incorrect characters found!");
}
12-08-2009 02:23 PM
12-08-2009 02:33 PM
roberto can you expalin this two lines,I just want to be clear. Let me explain first and you tell me if im correct.
strcpy (string, "12.35");//////// this line is grabbing my interger thats going to be converted into a string,then get you are copying my string interger into the 1st parameter
which is a string also.
strcpy (set, "-0123456789.");///this line im assuming is giving the the range of digits you going to use so that when you call this particular test below you are going to
compare it to check for the correct interger through string.
this is my interpretation of it. can you correct me if im wrong.
if (strspn (string, set) < strlen (string))
12-08-2009 02:35 PM
also why are you putting the negative in front of the zero below
"-0123456789"
12-08-2009 03:48 PM - edited 12-08-2009 03:53 PM
Some clarifications are needed. I will comment my code making reference to the help (which can be found here, reported in italic character).
strspn command "Locates the position of the first character in a string that is not in a specified set of characters" (my highlighting).
strcpy (string, "12.35");
Here I am simply creating a string that represents a numeric. You could test the same code with a string with non-numeric digits embedded, like "12k35" or "12#3z", in fact I encourage you to do so and examine the results of strspn.
strcpy (set, "-0123456789.");
This parameter is "the character set containing the characters that are searched for in the specified string", that is the set of allowed characters: in this case all numeric digits plus minus sign (normally when we write a number we omit the plus sign: you can add it for completeness to the character set), plus decimal separator (I have used the period; some international standards use the comma instead); in other words: I am not creating a particular number but simpli listing all allowed characters. You will have to adapt the character set to your actual needs, for example adding A to F in case you want to deal with hex numbers as well.
Note that with this set of characters you can test not only integers but even fracional numbers.
if (strspn (string, set) < strlen (string)) {
MessagePopup ("Warning", "Incorrect characters found!");
}
Here I am testing if all characters have been scanned from the string.
As you may read in the online help, the return value of the function "Contains the index value of the string corresponding to the first character that does not match any in the specified character set. This value also corresponds to the length of the segment in the string that contains only characters from the character set. If all characters in the string are in the character set, the function returns the index of the terminating ASCII NUL byte. " (i.e. the string lenght, my highlighting)