【问题标题】:C pointer arithmetic array remove charsC指针算术数组删除字符
【发布时间】:2016-11-02 21:40:08
【问题描述】:

我正在编写一个接受用户评论的程序。特别是在/**/ 之外以及内部都有输入。我已经编写了循环以在我的数组中找到字符 "/",但我不确定如何删除它以及它之间的所有内容,直到它再次出现。例如,如果我的输入是 "comment /* this is my comment */",我需要删除 /* */ 和它们之间的内容。所以我的输出就是"comment"。如果没有"/* and */",它不会删除任何东西。我知道我需要一个循环,但是我将如何编写一个循环来删除数组中的字符,直到下一个 "/" 出现并删除它? 我的代码如下:

#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;
}

【问题讨论】:

  • 您只需要找到评论的开始和结束位置,然后使用这些位置进行子串和连接
  • 这可能是一个细节,但使用 scanf() 读取您的输入将忽略第一个空格后面的所有内容(请参阅stackoverflow.com/questions/1247989/…
  • @Christophe 谢谢,自从发帖以来我已经改成fgets()
  • return 从函数返回,它不是“什么都不做”

标签: c arrays loops pointers char


【解决方案1】:

我知道我需要一个循环

可以使用循环,或者使用标准库函数。将char *strstr(const char *s1, const char *s2); 视为解决方案的候选部分。

strstr函数定位s1指向的字符串中的字符序列(不包括终止空字符)在指向的字符串中的第一次出现 s2.

strstr 函数返回一个指向已定位字符串的指针,如果未找到该字符串,则返回一个空指针。

一些未经测试的代码给你一个想法。

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(*s1 == '/'){ 
if(s1[0] == '/' && s1[1] == '*') { 

当然,这不足以在 C 代码中找到 /* */ cmets,例如:

puts("/* this is not a C comment, but a string literal */");
int a = '/*', b = '*/'; 
// start of comment /* xyz */

【讨论】:

  • 很好地使用strstr() ;-)
【解决方案2】:

您的代码似乎建立在一个探索字符串字符的循环之上。因此,我向您建议以下解决方案:

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. 
}

它使用in_comment 变量来判断我们当前是否正在探索评论中的字符(并寻找评论的结尾)(并最终寻找评论的开头)。

它使用*s1s1[1] 来访问当前和下一个字符。

它使原始字符串保持不变。

Online demo

【讨论】:

  • 我试图避免在我的函数中使用 array[] 而使用指针。我应该解释一下。我确实意识到这不是 cmets 在 C 中的工作方式,而是它只是来自用户的输入字符串。
  • "/*" 出现时我发现了一个问题,但"*/" 没有出现
  • @chux /*/ 将被解释为注释的开头,如果没有注释结尾,则忽略字符串的其余部分。 /**/ 被安全忽略。您可以在在线演示中测试所有这些,链接输入字符串
  • OP 有“如果没有“/* 和 */”,它不会删除任何东西。”
  • 我喜欢这个答案能够删除 2+ cmets,如 "abc /* def */ abc /* def */ abc"
猜你喜欢
  • 1970-01-01
  • 2023-01-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-10-20
  • 2012-07-27
相关资源
最近更新 更多