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

时间:2019-04-16 11:39:02

标签: c parsing newline string-comparison text-processing

我想使用以下函数比较两个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数组始终存在,我需要检查PtrTst-> cDatVonCom中是否包含“ szGeraeteAntwort”。 在C#中,我将使用cDatVonCom.Contains ...或类似的东西来检查是否相同。

3 个答案:

答案 0 :(得分: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);
}

假定您仅比较字符串是否相等。如果还要比较它们的 order ,那么您仍然可以使用此方法,但是您需要更加谨慎地规范化目标可以容纳的尽可能多的数据,并妥善处理数据太大的情况。

答案 1 :(得分:3)

您可以做几件事;这是两个:

  1. 解析两个字符串(例如,使用scanf()或更高级),并且在解析过程中忽略换行符。现在,您将拥有不同的字段(或指示不能正确解析其中的一行,无论如何这都是错误)。然后,您可以比较命令。
  2. 在这两个字符串上使用regular expression匹配器,仅获得命令,而忽略其他所有内容(本质上将CR和LF作为换行符处理),并比较命令。当然,您需要编写适当的正则表达式。

答案 2 :(得分: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;
}