HTML tags check in C - c

I'm writing a little program in C, for check the HTML file have the right open and close tags?
but i've got some issues...
i have a file what contains the all possible tags, named tags.txt(those are only the first ones):
<a>
</a>
<abbr>
</abbr>
<area>
</area>
<aside>
</aside>
and i have the htmlfile.html, what I have to check:
<!--#echo var="date" -->
<area>
</area>
<area>
</area>
secondly, i want to replace the comments like this to the sysdate
like , the format is OK i can do it, but the prog puts in the file
this
my code:
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <time.h>
#define MAX_SIZE 512
void menu();
void check();
void datumos();
int main(int argc,char *argv[])
{
menu();
return 0;
}
void menu()
{
char menu[MAX_SIZE];
while(1 < 2)
{
printf("\npress a button:\n\n");
printf("\tFile HTML check..............:c\n");
printf("\t<!--#echo var="date" -->...........:d\n");
printf("\tExit:\tCTRL + C\n");
scanf("%s",menu);
if( strcmp(menu,"c") == 0 )
{
check();
}
else if( strcmp(menu,"d") == 0 )
{
datumos();
}
}
}
void check()
{
FILE *htmlfile;
FILE *checkfile;
htmlfile = fopen("htmlfile.html","w");
checkfile = fopen("tags.txt","r");
char line[MAX_SIZE];
char htmlline[MAX_SIZE];
char tags[189][30];
int i=0;
printf("\tcheck__1\n");
while(fgets(line,sizeof(line),checkfile) != NULL)
{
int j;
for(j=0; j<sizeof(line); ++j)
{
tags[i][j]=line[j];
}
++i;
}
printf("\tcheck__2\n");
int k=0; char htmlfiletags[MAX_SIZE][30];
while(fgets(htmlline,sizeof(htmlline),htmlfile) != NULL)
{
char currentline[sizeof(htmlline)];
int j=0;
if( currentline[j]=="<" )
{
while(currentline[j]!=">")
{
htmlfiletags[k][j]=currentline[j];
++j;
}
strcat(htmlfiletags[k][j+1],">");
++k;
}
}
printf("\tcheck__3\n");
int n;
for(n=0; n<sizeof(htmlfiletags); ++n)
{
int j; int howmanytimesnot=0;
for(j=0; j<sizeof(tags); ++j)
{
printf("\tcheck__3/1\n");
if(strcmp(htmlfiletags[n],tags[j])==0)
{
printf("\t%d\n", howmanytimesnot);
++howmanytimesnot;
}
}
printf("\tcheck__3/3\n");
if(!(howmanytimesnot<sizeof(tags)))
{
printf("\tcheck__3/4\n");
printf("the file is not wellformed");
exit (1);
}
}
printf("\tcheck__4\n");
}
void copy_file(const char *from,const char *to)
{
FILE *fr;
FILE *t;
fr = fopen(from,"r");
t = fopen(to,"w");
char line[MAX_SIZE];
char row[MAX_SIZE];
while(fgets(line,sizeof(line),fr) != NULL)
{
sscanf(line,"%s",row);
fprintf(t,"%s\n",row);
}
fclose(fr);
fclose(t);
remove("tempfile.html");
}
void datumos()
{
time_t now = time(NULL);
struct tm *t = localtime(&now);
char date_time[30];
strftime( date_time, sizeof(date_time), "%x_%X", t );
FILE *htmlfile;
FILE *tempfile;
htmlfile = fopen("htmlfile.html","r");
tempfile = fopen("tempfile.html","w");
char line[MAX_SIZE];
//char datecomment[]="<!--#echo var=date -->";
while(fgets(line,sizeof(line),htmlfile) != NULL)
{
if( strcmp(line,"<!--#echo var="date" -->") == 0 )
{
char row[40];
strcpy(row,"<!--");
strcat(row, date_time);
strcat(row,"-->");
printf("%s",row);
fputs(row,tempfile);
}
else
{
fputs(line,tempfile);
}
}
fclose(htmlfile);
fclose(tempfile);
copy_file("tempfile.html","htmlfile.html");
}
it dies in this, in the inner for loop, in the if at the 200th check... i dont know why...
int n;
for(n=0; n<sizeof(htmlfiletags); ++n)
{
int j; int howmanytimesnot=0;
for(j=0; j<sizeof(tags); ++j)
{
printf("\tcheck__3/1\n");
if(strcmp(htmlfiletags[n],tags[j])==0)
{
printf("\t%d\n", howmanytimesnot);
++howmanytimesnot;
}
}
printf("\tcheck__3/3\n");
if(!(howmanytimesnot<sizeof(tags)))
{
printf("\tcheck__3/4\n");
printf("the file is not wellformed");
exit (1);
}
}
Thanks for all reply!!
G

