Thread: HTML tags validator

  1. #16
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Quote Originally Posted by Terrorist View Post
    So in other words, each row of those 2-D arrays should end with null char ? which is not possible, is it ?
    Why would that not be possible? You need to know where your tag ends, surely?

    But you could of course use some other end-marker, such as '>' instead of zero.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  2. #17
    Registered User
    Join Date
    May 2008
    Posts
    18
    Quote Originally Posted by matsp View Post
    Why would that not be possible? You need to know where your tag ends, surely?

    But you could of course use some other end-marker, such as '>' instead of zero.

    --
    Mats
    That's the problem matsp, knowing the end of the tag. Since I am using the '>' as a marker of ending the tag in the push function AND it indicates if there are errors such as: infiniate tags, large tags, etc..

    So what I am having as an input to the comparison is:

    opening array:
    html
    body

    closing array
    body
    html

    I have tried to initiate counters to count the opening tags and closing tags since the bracket_nr, close_nr are cleared in the writetags functions, but still nothing seems to work in this way !

  3. #18
    Registered User
    Join Date
    Apr 2008
    Posts
    396
    So in other words, each row of those 2-D arrays should end with null char ? which is not possible, is it ?
    ...you're already doing it, no? in the pushX() functions:
    Code:
      ...
      bracket[bracket_nr][bracket_char]='\0';
      ...

  4. #19
    Registered User
    Join Date
    May 2008
    Posts
    18
    Quote Originally Posted by root4 View Post
    ...you're already doing it, no? in the pushX() functions:
    Code:
      ...
      bracket[bracket_nr][bracket_char]='\0';
      ...
    Yes I did. I am trying to implement that code you gave me to adapt in here, but it doesn't seem to work. I have defined the function compare using the code you posted, called that function after the calls writetags(); and writetags2(); by passing the the current popped item from both arrays.

    The problem is that the counters to be cleared if done so, so I used similar counters to the row numbers of each array, (i.e. open_counter for open tags array row count, and close_counter for the other array). Still rubbish :S

  5. #20
    Registered User
    Join Date
    Apr 2008
    Posts
    396
    post your last version, it's difficult to help otherwise.

  6. #21
    Registered User
    Join Date
    May 2008
    Posts
    18
    Here it is:

    Code:
     #include <stdio.h>
    #define B_OPEN '<'
    #define B_CLOSE '>'
    #define BRACKET_MAX 10
    #define B_CHAR_MAX 7
    
    char bracket[BRACKET_MAX][B_CHAR_MAX]={0}; //THE OPENING BRACKETS ARRAY
    char close[BRACKET_MAX][B_CHAR_MAX]={0};  //THE CLOSING BRACKETS ARRAY
    int diagnosis, diag=0;                   // INTEGER VALUES TO COUNT THE BRACKET NUMBERS IN BOTH ARRAYS
    signed char bracket_nr, close_nr = 0; //ROW COUNT FOR BOTH ARRAYS
    char close_char, c, bracket_char = 0; //COLUMN COUNT FOR BOTH ARRAYS
    int close_counter, open_counter;
    /********************  Prototypes ***********************/
    /********************************************************/
    /********************************************************/
    int push (char c);  //TO PUSH TO THE OPENING BRACKETS ARRAY
    int push2(char c);//TO PUSH TO THE CLOSING BRACKETS ARRAY
    int writetags (void); //TO POP FROM THE OPENING BRACKETS ARRAY
    int writetags2 (void); //TO POP FROM THE CLOSING BRACKETS ARRAY
    int compare(const char* ,const char* ); //TO COMPARE BOTH ARRAYS
    
    /********************   Main      ***********************/
    /********************************************************/
    /********************************************************/
    int main (void){
    printf("Please Enter Your HTML statement..\n\n\n");
        char c=0;
        bracket_nr=-1;
        close_nr=-1;
        close_counter=0;
        open_counter=0;
        diagnosis=0;
        while((c=getchar())!=EOF && c!='\n'){
            if(c==B_OPEN){
              c=getchar();
              if (c=='/'){diagnosis=push2(c);} // THIS TO SEPARATE OPENING FROM CLOSING ARRAYS
                else  diag=push(c);
               
       }
     switch (diagnosis+diag){
     case -3:
     printf("infinate bracket.\n");
     break;
     case -5:
     printf("Too Large Bracket.\n");
     break;
     case -7:
     printf("Too many bracket.\n");
     break;
     
      };
     if ((diagnosis+diag) < 0)
     break;
     
     
     };
     if((diagnosis+diag)==0){
     printf("No brackets.\n");
     
     }else if ((diagnosis+diag) > 0){
     
      printf("\n\n** You have written &#37;d brackets, \n",(diagnosis+diag));
            
      writetags(); 
      writetags2(); 
      
      for (bracket_nr=0; bracket_nr<=open_counter && close_nr>=0; bracket_nr++, close_nr--){
      compare(bracket[bracket_nr][bracket_char], close[close_nr][close_char]); }
    
      if(diagnosis==diag) {printf("\n** You have the correct number of brackets in your HTML text.\n\n");}
       else if (diagnosis>diag){printf("\n** One or more of the OPENING tags is missing: %d tag(s)\n ", diagnosis-diag);}
        else if (diagnosis<diag){printf("\n** One or more of the CLOSING tags is missing: %d tag(s)\n ", diag-diagnosis);}
              
      }else{
      printf("Text contains errors.\n");
           
      };
           
    system ("PAUSE");
    return (diagnosis+diag);
      
     };
    
    
    /******************** Push Function**********************/
    /********************************************************/
    /********************************************************/
    int push (char c1){
    
         //char c1 = 0;
    char bracket_char =0;
         
         //c1=getchar();
    bracket_nr++;
    open_counter++;
      if(bracket_nr>=BRACKET_MAX)
        return (diag = -7); //to many tags
        diagnosis=bracket_nr+1;
         for(bracket_char=0;c1!=EOF && c1!='\n' && c1!=B_CLOSE && bracket_char<B_CHAR_MAX;bracket_char++, c1=getchar()){
       //record tag name into the stack bracket
           bracket[bracket_nr][bracket_char]=c1;
           
         };
       bracket[bracket_nr][bracket_char]='\0';
       if(c1==B_CLOSE){
         return diagnosis; 
       }else if (bracket_char>=B_CHAR_MAX){
         return(diagnosis=-5);
       }else if (c1==EOF || c=='\n')
         return (diagnosis=-3);
         
       return diagnosis;
     };
     
     
     
     
     
    /******************** Push2 Function**********************/
    /********************************************************/
    /********************************************************/
    int push2 (char c2){
    
    
         //char c =0;
    char close_char =0;
         
    c2=getchar();  //it removes the '/' from the closing tag.
    close_nr++;
    close_counter++;
    //printf("\n\nErrors in Closing Brackets,  (if They Are Any) are :\n");  // KRIS: JUST A PRINTF STATEMENT
      
      if(close_nr>=BRACKET_MAX)
        return (diagnosis = -7); //to many tags
        diagnosis=close_nr+1;
    
         
         for(close_char=0;c2!=EOF && c2!='\n' && c2!=B_CLOSE && close_char<B_CHAR_MAX;close_char++, c2=getchar()){
       //record tag name into the stack bracket
         close[close_nr][close_char]=c2;
      
       };
       
       close[close_nr][close_char]='\0'; 
           
           
       if(c2==B_CLOSE){
     return diagnosis; 
       
       }else if (close_char>=B_CHAR_MAX){
      return(diagnosis=-5);
       
       }else if (c2==EOF || c=='\n')
      return (diagnosis=-3);
    
       return diagnosis;
     };
     
     
     
    /********************  writetags function ***************/
    /********************************************************/
    /********************************************************/
    int writetags (void) {
    
    
    printf("\n\n%d Of Which is/Are Opening Tags; and it's/they are :\n",  open_counter);
        
    for(;bracket_nr>=0; bracket_nr--){
       for(bracket_char=0; bracket[bracket_nr][bracket_char]!='\0'; bracket_char++){
         putchar(bracket[bracket_nr][bracket_char]);
      }
         putchar('\n');
    }
    
    return 0;  
    };
    
    
    
    
    /********************  writetags2 function ***************/
    /********************************************************/
    /********************************************************/
    int writetags2 (void) {
    
    printf("\n\nWhile %d is/are Closing Tags; And It's/They are:\n", close_counter);
      for(;close_nr>=0; close_nr--){
         for(close_char=0; close[close_nr][close_char]!='\0'; close_char++){
         putchar(close[close_nr][close_char]);
        
      } 
    
         putchar('\n');
    
    }
    
    return 0;
    };
     
     
    
    /********************  compare function ***************/
    /********************************************************/
    /********************************************************/
    
     int compare(const char* s1,const char* s2)
     {
    
                
               
      if(!s1 || !s2) return 0;
      while(*s1 && *s1++==*s2++);
      return !*s1 && !*s2;
    
    
        
         
    }
    Last edited by Terrorist; 05-08-2008 at 12:31 PM.

  7. #22
    Registered User
    Join Date
    May 2008
    Posts
    18
    With these warnings in compilation:
    68 C:\Dev-Cpp\Projects\bracket_final_testing_with_comp.c [Warning] passing arg 1 of `compare' from incompatible pointer type
    68 C:\Dev-Cpp\Projects\bracket_final_testing_with_comp.c [Warning] passing arg 2 of `compare' from incompatible pointer type


    Edited the loop to pop one from the bottom, and another from the top:

    Code:
    for (bracket_nr=0; bracket_nr<=open_counter && close_nr>=0; bracket_nr++, close_nr--){
      compare(bracket[bracket_nr][bracket_char], close[close_nr][close_char]); }
    Last edited by Terrorist; 05-08-2008 at 11:56 AM.

  8. #23
    Registered User
    Join Date
    May 2008
    Posts
    18
    P.S. The lines with bold and red fonts are the new additions:

    Function "compare" declaration,
    Function call.
    and function definition.

  9. #24
    Registered User
    Join Date
    Apr 2008
    Posts
    396
    Here's a proposition. I cleaned up the code to make it simpler
    and reorganized a bit the error management code (it was not
    clear); you should also be careful about the indentation.
    The diagnostic at the end is uncomplete, I let you finish it - the
    tag checking code should work however. Try to rewrite it for
    yourself. I don't guarantee this is bugproof.
    Notice that you should avoid declaring global variables that
    are only used in one function (if this is the case simply declare
    them as locals); in your code, only the arrays and the 2
    associated counters have to be globals. At last, there was a
    bug in the string comparison function I provided earlier.

    Code:
    #include <stdio.h>
    
    #define B_OPEN '<'
    #define B_CLOSE '>'
    #define BRACKET_MAX 10
    #define B_CHAR_MAX 7
    
    typedef char Tag[B_CHAR_MAX];
    
    Tag bracket[BRACKET_MAX]; //THE OPENING BRACKETS ARRAY
    unsigned bracket_nr=0; // INTEGER VALUES TO COUNT THE BRACKET NUMBERS
    
    Tag close[BRACKET_MAX];  //THE CLOSING BRACKETS ARRAY
    unsigned close_nr=0; // INTEGER VALUES TO COUNT THE BRACKET NUMBERS
    
    
    int push(char c,Tag* tags,unsigned* pCounter) {
      char bracket_char=0;
    
      if(*pCounter>=BRACKET_MAX)
        return -7; // Too many tags.
    
      for(bracket_char=0;c!=EOF && c!='\n' && c!=B_CLOSE && bracket_char<B_CHAR_MAX;bracket_char++, c=getchar()) {
        // Record tag name into the tags array.
        tags[*pCounter][bracket_char]=c;
      };
    
      if (bracket_char>=B_CHAR_MAX)
        return -5; // Tag name too long.
    
      tags[*pCounter][bracket_char]='\0';
      ++*pCounter;
    
      if(c==EOF || c=='\n')
        return -3; // End of input.
    
      return 0;
    };
    
    void writetags(Tag* tags,unsigned count) {
      unsigned u;
      for(u=0;u<count;++u) printf("%u:%s\n",u,tags[u]);
      return;
    };
    
    
    int equal(const char* s1,const char* s2) {
      if(!s1 || !s2) return 0;
      while(*s1 && *s1==*s2) ++s1,++s2;
      return !*s1 && !*s2;
    }
    
    
    int main (void) {
    
      printf("Please Enter Your HTML statement..\n");
    
      char c=0;
      while((c=getchar())!=EOF && c!='\n') {
        if(c==B_OPEN) {
          int diag=0;
          c=getchar(); // Drop <
          if (c=='/') {
            c=getchar(); // Drop /
            diag=push(c,close,&close_nr); // THIS TO SEPARATE OPENING FROM CLOSING ARRAYS
          } else
            diag=push(c,bracket,&bracket_nr);
          switch(diag) {
            case -3:
              printf("Unexpected end of input.\n");
              break;
            case -5:
              printf("Tag name too long.\n");
              break;
            case -7:
              printf("Too many tags.\n");
              break;
          }
        }
      }
      if(bracket_nr==0 && close_nr==0){
        printf("No brackets.\n");
      } else {
    
        unsigned u;
    
        printf("\n** You have written %d brackets, \n",bracket_nr+close_nr);
    
        printf("\n\n%u Of Which is/Are Opening Tags; and it's/they are :\n",bracket_nr);
        writetags(bracket,bracket_nr);
    
        printf("\n\nWhile %u is/are Closing Tags; And It's/They are:\n", close_nr);
        writetags(close,close_nr);
    
        printf("\n");
    
        for(u=0;u<bracket_nr;++u) {
          if(close_nr>=1+u && !equal(bracket[u],close[close_nr-1-u])) {
            printf("Tag %u mismatch: %s/%s\n",u,bracket[u],close[close_nr-1-u]);
            break;
          }
        }
    
        if(u==bracket_nr)
          if(bracket_nr==close_nr)
            printf("\n** You have the correct number of brackets in your HTML text.\n\n");
          else
            printf("\n** Tags are missing.\n\n");
      }
    
      system ("PAUSE");
      return 0;
    };

  10. #25
    Registered User
    Join Date
    May 2008
    Posts
    18

    Thumbs up

    Thanks root4, that's pretty neat, at least as optimized as possible.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Library which extract html tags content
    By Bargi in forum C++ Programming
    Replies: 0
    Last Post: 05-10-2007, 10:17 PM
  2. Help reading file and adding html tags
    By enhancedmode in forum C Programming
    Replies: 3
    Last Post: 05-30-2005, 03:02 PM
  3. Help w/ HTML Tags
    By Landroid in forum C++ Programming
    Replies: 5
    Last Post: 03-08-2005, 08:19 PM
  4. Stacks, classes, HTML tags, and parsing.
    By Shinobi-wan in forum C++ Programming
    Replies: 5
    Last Post: 10-01-2003, 05:50 PM
  5. HTML tags
    By netboy in forum A Brief History of Cprogramming.com
    Replies: 4
    Last Post: 03-27-2002, 07:52 AM

Tags for this Thread