【问题标题】:Extract string before certain string在某个字符串之前提取字符串
【发布时间】:2018-08-21 01:30:15
【问题描述】:

我想在一系列特定字符或子字符串之前获取字符串。 例如,我有

unsigned char KeyStr[BUFFER_SIZE] = "-#NOT#"

unsigned char SomeStr[BUFFER_SIZE] = "this is the string i want to extract-#NOT#"

从上面的 char 数组,我想得到 this is the string i want to extract 。 我想在-#NOT#KeyStr 之前获取任何字符串。

我知道我可以使用strstr 来检查KeyStr 是否存在于SomeStr 中,但是我如何在KeyStr 之前提取字符串。 据我所知,我不能使用 strtok 原因,它检查分隔符而不是子字符串。

我是 C 的新手,所以完全一无所知。 任何帮助将不胜感激。

【问题讨论】:

  • C 还是 C++? C++ 有一些简洁的函数,但你似乎对 C 函数很感兴趣。
  • 您似乎也被固定在 C“字符串”上。这个问题中提到的唯一不是 C 的东西是 “我是 C++ 新手”。您可能在学习 C 而不是 C++?
  • 是的,实际上我使用的是 unsigned char[] 而不是 string。但大多数其他代码是 c++。所以,基本上我需要一个 C 解决方案。我已经坚持了很长一段时间了。 :(
  • 如果这是一个愚蠢的问题,我真的很抱歉。我是新手,所以对 C 语言没有太多经验。:(
  • "但大多数其他代码都是 c++。所以,基本上我需要一个 C 解决方案。" 这与逻辑结论相反。如果您正在编写 C++ 代码,则需要 C++ 解决方案。

标签: c++ c arrays string substring


【解决方案1】:

这可能不是最好的方法,但这就是我实施解决方案的方式。

unsigned char* buffer = (unsigned char*)calloc(BUFFER_SIZE, sizeof(char));
strcpy((char*)buffer, "this is the worst way possible to do this-yaL8r");

unsigned char ExtractedStr[BUFFER_SIZE] = "";
printf(">> %s\n", buffer);

// "-yaL8r" is the Key string
for (unsigned int i = 0; i < strlen((char*)buffer); i++)
{
    if (buffer[i] == '-' && buffer[i + 1] == 'y' && buffer[i + 2] == 'a' && buffer[i + 3] == 'L' && buffer[i + 4] == '8'
        && buffer[i + 5] == 'r')
    {
        break;
    }
    else
    {
        ExtractedStr[i] = buffer[i];
    }
}

printf(">> %s\n", ExtractedStr);

【讨论】:

    【解决方案2】:

    C++ 有一些简洁的函数,但由于您似乎在使用 C 字符串和 C 方法,我将给出 C 答案。大多数情况下,C 中的子字符串搜索必须手动实现。但是,对于这个简单的示例,我将为您提供一种幼稚的方法。您可以做的一件事是遍历您的字符串并寻找匹配的字符。如果找到匹配的字符,那么您可以查看下一个字符,看看它们是否对应于 keyString 中的下一个字符。大致如下:

    int simpleSubStrSearch(char * st1, char * needle) {
     int i;
     int i2;
     int j;
     int subStrIndex = 0;
     int haystackSize = strlen(st1);
     int needleSize = strlen(needle);
     int succeed = 1;
     for (i = 0; i < haystackSize; i++) {
         if (*(st1 + i) == *needle) /*Tests if the ith character equals the first character in the string we are looking for*/ {
             subStrIndex = i;
             j = 0;
             for (i2 = i; i2 < needleSize; i2++) { /*If so, then we continue looping unless the characters no longer match up*/
                 if (*(st1 + i2) == '\0') return -1; /*Return if its the end of the string*/
                 else if (*(st1 + i2) != *(needle + j)) { /*If characters no longer match in the haystack and needle string*/
                     succeed = 0;
                     break;
                 }
                 j++;
             }
             if (succeed) return subStrIndex;
         }
         else if (*(st1 + i) == '\0') return -1;
      }
    }
    

    从那里你可以只取这个函数返回的索引,只要它不是 -1(找不到针)你可以使用 memcpy 复制你想要的字符串部分。

    int index = simpleSubStrSearch(someStr, keyStr);
    if (index > 0) {
        char * noKey = (char*)malloc(index + 1);
        memcpy(noKey, someStr, index);
        *(noKey + index) = '\0'; /*Remember the null terminator*/
        printf("Succeeded: %s \n", noKey);
        free(noKey);
    } 
    

    显然,这不是一种有效的方法,因此我将留给您探索更好的子字符串算法。如果您实际上正在使用 C++,那么最简单的方法是使用 std::string 及其 substr()indexOf() 方法从 std::string 的开头到 keyString 的索引。

    【讨论】:

      【解决方案3】:

      1:(我将假设您有充分的理由使用 unsigned char 作为缓冲区而不是 char,以及为什么在 C++ 中使用旧式 C 函数而不是使用现代 C++ 方法)。

      就像您在问题中所说,您可以使用strstr() 来查找令牌。找到令牌后,您可以使用简单的指针算法来知道要复制多少个字符,使用strncpy() 进行实际复制,例如:

      unsigned char KeyStr[BUFFER_SIZE] = "-#NOT#";
      unsigned char SomeStr[BUFFER_SIZE] = "this is the string i want to extract-#NOT#";
      
      unsigned char *found = (unsigned char*) strstr((char*)SomeStr, (char*)KeyStr);
      if (!found) ...
      
      unsigned char extracted[BUFFER_SIZE];
      strncpy((char*)extracted, (char*)SomeStr, found - SomeStr);
      

      现在,话虽如此,请考虑使用实际的 C++ 技术而不是 C:

      std:string KeyStr = "-#NOT#";
      std::string SomeStr = "this is the string i want to extract-#NOT#";
      
      std::string::size_type index = SomeStr.find(KeyStr);
      if (index == std::string::npos) ... 
      
      std::string extracted = SomeStr.substr(0, index);
      

      【讨论】:

      • 这很有帮助。 :) 谢谢@RemyLebeau
      猜你喜欢
      • 2018-06-27
      • 2014-11-24
      • 2019-03-06
      • 2019-07-08
      • 2013-02-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-12-28
      相关资源
      最近更新 更多