0

I am writing a program that takes a user's comment. Specifically one that has input outside of /* and */ and also inside. I have written my loop to find the char "/" in my array and I am unsure how to remove it and everything in between it until it appears again. For example if my input was "comment /* this is my comment */" I need to remove the /* */ and contents between. So my output would just be "comment". If there is no "/* and */" it doesn't remove anything. I know I need a loop but how would I write a loop that removes chars in the array until the next "/" appears and removes it as well? My code is as follow:

#include <stdio.h>
#include <string.h>

void remove_comment(char *s1, char *s2){

  for(; *s1 != '\0'; s1++){  //loops through array until null value
    if(*s1 == '/'){  //if array has '/' stored
                     //clear array elements till next '/' and removes it as well
  }
    else{
    return; //do nothing to array
  }
  strcpy(s2,s1); //copies new modified string to s2 for later use
}

int main(){

  char s1[101]; //declares arrays up to 100 in length with room for null character
  char s2[101];

  printf("Enter a comment: "); //enter a comment
  fgets(s1, 100, stdin);  // saves comment to array

  remove_comment(s1,s2);  //calls function

  printf("%s", s2); //prints my modified array 

  return 0;
}
  • 1
    You just need to find the start and end positions of the comment, then substring and concatenate using those positions – alter_igel Jun 30 '16 at 16:54
  • It could be a detail, but reading your input with scanf() will ignore everything that follows the first whitespace (see http://stackoverflow.com/questions/1247989/how-do-you-allow-spaces-to-be-entered-using-scanf) – Christophe Jun 30 '16 at 19:12
  • @Christophe Thank you, since time of posting I have changed to `fgets()` – I'm here for Winter Hats Jun 30 '16 at 19:50
  • `return` returns from the function, it doesn't "do nothing" – M.M Jun 30 '16 at 20:02

2 Answers2

1

I know I need a loop

Could use a loop, or use standard library functions. Consider char *strstr(const char *s1, const char *s2); as a candidate part of a solution.

The strstr function locates the first occurrence in the string pointed to by s1 of the sequence of characters (excluding the terminating null character) in the string pointed to by s2.

The strstr function returns a pointer to the located string, or a null pointer if the string is not found.

Some untested code to give you an idea.

void remove_comment(const char *src, char *dest){
  char *start = strstr(str, "/*");        // Look for beginning
  if (start) {                            // Find the beginning?
    char *end = strstr(start + 2, "*/");  // Now search 2 past
    if (end) {                            // Find the end?
      memcpy(dest, src, start - src);
      strcpy(&dest[start - src], end+2);
      return;
    }
  }
  strcpy(dest, src);
}

If you want to avoid library funcitons, I'll pass along a hint

// if(*s1 == '/'){ 
if(s1[0] == '/' && s1[1] == '*') { 

Of course this is insufficient for finding /* */ comments in C code like:

puts("/* this is not a C comment, but a string literal */");
int a = '/*', b = '*/'; 
// start of comment /* xyz */
chux - Reinstate Monica
  • 143,097
  • 13
  • 135
  • 256
1

Your code seems to build on a loop exploring the chars of the string. I propose you therefore the following solution:

void remove_comment(char *s1, char *s2) 
{
    for(int in_comment=0; *s1 ; s1++){  //loops through array until null value
      if(!in_comment && *s1 == '/' && s1[1]=='*') {  //if array has '/' follewed by '*' stored
          in_comment=1;    // we enter a comment area
          s1++; 
      }
      else if (in_comment) {     // if we are in a comment area
          if (*s1=='*' && s1[1]=='/') {    // we only look for end of comment
              in_comment = 0; 
              s1++;
          }
      }
      else *s2++=*s1;       // if we're not in comment, in all other cases we just copy current char
    }
    *s2='\0'; // don't forget to end the string. 
}

It uses a in_comment variable to tell if we are currently exploring chars in the comment (and looking for an end of comment) or not (and looking eventually for a start of comment).

It uses *s1 and s1[1] to access the current and the next char.

It leaves the original string unchanged.

Online demo

Christophe
  • 68,716
  • 7
  • 72
  • 138
  • I was trying to get away from using array[] in my function and using pointers rather. I should have explained that. I do realize that it isn't how comments work in C but rather it is just an input string from the user. – I'm here for Winter Hats Jun 30 '16 at 17:40
  • I see a problem when the `"/*"` appears, but no `"*/"` – chux - Reinstate Monica Jun 30 '16 at 17:41
  • @chux the `/*/` will be interpreted as a start of comment and the rest of the string is ignored if there's no end of comment. `/**/` is safely ignored. You can test all this in the online demo, chainging the input string – Christophe Jun 30 '16 at 17:42
  • OP has "If there is no "/* and */" it doesn't remove anything." – chux - Reinstate Monica Jun 30 '16 at 17:43
  • I like this answers ability to remove 2+ comments like `"abc /* def */ abc /* def */ abc"` . – chux - Reinstate Monica Jun 30 '16 at 17:45
  • @chux If there's "no `/*` and no `*/`" this code removes noting as expected. If OP meant "if there is an `/*` but no `*/` it removes nothing", then indeed this code should indeed be adapted (i.e. keep a copy of start pointer when entering a comment, and use a `strcpy()` from this start pointer in case end of string is reached and still in comment) – Christophe Jun 30 '16 at 18:55
  • @Chux by the way, it would be easy to add an `in_quote` state if there would be a need to ignore `/*` when it appears between quote or double quote. – Christophe Jun 30 '16 at 19:01
  • True the unmatched `"/*"` requirement is open to interpretation. +1 for your nice state-machine. BTW: I see 5+ C states: in_code, in_slash_comment, in slash_slash_comment, in_quote, in_double_quote, maybe in_pre-process (ignoring tri-graphs), maybe in_escape_seq – chux - Reinstate Monica Jun 30 '16 at 19:08