繁体   English   中英

删除字母之间的制表符和空格-分段错误

[英]Removing tabs and spaces between letters - segmentation fault

这是我到目前为止的内容:

      while ((currentChar != '\0') && (i < (length - 1)))
      {

          if (isalnum(*currentChar))
          {
              foundAlphaNum = 1;
          }

          if (*currentChar != ' ' && *currentChar != '\t' && *currentChar !='\n' && foundAlphaNum)
          {
              modifiedString[i] = *currentChar;
              i++;
          }
          else if ((*currentChar == ' ' || *currentChar == '\t') && !foundAlphaNum)
          {
              modifiedString[i] = *currentChar;
              i++;
          }
          else if(*currentChar == '\n')
           {
             modifiedString[i] = *currentChar;
             i++;
             foundAlphaNum = 0;
           }

         currentChar++;

     }

     // add null terminating char (maybe...)
     modifiedString[i] = '\0';
     printf("%s\n", modifiedString);

这是我的输出:

 "       HelloLbaldkgabcdefghijklmnopqrstuvwxyz0123456789
 helluhworldzguhmornings

 hhulsuhfhdjfue12345678910morealphabettseee"

它应该在第一个字母出现之前保留任何空白,它在第一行中执行,但在其他行中将其删除。

我尝试将其重置为0,但这给了我一个分段错误核心转储

当您到达行foundAlphaNum时,您无需重置foundAlphaNum

您应该再添加一个if语句

else if ( *currentChar == '\n' )
{
  modifiedString[i] = *currentChar;
  foundAlphaNum = false;
}

你可以做这样的事情

char buf[255] = {"  your string bla bla\n  bla bla bla\n  bla bla"};
char* p = buf;
int targetIndex = 0;
char modifiedString[255] = {'\0'};
bool beforeLetter = true;

for (p = buf; *p && targetIndex < sizeof(buf); ++p)
{
  if (*p == '\n')
  {
    beforeLetter = true;
  }
  else if ( isspace(*p) && beforeLetter )
  {
    modifiedString[targetIndex++] = *p; // copy preceding spaces
  }
  else if ( isspace(*p) && !beforeLetter )
  {
    ; // skip spaces after letter is found
  }
  else if ( isalphanum(*p) )
  {
    beforeLetter = false;
    modifiedString[targetIndex++] = *p;
  }
}
 modifiedString[targetIndex++] = '\0';

检查以下代码:

while(//Assuming you are doing it line by line //)
{
    i=0;
    flag = 0;
    while ((currentChar != '\0') && (i<length-1))
    {
       if (isalnum(*currentChar))
       {
          flag = 1;
          modifiedString[i] = *currentChar;
          i++;
       }
       else if((*currentChar == ' ' || *currentChar == '\t') && !flag)
       {
          modifiedString[i] = *currentChar;
          i++;
       } 
       currentChar ++;
    }
    modifiedString[i] = '\0';
    //print or store the modified string for this line //
}

为了使您的代码忽略每行的前导空格,可以在找到换行符时将foundAlphaNum重置为零...但是您应该在实际测试'\\n'这样做。 在修改后的代码中,对'\\n'的检查发生在else子句(后面两个)之后的else子句中, if已经在该行上找到了字母数字字符(或更早的字符),则会执行if子句,因为此错误会阻止foundAlphaNum从被重置。

while循环条件中还存在一个错误,即您将指针currentChar而不是它指向的字符与'\\0' ,这可能会导致段错误。

修复这些问题(使代码大部分保持原样)可能会导致:

/* == fixed loop condition == */
while ((*currentChar != 0) && (i < (length -1)))
{
    if (isalnum(*currentChar))
    {
        foundAlphaNum = 1;
    }

    /* == moved '\n' test (now checked first) == */
    if (*currentChar == '\n')
    {
        modifiedString[i] = *currentChar;
        i++;
        foundAlphaNum = 0;
    }
    else if (*currentChar != ' ' && *currentChar != '\t' && foundAlphaNum)
    {
        modifiedString[i] = *currentChar;
        i++;
    }
    else if ((*currentChar == ' ' || *currentChar == '\t') && !foundAlphaNum)
    {
        modifiedString[i] = *currentChar;
        i++;
    }

    currentChar++;

}

// add null terminating char (maybe...)
modifiedString[i] = '\0';
printf("%s\n", modifiedString);

但是,仍有足够的空间来清理东西。 例如:

while ((*currentChar != 0) && (i < length - 1))
{
    if (isalnum(*currentChar))
        foundAlphaNum = 1;

    switch (*currentChar) {
      case '\n':
        foundAlphaNum = 0;
      case ' ':
      case '\t':
        if (foundAlphaNum)
            break;
      default:
        modifiedString[i++] = *currentChar;
    }

    currentChar++;
}
modifiedString[i] = '\0';
puts(modifiedString);

在上面, if找到字母数字字符,则if设置foundAlphaNum 然后,如果发现换行符,则使用大小写穿透switch将清除foundAlphaNum ,然后将字符添加到新字符串中,除非它是空格或制表符, foundAlphaNum已设置foundAlphaNum 然后,将currentChar递增,添加终止nul,并打印字符串。

还要注意,您的代码(以及上面的替代方法)仅去除空格和水平制表符,并且仅在在线上找到字母数字字符后才这样做(与任何非空格字符(如标点符号)相对)。 如果这不是您想要的,则可能需要用*currentChar不是空格或制表符的代替来替换isalnum()

i=0;
flag = 0;
while ((currentChar != '\0') && (i<length-1))
{
   if (isalnum(*currentChar))
   {
      flag = 1;
      modifiedString[i] = *currentChar;
      i++;
   }
   else if((*currentChar == ' ' || *currentChar == '\t') && !flag)
   {
      modifiedString[i] = *currentChar;
      i++;
   }
   else if(*currentChar == '\n')
   {
       flag = 0 ;
   } 
   currentChar ++;
}
modifiedString[i] = '\0';
//print or store the modified string for this line //

我认为这行得通...尝试一下..

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM