比较没有CR LF的两个char数组

问题描述 投票:1回答:3

我想使用以下函数来比较两个char数组:

if(strcmp((PtrTst->cDatVonCom),szGeraeteAntwort)==0)

现在我的问题是PtrTst->cDatVonCom[5000]szGeraeteAntwort[255]不同,并且整个值看起来有点不同:(来自日志文件的摘要)。

PtrTst-> cDatVonCom:

04/16/19 12:53:36 AB A{CR}{LF}
  0  0{CR}{LF}

szGeraeteAntwort:

04/16/19 12:53:36 AB A  0  0{CR}{LF}

我能检查这两个命令(在这种情况下是AB A)是否相同?该命令可以更改,并且它必须同时通过if语句。

更新:

两个char数组总是存在,我需要检查“szGeraeteAntwort”是否在PtrTst-> cDatVonCom中。在C#中我将使用cDatVonCom.Contains ...或类似的东西来检查是否有相同的。

c parsing newline string-comparison text-processing
3个回答
4
投票

您有两个字符串,其逻辑内容要比较,但它们的文字显示可能会有所不同。特别地,可能存在插入一个或两个中的CR / LF线路终止序列,这对于比较的目的而言并不重要。有很多方法可以解决这类问题,但一个常见的方法是为字符串定义一个唯一的规范形式,为这个表单准备两个字符串的版本,并比较结果。在这种情况下,规范形式可能是没有任何CR或LF字符的形式。

解决此问题的最常用方法是创建字符串的规范化副本。这解释了您无法就地修改字符串的情况。例如:

/*
 * src  - the source string
 * dest - a pointer to the first element of an array that should receive the result.
 * dest_size - the capacity of the destination buffer
 * Returns 0 on success, -1 if the destination array has insufficient capacity
 */
int create_canonical_copy(const char src[], char dest[], size_t dest_size) {
    static const char to_ignore[] = "\r\n";
    const char *start = src;
    size_t dest_length = 0;
    int rval = 0;

    while (*start) {
        size_t segment_length = strcspn(start, to_ignore);

        if (dest_length + segment_length + 1 >= dest_size) {
            rval = -1;
            break;
        }
        memcpy(dest + dest_length, start, segment_length);
        dest_length += segment_length;
        start += segment_length;
        start += strspn(start, to_ignore);
    }
    dest[dest_length] = '\0';

    return rval;
}

您可以这样使用:

char tmp1[255], tmp2[255];

if (create_canonical_copy(PtrTst->cDatVonCom, tmp1, 255) != 0) {
    // COMPARISON FAILS: cDatVonCom has more non-CR/LF data than szGeraeteAntwort
    // can even accommodate
    return -1;
} else if (create_canonical_copy(szGeraeteAntwort, tmp2, 255) != 0) {
    // should not happen, given that szGeraeteAntwort's capacity is the same as tmp2's.
    // If it does, then szGeraeteAntwort must not be properly terminated
    assert(0);
    return -1;
} else {
    return strcmp(tmp1, tmp2);
}

这假设您只是比较字符串是否相等。如果您正在将它们与订单进行比较,那么您仍然可以使用这种方法,但是您需要更加关注规范化目标可以容纳的数据,以及正确处理数据 - 太大的情况。


3
投票

可以使用在跳过某些字符时比较字符串的函数。

#include <stdio.h>
#include <string.h>

int strcmpskip ( char *match, char *against, char *skip) {
    if ( ! match && ! against) { //both are NULL
        return 0;
    }
    if ( ! match || ! against) {//one is NULL
        return 1;
    }
    while ( *match && *against) {//both are not zero
        while ( skip && strchr ( skip, *match)) {//skip not NULL and *match is in skip
            match++;
            if ( ! *match) {//zero
                break;
            }
        }
        while ( skip && strchr ( skip, *against)) {//skip not NULL and *against is in skip
            against++;
            if ( ! *against) {//zero
                break;
            }
        }
        if ( *match != *against) {
            break;
        }
        if ( *match) {//not zero
            match++;
        }
        if ( *against) {//not zero
            against++;
        }
    }
    return *match - *against;
}

int main( void) {
    char line[] = "04/16/19 12:53:36 AB A\r\n 0  0\r\n";
    char text[] = "04/16/19 12:53:36 AB A 0  0\r\n";
    char ignore[] = "\n\r";

    if ( strcmpskip ( line, text, ignore)) {
        printf ( "do not match\n");
    }
    else {
        printf ( "match\n");
    }

    return 0;
}

3
投票

你可以做几件事;这里有两个:

  1. 解析两个字符串(例如使用scanf()或其他更奇特的东西)),并且在解析期间忽略换行符。现在你将拥有不同的字段(或指示其中一行无法正确解析,无论如何都是错误)。然后你可以比较命令。
  2. 在这两个字符串上使用regular expression匹配器,只获取命令而忽略其他所有内容(基本上将CR和LF视为换行符),并比较命令。当然,您需要编写适当的正则表达式。
© www.soinside.com 2019 - 2024. All rights reserved.