Your code is very complicated, it has several issues.
Here's one:
for(j=0; j<sizeof(tags); ++j)
this will not do what I believe you expect; sizeof(tags) is not the array length of tags (which is declared as char tags[189][30];), it's the total size of the variable. So, this loop will go from 0 to 189 * 30 - 1, i.e. 5669, and thus index way out beyond the end of array.
Also, the idea to use sizeof here in any way is wrong, since the content of tags comes from a file and it thus impossible for the compiler to know. Remember that sizeof is evaluated at compile-time, for expressions like these.
You need to have a variable (e.g. size_t num_tags) that you increment for each line parsed from the tags file, and that you later use to iterate over tags.

Do not use regex, or some kind of string parsing, to parse HTML. Instead search the web, or this site, for a c library to parse html. Then check the parsed HTML file for the tags. This will ease the development a lot as you don't have to parse the files yourself.

i've fixed some things, but
- i still cant check the file's htmltags, dies at the same loop, i've fixed allocation of the tags array
- when in the htmlfile are 2 or more different comments and i'm replacing the comment the program replaces it with the sysdate, but the program copy the another comments badly, like =>
the code is now:
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <time.h>
#define MAX_SIZE 512
void menu();
void check();
void datumos();
int main(int argc,char *argv[])
{
menu();
return 0;
}
void menu()
{
char menu[MAX_SIZE];
while(1 < 2)
{
printf("\npress a button:\n\n");
printf("\tFile HTML check..............:c\n");
printf("\t<!--#echo var="date" -->...........:d\n");
printf("\tExit:\tCTRL + C\n");
scanf("%s",menu);
if( strcmp(menu,"c") == 0 )
{
check();
}
else if( strcmp(menu,"d") == 0 )
{
datumos();
}
}
}
void check()
{
FILE *htmlfile;
FILE *checkfile;
htmlfile = fopen("htmlfile.html","r");
checkfile = fopen("tags.txt","r");
char line[MAX_SIZE];
char htmlline[MAX_SIZE];
int i2=0;
printf("\tcheck__1\n");
while(fgets(line,sizeof(line),checkfile) != NULL)
{
++i2;
}
char tags[i2][20];
int i=0;
printf("\tcheck__11\n");
while(fgets(line,sizeof(line),checkfile) != NULL)
{
int j;
for(j=0; j<sizeof(line); ++j)
{
tags[i][j]=line[j];
}
++i;
}
printf("\tcheck__2\n");
int k=0; char htmlfiletags[MAX_SIZE][30];
while(fgets(htmlline,sizeof(htmlline),htmlfile) != NULL)
{
char currentline[sizeof(htmlline)];
int j=0;
if( currentline[j]=="<" )
{
while(currentline[j]!=">")
{
htmlfiletags[k][j]=currentline[j];
++j;
}
strcat(htmlfiletags[k][j+1],">");
++k;
}
}
printf("\tcheck__3\n");
int n;
for(n=0; n<sizeof(htmlfiletags); ++n)
{
int j; int howmanytimesnot=0;
for(j=0; j<sizeof(tags); ++j)
{
//printf("\tcheck__3/1\n");
if(strcmp(htmlfiletags[n],tags[j])==0)
{
// printf("\t%d\n", howmanytimesnot);
++howmanytimesnot;
}
}
printf("\tcheck__3/3\n");
if(!(howmanytimesnot<sizeof(tags)))
{
printf("\tcheck__3/4\n");
printf("the file is not wellformed");
exit (1);
}
}
printf("\tcheck__4\n");
}
void copy_file(const char *from,const char *to)
{
FILE *fr;
FILE *t;
fr = fopen(from,"r");
t = fopen(to,"w");
char line[MAX_SIZE];
char row[MAX_SIZE];
while(fgets(line,sizeof(line),fr) != NULL)
{
sscanf(line,"%s",row);
fprintf(t,"%s\n",row);
}
fclose(fr);
fclose(t);
remove("tempfile.html");
}
void datumos()
{
time_t now = time(NULL);
struct tm *t = localtime(&now);
char date_time[30];
strftime( date_time, sizeof(date_time), "%x_%X", t );
FILE *htmlfile;
FILE *tempfile;
htmlfile = fopen("htmlfile.html","r");
tempfile = fopen("tempfile.html","w");
char line[MAX_SIZE];
char* datecomment="<!--#echo var=\"date\" -->";
while(fgets(line,sizeof(line),htmlfile) != NULL)
{
int i3; int db=0;
for(i3=0; i3<strlen(datecomment); ++i3)
{
if(line[i3]==datecomment[i3])
{
++db;
}
}
if(db==strlen(datecomment))
{
char row[30];
strcpy(row,"<!--");
strcat(row, date_time);
strcat(row,"-->\n");
fputs(row,tempfile);
}
else
{
fputs(line,tempfile);
}
}
fclose(htmlfile);
fclose(tempfile);
copy_file("tempfile.html","htmlfile.html");
}

