C中的字符串比较函数

时间:2017-02-21 06:22:53

标签: c

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

int in_mot(char *str) //check whether input from text file in mot table
{
    FILE *fp_mot;
    int i = 0, j = 0, r;
    char check[300], first_field[7];

    fp_mot = fopen("mot.txt", "r");

    while (1)
    {
        if (fgets(check, sizeof(check), fp_mot) == NULL)
        {
            printf("EOF");
            return 0;
        }
        else
        {
            i = 0;
            for (i = 0; i < 7; i++)
                first_field[i] = 0;

            i = 0;
            while (check[i] != ' ')
            {
                first_field[i] = check[i];
                i++;
            }
            first_field[i] = '\0';

            if (strcmp((char*)str, (char*)first_field) == 0)
            {
                puts(first_field);
                return 1;
            }
        }
    }
    if (j == 18)
        return 0;
}

int main()
{
    char temp[30], wc[10], str[4][10];
    int i = 0, j = 0, k = 0, z;
    FILE *fp;

    int LC = 0, RC = 0, STP = 1;

    fp = fopen("ip.txt", "r");

    while (1)
    {   //1-break a line and store in array of strings(str)
        if (fgets(temp, 30, fp) == NULL)
            break;
        else
        {
            j = 0; i = 0;
            while (j < 3)
            {
                k = 0;
                for (z = 0; z < 10; z++)
                    wc[z] = 0;
                while (temp[i] != ' ' && temp[i] != ',')
                {
                        wc[k] = temp[i];
                        i++;
                        k++;
                }
                i++;
                wc[k] = '\0';
                strcpy(str[j], wc);
                j++;
            }
        }

        //str[0][3] = '\0';
        if (in_mot(str[0]))
        {
            //printf("\n yesssssssss");
        }
    }

    return 0;    
}

strfirst_field是我的两个字符串。通过puts(),当两个字符串相等时,它们打印相同的输出,但strcmp()返回非零值? strfirst_field不被视为字符串吗?当我尝试按strlen打印长度时,它没有显示任何输出。

3 个答案:

答案 0 :(得分:2)

尝试打印每个字符代码,而不是仅显示可打印的字符(可打印)。然后你会发现两个字符串之间有什么不同。

像,

char* p = str;
while (*p)
{
    printf("%02x ", p++);
}

答案 1 :(得分:1)

也许,字符串在某些不可打印的字符中是不同的,例如您无法在屏幕上看到的\n\r(空格)。

E.g:

char first_field[] = "Test\r";
char str[] = "Test\n";
puts(first_field);
puts(str);
if ( !strcmp(str, first_field) )
{
    puts(first_field);
    return 1;
}

将提供相同的输出,但字符串确实不同。

<强>更新

可能的检查方法:

// check pointers
if (str != NULL && first_field != NULL)
{
    // check length
    if (strlen(str) == strlen(first_field))
    {
        // check content
        if (!strcmp(str, first_field))
        {
            //do something for equal strings
            return 1;
        }
    }
}

作为一个选项,您可以编写自己的比较,在比较字符串时跳过某些字符,或者在使用strcmp之前删除字符串末尾的所有不可打印字符,例如:

void removeEmptyEnd(char * str)
// removes insignificant endings (including space with code 32)
{
    if (!str)
    {
        return;
    }
    // Start from the end
    int i = strlen(str);
    // and skip space and other non-printable chars
    while (i >= 0 && str[i] <= 32)
    {
        i--; // move to next char
    }
    // put new null-termitator to the end of string
    str[i+1] = '\0';
}

更新2:

打开后检查文件指针:

fp=fopen("ip.txt","r");
if( fp )
{
     // use file - read data
}

答案 2 :(得分:0)

您的解析器不会验证目标阵列的长度。如果 ip.txt 包含长于9个字符的单词(由单个空格或逗号分隔),或者文件 mot.txt 中任何一行的第一个单词长于6字符,你会有一个缓冲区溢出,导致未定义的行为。

如果 ip.txt 中的行不包含至少3个分隔符,并且 mot.txt 中的行不包含空格,则您还有未定义的行为

这是一个检查和报告缓冲区溢出的版本:

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

int copy_word(char *dest, int size, const char *src, int len,
              const char *filename, int lineno) {
    *dest = '\0';
    if (len >= size) {
        fprintf(stderr, "%s:%d: word longer than %d characters: %.*s\n",
                filename, lineno, size - 1, len, src);
        return -1;
    }
    strncat(dest, src, len);
    return len;
}

int in_mot(const char *str) { //check whether input from text file in mot table
    FILE *fp_mot;
    char check[300], first_field[7];
    int i, lineno = 0;

    fp_mot = fopen("mot.txt", "r");
    if (fp_mot == NULL) {
        perror("cannot open file mot.txt");
        return 0;
    }

    while (fgets(check, sizeof(check), fp_mot)) {
        lineno++;
        i = strcspn(check, " \n");
        copy_word(first_field, sizeof first_field, check, i, "mot.txt", lineno);
        if (strcmp(str, first_field) == 0) {
            puts(first_field);
            return 1;
        }
    }
    return 0;
}

int main(void) {
    char temp[30], wc[10], str[4][10];
    int i, j, k;
    int lineno = 0;
    FILE *fp;

    //int LC = 0, RC = 0, STP = 1;

    fp = fopen("ip.txt", "r");
    if (fp == NULL) {
        perror("cannot open file ip.txt");
        return 1;
    }

    while (fgets(temp, sizeof(temp), fp)) {
        lineno++;
        for (j = i = 0; j < 3; j++) {
            k = strcspn(temp + i, " ,\n");
            copy_word(wc, sizeof(wc), temp + i, k, "ip.txt", lineno);
            strcpy(str[j], wc);
            i += k;
            if (temp[i] != '\0')
                i++;
        }
        if (in_mot(str[0])) {
            printf("yes!\n");
        }
    }
    return 0;
}