【问题标题】:substring position in cc中的子字符串位置
【发布时间】:2018-08-16 08:42:33
【问题描述】:

我不仅想知道子字符串是否存在于缓冲区中,还想知道它结束的位置。我正在做一个 ftp,它会寻找@filestart;开始复制文件,只有在找到 @fileend 时才会返回文件; 我将发送第一条类似这样的消息:@filestart;len=50; 第一部分很简单,因为我可以使用 strstr 找到 @filestart。但在那之后我想知道 len 的结尾,所以我可以“运行”到缓冲区,从那个位置向前直到找到等号并开始复制长度直到字符“;”或 '\0" 被发现。对不起,我的废话英语,我来自巴西,不懂英语,但我希望你们都能理解。我做了一个函数来做到这一点,但我想知道是否' t 有一个标准的。这是我的:

#define unsigned int B32U
#define char B8

B32U strsub(B8 *data, B8 *key) {
    if (data && key) {
        B8 *d = data;
        B32U len = strlen(key), p = 0;
        if (len > strlen(d))
            return (0);
        while (*d != '\0') {
            if (*(d + len) != '\0') {
                B32U x = 0;
                while (x < len) {
                    if (key[x] == *d) {
                        *d++;
                        p++;
                    } else
                        break;
                    x++;
                }
                if (x == len)
                    return (p);
            } else {
                if (len == 1)
                    if (*d == key[0])
                        return (p);
                B32 x = 0;
                while (x < len) {
                    if (key[x] == *d) {
                        *d++;
                        p++;
                    } else 
                        return (0);
                    x++;
                }
                return (p);
            }
            p++;
            *d++;
        }
    }
    return (0);
}

【问题讨论】:

  • 为什么不char *keyloc; if ((keyloc = strstr (data, key))) { /* key exists */ keyloc += strlen(key); /* to find one past end of key in data */ }??
  • “我不仅想知道子字符串是否存在于缓冲区中,还想知道它结束的位置。” char *start = strstr(buf, target); char *end = start != NULL ? start + strlen(target) : NULL;
  • @DavidC.Rankin 请注意,OP 的代码处理 NULL 输入,与 strstr() 不同。
  • 准确地说——合适的守卫已经在那里:)
  • 另外... 我不仅想知道子字符串是否存在于缓冲区中,还想知道它结束的位置 如果你有子字符串并且你知道在哪里它从您正在搜索的字符串开始,您已经知道它在哪里结束 - 因为您知道子字符串有多长。

标签: c substring


【解决方案1】:

这些定义确实有问题,代码无法编译:

#define unsigned int B32U
#define char B8

使用上述定义,您没有将B32U 定义为预处理器宏,而是将unsigned 定义为int B32U,而不是您想要的。

您应该改用typedef 来定义这些类型:

typedef unsigned int B32U;
typedef char B8;

或者根本不定义这些类型并使用标准类型。

您可以使用strstr 编写一个简单的函数,该函数返回一个指向匹配结束的指针或NULL 未找到匹配项:

#include <string.h>

char *strstr_end(const char *s1, const char *s2) {
    char *p = strstr(s1, s2);
    if (p)
        p += strlen(s2);
    return p;
}

如果你坚持返回从字符串开头的偏移量,你可以返回一个有符号类型,如果没有匹配,则返回值为-1,如果有匹配则返回结尾的偏移量。 ptrdiff_t 是一个很好的类型:

#include <stddef.h>
#include <string.h>

ptrdiff_t strstr_endpos(const char *s1, const char *s2) {
    char *p = strstr(s1, s2);
    if (p)
        return p - s1 + strlen(s2);
    else
        return -1;
}

【讨论】:

  • #define 有什么问题?
  • 我的代码运行时间过长,我总是使用这样的类型。
  • 不管怎样,我来测试一下。我发现你的 strstr_endpos 很漂亮。小而且非常聪明。谢谢
【解决方案2】:

要解决您的问题,您可以使用: char *strrchr(const char *str, int c)

此函数(在 string.h 中)将返回字符串 str 中最后一次出现的字符 c(';' 或 '\0')的地址。但是你只能找到一个字符,而不是一个字符串。

【讨论】:

  • 但是我怎么知道我上次出现的“int”位置?我猜它会返回一个字符,而不是一个整数?我的意图是获取 int 而不是 char
  • 在 fatc 中它会返回一个 char*,它是一个指针。但是你可以对指针进行算术运算。并且 sizeof(char)=1,所以只要得到结果并提取初始指针,你就有一个 int
  • 我会试一试,稍后我会告诉你结果。感谢您的建议
  • 我觉得这个功能不太方便。因为在最后一种情况下我读的是“;”,但在此之前我读的是“len”,所以我必须逐个字符地运行才能知道结果。我制作的 strsub 并没有太大区别。如果我必须跑到一个缓冲区中,我更愿意得到最终结果,而不是通过 strrchr 函数将其拆分为多个进程。
猜你喜欢
  • 1970-01-01
  • 2012-08-03
  • 2014-05-06
  • 1970-01-01
  • 2012-05-21
  • 2015-03-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多