the currentline it's not necessary,and i've fixed the compares too
while(fgets(htmlline,sizeof(htmlline),htmlfile) != NULL)
{
int j=0;
if( htmlline[j]=='<' )
{
while(htmlline[j]!='>')
{
htmlfiletags[k][j]=htmlline[j];
++j;
}
strcat(htmlfiletags[k][j+1],">");
++k;
}
}
-in addition, the another problem to replace only the suitable comments, and dont hurt the different ones still dont work
"so it replaces
<!--#echo var="date" --> to the sysdate, it's ok, but when there are different comments like
<!--#include something -->, it wont be copied back well, in the htmlfile will be only <!--#include"
ideas?

Related

how to remove certain words from a line of text in c

I got my code working to an extent, but I need some more help. If I needed to remove the word "an", from sentence: "I ate an apple whilst looking at an ape.", it only removes the first "an" and not the second, how do I repeat the loop so it deletes all "an"s? I need the final sentence, after the code has been ran, to be: "I ate apple whilst looking at ape.". That is the goal im trying to achieve
Sorry for not including the code.
Here it is:
#include "RemoveFromText.h"
#include <stdlib.h>
#include <string.h>
int findFirstSubstring(char textToChange[], char removeThis[])
{
int size = strlen(textToChange);
int subStringLength = strlen(removeThis);
for(int i=0; i<size; i++)
{
if(textToChange[i] == removeThis[0])
{
int j = 0;
while(textToChange[i+j] == removeThis[j])
{
j++;
if(j==subStringLength)
{
return i;
}
}
}
}
return -1;
}
void removeFromText( char textToChange[], char removeThis[])
{
int textLength = strlen(textToChange);
if(findFirstSubstring(textToChange, removeThis) >= 0)
{
int subStringIdx = findFirstSubstring(textToChange, removeThis);
int loopVariabele = 0;
for(loopVariabele = subStringIdx; loopVariabele<textLength; loopVariabele++)
{
textToChange[loopVariabele] = textToChange[loopVariabele + strlen(removeThis)];
}
}
}
Leveraging 'strstr', and 'memmove' standard "C" library functions
// Remove all occurences of 'source' from 'message'.
void removeAll(char *message, char *source)
{
int len = strlen(source) ;
for (char *x = message ; x=strstr(x, source) ; ) {
// Copy everything after 'source', including terminating nul.
memmove(x, x+len, strlen(x+len)+1) ;
} ;
}
Notes:
that solution that not properly address the trailing space(s) after a word. This can be addressed by chaning the 'memmove'.
Probably make sense to make the function return the number of substitutions, or some other meaningful result

