Reputation: 635
I'm quite new to C and programming in general, I tried to implement a simple command parser function, which should do the following:
Read characters from the serial line and parse for the string "boot\n". If I receive this command I would like to output the name of the application over the serial line. For the command "boot AppName\n", I would start the application with the name given in AppName. How can I achieve this with a quite simple parser, by simple I mean in code complexity?
static void parse_input(void)
{
uint16_t i;
char input_buf[30];
char c;
read_character(&c);
if (c == '\n') /* sync character */
for (i=0; i < 20; i++)
{
read_character(&c);
input_buf[i] = c;
}
/* check for string "boot" in input buffer */
/* maybe string compare? */
}
Thx
Upvotes: 0
Views: 3227
Reputation: 25865
The another way for getting serial data and parse as follows i have modified your code
static void parse_input(void)
{
uint16_t i;
char input_buf[30];
char c;
char cmdBuf[ 1024 ]; /* character input buffer */
int bufPos = 0;
memset(cmdBuf,0, 1024);
for(;;)
{
read_character(&c);
if( ( c == '\r') || ( c == '\n' ) )
{
if( ( 1 + bufPos ) < 1024 ) {
cmdBuf[bufPos++] = '\0';
}
if(cmdBuf[0] != 0)
{
//serial data available in cmdBuf
//here your code what to do
//whether you application or other stuff
}
break;
}
else
{
if( c == '\b' )
{
if( bufPos > 0 ) {
bufPos--;
}
}
else
{
if( ( 1 + bufPos ) < 1024 ) {
cmdBuf[bufPos++] = c;
}
}
}
}
}
Upvotes: 1
Reputation: 76395
Given that you're working with a fixed size input buffer, I'd simply settle for something like:
fflush(stdout);
if ((fgets(input_buf, 30, stdin)) == NULL)
{
puts("No input...");
return;
}
if ((strncmp(buffer, "boot", 4)) != 0)
{//boot was NOT found
printf("Command: %s is unknown\n", buffer);
return;
}
//boot was found, so something like:
char *token = strtok(buffer, " \n");
while(token != NULL)
{
token = strtok(NULL, " \n");
if (token) printf("To boot -> %s\n", token);
}
The latter is just simply "chunking" the string using spaces as a delimiter. so token will point to boot
after the first call, and then it'll point to whatever words (if any) that follow.
Of course, an easier way would be to do
char *boot_what = buffer+5;
buffer[4] = '\0';
But this implies that the first 5 chars of the buffer are indeed 'b''o''o''t'' '
, the easiest way to obtain this is by doing:
char *boot_ptr = strstr(buffer, "boot ");
because strstr
returns a pointer to where the string-to-find is found in the given string... ah well, play around with the functions in <string.h>
and find what works best for your purpouse.
Upvotes: 3
Reputation: 6116
I think the best way is using a state machine as follows:
Take a integer variable state
initially equal to 0
denoting no character found.
This variable will be the condition for a switch
statement
For case 0
: keep scanning characters until you find 'b'
, where you will update state
to 1
For case 1
, likewise, you will be searching for 'o'
, if you encounter any other character then reset the state
to 0
.
Similarly for 'o'
and 't'
Whatever follows after "boot"
will be your AppName.
Upvotes: 1