c language version remove source code comments

  1. Note the following points when removing comments in the code
    First, comments have multiple or single line comments from "/ *" to "* /"
    Second, there is a single line comment of "/ /"
    Also note that characters in double and single quotation marks are not included in comments
  2. So I designed the following program
    When encountering "" double quotes and "" "", you need to skip the whole string, paying special attention to the escape characters inside the string and characters.
    When a "/" slash is encountered, match whether the next one is an asterisk or a slash. If the next one is a slash, skip directly to the end of the line. Match "* /" if asterisk
  3. Here is the source code, nothing special
#include <stdio.h>
#include <ctype.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/stat.h>

/**
* Remove the comment part of the string
**/
void remove_comment(char *buf)
{
  size_t off;
  char *s, *p, *t, *tmp;
  char *sss="adas\"d/**/\"*a\"//s/**/d*/"; // Here, the main test string is annotated

  for (s = p = buf; *p != '\0'; p++) {
    switch(*p) {
      case '"': // Loop directly to next“
      case '\'': /* Loop directly to next ' */
          // Next, find the end of the string to avoid matching the / * or//
        for (tmp = p + 1; *tmp != *p; tmp++) {
          if (*tmp == '\\') {
            tmp++; /* Skip escape position because 2 positions of escape characters represent one character */
          }
        }//Assad

        // while(1) {
          // if ( NULL != (t = strchr(tmp, '\\')) ) {
        // printf("%c\n", *tmp);
            // tmp = t + 2; / / escape character
          // }
          // if ( NULL != (t = strchr(tmp, *p)) ) {
            // tmp = t + 1; / / there are characters to find
            // break;
          // }
        // }
        // printf("%c\n", *(tmp-2));
        // exit(0);
        // while ( NULL != (t = strchr(tmp, *p)) ) {
          // tmp = t + 1; / * from next location every time*/
          // if ( *(t - 1) != '\\' ) {
            // break; / / this time the symbol is not escaped, it means that the end of the real string has been found
          // }
        // }

        off = tmp - p+1/* Calculate the length of this copy */;
        if (off > 1) {
          strncpy(s, p, off);
          p += off - 1; // There is a p + + outside, so add one less here
          s += off;
        }
      break;

      case '/':
        switch ( *(p + 1) ) {
          case '*': // Composition/*
            if (NULL != (t = strstr(p + 1, "*/"))) {
              p = t + 1; /* Here point the pointer to the / * end tag */
            }
          break;

          case '/':  //  Composition//
            for (tmp = p - 1; 0 != isspace(*tmp); tmp--) {
            } // /*The loop here is used to remove empty line comments
            s -= p - tmp - 1; // s goes back to the previous non white space character
            *s++ = '\n'; /* //Is a single line comment, so there must be a newline */

            while (*p != '\n' && *p != '\r') {
              p++;//  p pointer moves to next carriage return line feed
            }
          break;

          default: // No matching comment characters
            *s++ = *p;
          break;
        }
      break;

      default: // Write one by one if there is no matching character
        *s++ = *p;
      break;
    }
  }

  *s = '\0'; // Write end tag
}

/**
* Because the largest source file is only a few M
* So all read to memory processing, more than enough
* This is a multi line comment. If it is removed, there will be a carriage return
* And multi line comments are shortened to one line
**/
int main(int argc, char *argv[])
{
  if (argc != 2) { /* Incorrect pass through parameters */
    printf("Usage : %s file.c\n", argv[0]);
    return -1;
  }
  const char *filename = argv[1]; // Get file name

  struct stat statbuff;  /* Get file information structure */
  if(stat(filename, &statbuff) < 0){
    return -1; // Failed to get file size
  }

  off_t filesize = statbuff.st_size; // Cache file size
  char *fileBuff = (char *)malloc(sizeof(char) * filesize);

  int fd = open(filename, O_RDONLY);
  if (-1 == fd) {
    printf("open %s : %s\n", filename, strerror(errno));
    return errno;
  }

  ssize_t n = read(fd, fileBuff, filesize);
  if (n <= 0) { // Read error or empty file, close the file directly and exit
    close(fd);
    return -1;
  }

  *(fileBuff + n) = '\0'; /* Add closing */
  remove_comment(/* Divide the parameters into two and a half */fileBuff); // Remove comments
  printf("%s\n", fileBuff); /* Print results */

  close(fd);
  return 0;
}

4. Here is a function to save the above file as main.c and execute
gcc main.c && .\a.exe main.c

#include <stdio.h>
#include <ctype.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/stat.h>


void remove_comment(char *buf)
{
  size_t off;
  char *s, *p, *t, *tmp;
  char *sss="adas\"d/**/\"*a\"//s/**/d*/";

  for (s = p = buf; *p != '\0'; p++) {
    switch(*p) {
      case '"':
      case '\'':
        for (tmp = p + 1; *tmp != *p; tmp++) {
          if (*tmp == '\\') {
            tmp++;
          }
        }

        off = tmp - p+1;
        if (off > 1) {
          strncpy(s, p, off);
          p += off - 1;
          s += off;
        }
      break;

      case '/':
        switch ( *(p + 1) ) {
          case '*':
            if (NULL != (t = strstr(p + 1, "*/"))) {
              p = t + 1;
            }
          break;

          case '/':
            for (tmp = p - 1; 0 != isspace(*tmp); tmp--) {
            }
            s -= p - tmp - 1;
            *s++ = '\n';

            while (*p != '\n' && *p != '\r') {
              p++;
            }
          break;

          default:
            *s++ = *p;
          break;
        }
      break;

      default:
        *s++ = *p;
      break;
    }
  }

  *s = '\0';
}


int main(int argc, char *argv[])
{
  if (argc != 2) {
    printf("Usage : %s file.c\n", argv[0]);
    return -1;
  }
  const char *filename = argv[1];

  struct stat statbuff;
  if(stat(filename, &statbuff) < 0){
    return -1;
  }

  off_t filesize = statbuff.st_size;
  char *fileBuff = (char *)malloc(sizeof(char) * filesize);

  int fd = open(filename, O_RDONLY);
  if (-1 == fd) {
    printf("open %s : %s\n", filename, strerror(errno));
    return errno;
  }

  ssize_t n = read(fd, fileBuff, filesize);
  if (n <= 0) {
    close(fd);
    return -1;
  }

  *(fileBuff + n) = '\0';
  remove_comment(fileBuff);
  printf("%s\n", fileBuff);

  close(fd);
  return 0;
}

Keywords: Asterisk less

Added by PHPeter on Thu, 21 May 2020 17:44:02 +0300