How to pass value of names in struct array as reference in C?

im supposed to be able to print all of the countries in the printfunction and pass it to the second if statement, but it doesn't seem to be printing . I know it's the
printf("%s\n", ctryList[numCountries].countryName);
part but i don't know what's wrong with it.
#include <stdio.h>
#include <string.h>
#include <stdbool.h>
const int MAX_COUNTRY_NAME_LENGTH = 50;
typedef struct CountryTvWatch_struct {
char countryName[50];
int tvMinutes;
} CountryTvWatch;
void PrintCountryNames(CountryTvWatch ctryList[], int numCountries)
{
int i;
for(i = 0; i < numCountries; i++)
{
printf("%s\n", ctryList[numCountries].countryName);
}
return;
}
int main(void) {
// Source: www.statista.com, 2010
const int NUM_COUNTRIES = 4;
CountryTvWatch countryList[NUM_COUNTRIES];
char countryToFind[MAX_COUNTRY_NAME_LENGTH];
bool countryFound = false;
int i = 0;
strcpy(countryList[0].countryName, "Brazil");
countryList[0].tvMinutes = 222;
strcpy(countryList[1].countryName, "India");
countryList[1].tvMinutes = 119;
strcpy(countryList[2].countryName, "U.K.");
countryList[2].tvMinutes = 242;
strcpy(countryList[3].countryName, "U.S.A.");
countryList[3].tvMinutes = 283;
printf("Enter country name: \n");
scanf("%s", countryToFind);
countryFound = false;
for (i = 0; i < NUM_COUNTRIES; ++i) { // Find country's index
if (strcmp(countryList[i].countryName, countryToFind) == 0) {
countryFound = true;
printf("People in %s watch\n", countryToFind);
printf("%d minutes of TV daily.\n", countryList[i].tvMinutes);
}
}
if (!countryFound) {
printf("Country not found, try again.\n");
printf("Valid countries:\n");
PrintCountryNames(countryList, NUM_COUNTRIES);
}
return 0;
}
the following proposed code:
incorporates the comments to the question
properly checks for I/O errors
lets the user know what countries are available to chose from
is appropriately spaced, both horizontally and vertically, for readability
performs the desired functionality
cleanly compiles
documents why each header file is included
and now the proposed code:
#include <stdio.h> // scanf(), printf()
#include <stdlib.h> // exit(), EXIT_FAILURE
#include <string.h> // strcmp()
#include <stdbool.h> // bool, true, false
#define MAX_COUNTRY_NAME_LENGTH 50
#define NUM_COUNTRIES 4
struct CountryTvWatch_struct
{
char countryName[ MAX_COUNTRY_NAME_LENGTH ];
int tvMinutes;
};
typedef struct CountryTvWatch_struct CountryTvWatch;
// prototypes
void PrintCountryNames( CountryTvWatch ctryList[], int numCountries );
int main(void)
{
// Source: www.statista.com, 2010
CountryTvWatch countryList[NUM_COUNTRIES];
char countryToFind[ MAX_COUNTRY_NAME_LENGTH+1];
strcpy(countryList[0].countryName, "Brazil");
countryList[0].tvMinutes = 222;
strcpy(countryList[1].countryName, "India");
countryList[1].tvMinutes = 119;
strcpy(countryList[2].countryName, "U.K.");
countryList[2].tvMinutes = 242;
strcpy(countryList[3].countryName, "U.S.A.");
countryList[3].tvMinutes = 283;
// let user know what countries are available and how they are spelled
PrintCountryNames(countryList, NUM_COUNTRIES);
printf("Enter country name: \n");
// Note: following statement
// checks for error
// includes a MAX_CHAR modifier that is one less than
// the length of the input field
if( 1 != scanf("%49s", countryToFind) )
{
perror( "scanf failed" );
exit( EXIT_FAILURE );
}
// implied else, scanf successful
bool countryFound = false;
for ( int i = 0; i < NUM_COUNTRIES; ++i )
{ // Find country's index
if (strcmp(countryList[i].countryName, countryToFind) == 0)
{
countryFound = true;
printf("People in %s watch\n", countryToFind);
printf("%d minutes of TV daily.\n", countryList[i].tvMinutes);
break; // exit the search loop early
}
}
if (!countryFound)
{
printf("Country not found, try again.\n");
printf("Valid countries:\n");
PrintCountryNames(countryList, NUM_COUNTRIES);
}
return 0;
}
void PrintCountryNames( CountryTvWatch ctryList[], int numCountries )
{
for( int i = 0; i < numCountries; i++ )
{
printf("%s\n", ctryList[ i ].countryName);
}
}

