【问题标题】:Removing tabs and spaces between letters - segmentation fault删除字母之间的制表符和空格 - 分段错误
【发布时间】:2015-03-17 02:21:56
【问题描述】:

这是我目前所拥有的:

      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 重置为零将是一个明显的解决方法...
  • 你检查过函数 isspace() 吗?
  • 我无法将“foundAlphaNum”重置为零。要么我得到一个分段错误核心转储,要么它对我没有任何作用。或者,也许我正在完全错误地重置“foundAlphaNum”。我该怎么办?
  • 对不起,这是什么意思?

标签: c segmentation-fault whitespace removing-whitespace


【解决方案1】:

检查以下代码:

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

【讨论】:

  • Why ? down Vote 或 up Vote 是什么意思? :D
  • @Rizier123 感觉就像回到了某个时候.. :) 我真的不记得我的意思了:)
【解决方案2】:
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 //

我认为这会起作用...试试这个..

【讨论】:

    【解决方案3】:

    当您到达行尾时,您不会重置您的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';
    

    【讨论】:

      【解决方案4】:

      要让您的代码忽略每一行的前导空格,您可以在找到换行符时将foundAlphaNum 重置为零...但您应该在实际发生'\n' 测试的情况下这样做。在您修改后的代码中,'\n' 的检查发生在 else 子句中,该子句跟在 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 将设置 foundAlphaNum。然后switch,利用大小写,如果找到换行符,则清除foundAlphaNum,然后将字符添加到新字符串中,除非它是空格或制表符并且设置了foundAlphaNum。然后currentChar递增,加上终止的nul,并打印字符串。

      另请注意,您的代码(以及上面的替代代码)仅去除空格和水平制表符,并且仅在行上找到 字母数字 字符后才这样做(与任何非空格字符相反,如标点符号)。如果这不是您想要的,您可能需要将 isalnum() 替换为检查 *currentChar 不是空格或制表符。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2020-07-09
        • 1970-01-01
        • 2023-03-04
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多