Sudoku Solver in C printing

Okay so I have all this code for a sudoku solver (it's not done, I still need my find next function and legal move function) but I could use some help with printing. The code asks for the user to upload a file to read, and then prints out the puzzle. This means sudoku can be 3x3 or 4x4, all the way up to 25x25. What I need help with, is in my print_puzzle function, how do I make sure that it prints out in blocks? Like if it was 3x3, there would be 9 3x3 boxes for the puzzle, etc. Hopefully that makes sense, anyways here's the code:
#include <stdio.h>
#include <stdbool.h>
#include <string.h>
#include <stdlib.h>
#include <math.h>
bool prompt_for_file (void);
bool load_puzzle(char filename[]);
void print_puzzle (void);
bool solve_puzzle(void);
bool find_next( int *row, int *col, int dir);
bool legal_move(int num; int row; int col);
#define MAX_SIZE 25
#define FORWARD 1
#define BACKWARD 0
int puzzle[MAX_SIZE][MAX_SIZE];
int puzzle_size;
int block_size;
int main(void)
{
if (!prompt_for_file())
{return -1;}
print_puzzle();
if (solve_puzzle())
{print_puzzle();}
else
{return -1;}
return 0;
}
bool solve_puzzle(void)
{
int dir;
int R;
int C;
int n;
int previous_n;
dir = FORWARD;
while(find_next(&R, &C, dir))
{
dir= BACKWARD;
previous_n=abs(puzzle[R][C]);
puzzle[R][C]= 0;
for (n=previous_n+1; n<=puzzle_size; n++)
{
if (legal_move(n, R, C))
{
puzzle[R][C] = -n;
dir = FORWARD;
break;
}
}
}
if (dir== FORWARD)
{return true;}
else
{return false;}
}
void print_puzzle (void)
{
int r;
int c;
printf("\n");
for (r=0;r<puzzle_size;r++)
{
for (c=0;c<puzzle_size;c++)
{
printf("%3d", abs(puzzle[r][c]));
//put something in to define blocks
}
printf("\n");
}
printf("\n");
}
/*
bool find_next( int *row, int *col, int dir)
{
*R=r;
*C=c;
}
*/
bool prompt_for_file (void)
{
char filename[100];
do
{
printf("Enter a file name (or ""quit""): ");
scanf("%s",&filename[0]);
if ( strcmp(filename,"quit")==0 )
{
filename[0]='\0';
printf("quitting\n");
return false;
}
} while( load_puzzle(filename)!=true );
return true;
}
bool load_puzzle(char filename[])
{
int r;
int c;
int dummy;
FILE *fileptr;
// open the file but return if not successful
fileptr = fopen(filename,"r");
if ( fileptr==NULL)
{
printf("the file was not opened: %s\n", filename);
return false;
}
else
{
printf("the file was opened: %s\n", filename);
}
// read the sizing info
fscanf(fileptr,"%d",&puzzle_size);
printf("the number of rows and cols: %d\n",puzzle_size);
if (puzzle_size>MAX_SIZE)
{
printf("puzzle is too big %d. Max size is %d\n", puzzle_size,MAX_SIZE);
return false;
}
block_size=sqrt(puzzle_size);
// read the data
for (r=0;r<puzzle_size;r++)
{
for (c=0;c<puzzle_size;c++)
{
if ( fscanf(fileptr,"%d",&puzzle[r][c])!=1 )
{
printf("insufficient number of elements\n");
return false;
}
}
}
// check to see if all of the data was read
// and that the end of the input file has been reached
if (fscanf(fileptr,"%d",&dummy) ==1)
{
printf("WARNING: not all numbers from file were used.\n");
}
if (feof(fileptr))
{
printf("The end of the input file has been reached.\n");
}
fclose(fileptr);
return true;
}
Thank you!!:)

Very Basic Encryption

#include <stdio.h>
int limit;
char alp[26]={'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','w','x','y','z'};
void encode(char message[21],char enc_message[21],int key);
void decode(char enc_message[21],char dec_message[21],int key);
main()
{
int key,i=0,j=0;
char message[21];
char enc_message[21];
char dec_message[21];
char encrypted[21];
char a='\0';
printf("Input the characters to encrypt\n");
while(i<21 && a!='\n')
{
scanf("%c",&a);
message[i]=a;
i=i+1;
}
for(i=0;;i++) /*custom strlen*/
{
if( message[i]= '\0')
{
limit=i;
break;
}
}
printf("Input the key");
scanf("%d",key);
for(i=0;i<21;i++)
{
enc_message[i]=message[i];
}
encode(message[21],enc_message[21],key);
for(i=0;i<21;i++)
{
dec_message[i]=enc_message[i];
}
for(i=0;i<limit;i++)
{
printf("%c",enc_message[i]);
}
printf("\n\n");
decode(enc_message[21],dec_message[21],key);
for(i=0;i<limit;i++)
{
printf("%c",dec_message[i]);
}
}
void encode(char message[21],char enc_message[21],int key)
{
/*char temp[21];*/
int x,y;
for(x=0;x<limit;x++) /* message check */
{
for(y=0;y<26;y++) /* <----- alphabet check */
{
if (enc_message[x]==alp[y]) enc_message[x]=alp[y+key];
}
}
}
/*------------------------------------------------------------------------*/
void decode(char enc_message[21],char dec_message[21],int key)
{
int x,y;
for (x=0;x<limit;x++)
{
for(y=0;y<26;y++)
{
if (dec_message[x]==alp[y+key]) dec_message[x]=alp[y];
}
}
}
The compiler says,the mistake has to do with the way I call functions(and write them)and says: passing argument1 of 'encode' makes pointer from integer without a cast ,and that is for argument 2 of 'encode' and the exact same for 'decode'
Thanks in advance!
You are passing a single element and it's not even a valid element, try
decode(enc_message, dec_message, key);
Also, format your code so it's readable that is really important, and looping to compute the length of the string to use it in another loop is not a very smart thing, print it in a loop like
for (int i = 0 ; enc_message[i] != '\0' ; ++i) ...
also, don't over use break, just think about the logical condition for the loop, it's the same one where you break. Code is much more readable if the condition appears in the right place.

How to create AT Commands Parser in C to get the incoming string from USART1?

I want to get the string from USART1 of STM32VLDiscovery (STM32F100X4) and write an AT Command Parser from the string received from USART1.
Below are the concept that I have developed but I am not sure whether it's correct or not.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "dosomethinga.h"
void dosomethingB();
void GET_AT_COMMAND(char*);
void takecommand(char *, char *);
int quit;
int main()
{ char buff[15];
char command = '\0';
quit = 0;
while(!quit)
{
printf("Enter your command: ");
scanf("%s", &buff);
if (buff[0] == 'A' && buff[1] == 'T' && buff[2] == '+')
{
GET_AT_COMMAND(buff);
}
}
}
void dosomethingB()
{
printf("dosomethingB called \n");
}
void GET_AT_COMMAND(char *text)
{
int command;
char temp[10] = "";
/*if(text[3] == 'A')
command = 1;
else if(text[3] == 'B')
command = 2;
else if(text[3] == 'Z')
command = 3;
*/
takecommand(text,temp);
if (strcmp(temp, "CALLA") == 0)
command = 1;
if (strcmp(temp, "CALLB") == 0)
command = 2;
if (strcmp(temp, "Z") == 0)
command = 3;
switch(command)
{
case 1:
dosomethingA();
break;
case 2:
printf("herehere.... \n");
dosomethingB();
break;
case 3:
printf("Exiting program.... \n");
quit = 1;
break;
default:
printf("Nothing to do here \n");
}
}
void takecommand(char *mycmd, char *hold)
{
int i;
for(i = 0; i < 10 ; i++)
{
hold[i] = mycmd[i+3];
}
}
Can anyone explain on the steps that I should do? Thanks.
Basicly you should wait an attention "AT" from the input and ignore anything before it.
For example inputs "XYZATZ\r" and "AaatZ\r" should be both handled as a "ATZ" command.
There can also be short pause between 'A' and 'T' (and all other chars of commands too), because human may type those commands.
By the default all commands end to "\r" character.
See more about AT commands from ITU-T documentation. For example from V.250 standard.
There are probably many alternative ways to implement that. The best alternative depends on your needs. If you are going to implement all AT-commands of mobile-terminal, then you should spend more time for the parser. If you want make some test application for few commands, then your implementation could be simple as your provided one.
I have developed this AT command parser, this could be use for reference.
When you get data from UART1 just call this method at_wait_msg() to parse the AT message
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
static const char *AT_HEADER = "AT";
static const char *AT_DEVICE_PROFILE = "DR";
static const char *AT_SET_DEVICE = "SD";
static const char AT_EOF = '\r';
typedef enum {
DeviceProfile,
SetDevice,
Error
} AT_Msg_Type;
typedef struct {
char header[3];
char command[3];
char data[128];
} AT_Msg_Data;
static void at_wait_msg(char text);
static void at_wait_msg_complete(char *text);
static void at_parse_msg(AT_Msg_Data *data);
static AT_Msg_Type at_check_format(AT_Msg_Data *data);
static char _rx_data[512];
static uint16_t _rx_index = 0;
int main()
{
//example data getting from UART1
char text[] = "ATDR\rATSD123456abchelloworld\r1123ATssa\r";
for (int i = 0; i < strlen(text) + 1; i++) {
//to simulate getting data from UART1 byte per byte
at_wait_msg(text[i]);
}
return 0;
}
static void at_wait_msg(char text)
{
_rx_data[_rx_index++] = text;
if (text == AT_EOF) {
at_wait_msg_complete(_rx_data);
_rx_index = 0;
}
}
static void at_wait_msg_complete(char *text)
{
AT_Msg_Data data;
int result = sscanf_s(_rx_data, "%2s%2s%s\r",
data.header, sizeof(data.header),
data.command, sizeof(data.command),
data.data, sizeof(data.data));
if (result >= 2) {
at_parse_msg(&data);
}
}
static void at_parse_msg(AT_Msg_Data *data)
{
AT_Msg_Type type = at_check_format(data);
switch (type) {
case DeviceProfile:
printf("device profile\r\n");
break;
case SetDevice:
printf("settings %s\r\n", data->data);
break;
case Error:
default:
printf("Error\r\n");
break;
}
}
static AT_Msg_Type at_check_format(AT_Msg_Data *data)
{
if (strcmp(data->header, AT_HEADER) != 0) {
return Error;
}
if (strcmp(data->command, AT_DEVICE_PROFILE) == 0) {
return DeviceProfile;
}
if (strcmp(data->command, AT_SET_DEVICE) == 0) {
return SetDevice;
}
return Error;
}

Resources