C satrlari taqqoslash funktsiyasi

#include 
#include 

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;    
}

str and first_field are my two strings. By puts(), when both the strings are equal they print same output but strcmp() returns non zero value? Aren't str and first_field being considered as strings? When I tried to print their lengths by strlen, it didn't show any output.

1
Ugh nima uchun bular?
qo'shib qo'ydi muallif Matteo Italia, manba
Ugh nima uchun bular?
qo'shib qo'ydi muallif Matteo Italia, manba
strlen ni bosib chiqarishni harakat qilib ko'ring, balki yozilmaydigan belgilarga bog'liq bo'lishi mumkin
qo'shib qo'ydi muallif StoryTeller, manba
@ash tugmasi hali siz char * -ga tashlanasiz. Bu yerda shashka yasash odatiy emas.
qo'shib qo'ydi muallif StoryTeller, manba
@ash tugmasi hali siz char * -ga tashlanasiz. Bu yerda shashka yasash odatiy emas.
qo'shib qo'ydi muallif StoryTeller, manba
strlen() tomonidan qaytarilgan qiymatni puts() bilan ko'rsatish mumkin emas. printf() dan foydalaning.
qo'shib qo'ydi muallif DyZ, manba
strlen() tomonidan qaytarilgan qiymatni puts() bilan ko'rsatish mumkin emas. printf() dan foydalaning.
qo'shib qo'ydi muallif DyZ, manba
"hech qanday chiqish ko'rsatmadi" - bu mumkin emas. printf() ishlatganmi?
qo'shib qo'ydi muallif DyZ, manba
"hech qanday chiqish ko'rsatmadi" - bu mumkin emas. printf() ishlatganmi?
qo'shib qo'ydi muallif DyZ, manba
@ash Iltimos, sinov ma'lumotlari bilan to'liq test dasturini taqdim eting. Aks holda, sizning kuzatuvingiz qayta ishlab chiqilmaydi.
qo'shib qo'ydi muallif Scheff, manba
@ash Faqat taxmin: strcmp() ASCII bilan ishlatish uchun mo'ljallangan. UTF-8 ga tegishli bo'lsa, u bir xil kodlangan satrlari uchun ishlaydi. Biroq, Unicode/UTF-8 da ba'zi hollarda bir xil glifni ifodalash uchun bir nechta usul mavjud, masalan. "ü" kod nuqtasi 252 yoki "u" va diarez (yuqori juftlik nuqtalari) bo'lishi mumkin. Bunday holda, u teng ko'rinadi, lekin strcmp() bu haqda boshqacha fikrda.
qo'shib qo'ydi muallif Scheff, manba
@ash Faqat taxmin: strcmp() ASCII bilan ishlatish uchun mo'ljallangan. UTF-8 ga tegishli bo'lsa, u bir xil kodlangan satrlari uchun ishlaydi. Biroq, Unicode/UTF-8 da ba'zi hollarda bir xil glifni ifodalash uchun bir nechta usul mavjud, masalan. "ü" kod nuqtasi 252 yoki "u" va diarez (yuqori juftlik nuqtalari) bo'lishi mumkin. Bunday holda, u teng ko'rinadi, lekin strcmp() bu haqda boshqacha fikrda.
qo'shib qo'ydi muallif Scheff, manba
Siz xatolar uchun fopen kodini tekshirishingiz kerak.
qo'shib qo'ydi muallif Michi, manba
Siz xatolar uchun fopen kodini tekshirishingiz kerak.
qo'shib qo'ydi muallif Michi, manba
Keyin ular faqat qarash bir xil.
qo'shib qo'ydi muallif Paul Stelian, manba
Strcmp ilovangiz sızdırıyor (+ yoki - 1 tashqari qiymatlari qaytib)? Agar shunday bo'lsa, u nimani ko'rsatadi?
qo'shib qo'ydi muallif Paul Stelian, manba
Strcmp ilovangiz sızdırıyor (+ yoki - 1 tashqari qiymatlari qaytib)? Agar shunday bo'lsa, u nimani ko'rsatadi?
qo'shib qo'ydi muallif Paul Stelian, manba
Puts so'zlarini o'chirib tashladim, shuning uchun har qanday chiqishni ko'rsatib turibsiz
qo'shib qo'ydi muallif ash, manba
Puts so'zlarini o'chirib tashladim, shuning uchun har qanday chiqishni ko'rsatib turibsiz
qo'shib qo'ydi muallif ash, manba
strcmp uchun imzo turi const char * so
qo'shib qo'ydi muallif ash, manba
strcmp uchun imzo turi const char * so
qo'shib qo'ydi muallif ash, manba

6 javoblar

Belgilar faqat ko'rinadigan (chop etilmaydi) emas, balki har bir belgi kodini chop etishga harakat qiling. Keyin ikkita satr orasida farq nima ekanligini bilib olasiz.

Kabi,

char* p = str;
while (*p)
{
    printf("%02x ", p++);
}
2
qo'shib qo'ydi

Belgilar faqat ko'rinadigan (chop etilmaydi) emas, balki har bir belgi kodini chop etishga harakat qiling. Keyin ikkita satr orasida farq nima ekanligini bilib olasiz.

Kabi,

char* p = str;
while (*p)
{
    printf("%02x ", p++);
}
2
qo'shib qo'ydi

Ehtimol, ba'zi bir nusxa ko'chirilmaydigan belgilarda, masalan. \ n yoki \ r yoki (bo'sh joy) ni ko'rishingiz mumkin.

Masalan,

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

bir xil chiqdi beradi, lekin satrlari, albatta, boshqacha.

UPDATE:

Tekshirishning mumkin bo'lgan usullari:

// 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;
        }
    }
}

As an option, you can write your own comparison, that skips some characters when compare strings, or delete all non-printable characters at the end of strings before using strcmp, Masalan,

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';
}

UPDATE 2:

Bundan tashqari ochilganidan keyin fayl-belgilarini tekshiring:

fp=fopen("ip.txt","r");
if( fp )
{
    //use file - read data
}
1
qo'shib qo'ydi
@ash Men echimni qo'shdim - removeEmptyEnd (first_field) deb chaqirishingiz mumkin, bu erda '' , '\ n' va boshqasi string oxirida
qo'shib qo'ydi muallif VolAnd, manba
@ash As StoryTeller yozgan: Siz qo'shimcha ravishda tekshirishingiz mumkin. strlen() , \ r va \ n kabi har qanday belgini hisobga oladi! = 0.
qo'shib qo'ydi muallif Scheff, manba
Buni tekshirishning har qanday usuli?
qo'shib qo'ydi muallif ash, manba
ha ular qochish belgilaridan farqli ravishda turli uzunlikni ko'rsatmoqda, lekin ular bir xil belgilar (harflardagi kabi) o'z ichiga oladilar .Qanday qilib qo'shimcha qochish ketma - ketligini aniqlay olaman?
qo'shib qo'ydi muallif ash, manba

Ehtimol, ba'zi bir nusxa ko'chirilmaydigan belgilarda, masalan. \ n yoki \ r yoki (bo'sh joy) ni ko'rishingiz mumkin.

Masalan,

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

bir xil chiqdi beradi, lekin satrlari, albatta, boshqacha.

UPDATE:

Tekshirishning mumkin bo'lgan usullari:

// 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;
        }
    }
}

As an option, you can write your own comparison, that skips some characters when compare strings, or delete all non-printable characters at the end of strings before using strcmp, Masalan,

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';
}

UPDATE 2:

Bundan tashqari ochilganidan keyin fayl-belgilarini tekshiring:

fp=fopen("ip.txt","r");
if( fp )
{
    //use file - read data
}
1
qo'shib qo'ydi
@ash Men echimni qo'shdim - removeEmptyEnd (first_field) deb chaqirishingiz mumkin, bu erda '' , '\ n' va boshqasi string oxirida
qo'shib qo'ydi muallif VolAnd, manba
@ash As StoryTeller yozgan: Siz qo'shimcha ravishda tekshirishingiz mumkin. strlen() , \ r va \ n kabi har qanday belgini hisobga oladi! = 0.
qo'shib qo'ydi muallif Scheff, manba
Buni tekshirishning har qanday usuli?
qo'shib qo'ydi muallif ash, manba
ha ular qochish belgilaridan farqli ravishda turli uzunlikni ko'rsatmoqda, lekin ular bir xil belgilar (harflardagi kabi) o'z ichiga oladilar .Qanday qilib qo'shimcha qochish ketma - ketligini aniqlay olaman?
qo'shib qo'ydi muallif ash, manba

Sizning ajralishingiz maqsad majmuasining uzunligini tasdiqlamaydi. Agar ip.txt so'zlar (bitta bo'shliq yoki vergul bilan ajratilgan) 9 ta belgidan uzun bo'lsa yoki mot.txt faylidagi har qanday qatordagi birinchi so'z 6 dan ortiq bo'lsa belgilar bo'lmasa, aniqlanmagan xatti-harakatlarga olib keladigan bufercha to'ldirishingiz kerak bo'ladi.

Agar ip.txt qatoridagi satrlarda kamida 3 separator bo'lmasa va mot.txt qatoridagi barcha bo'shliqlar bo'lmasa, unda aniq harakatlaringiz bor.

Bufet oqimlarini tekshiradigan va hisobot beruvchi versiya:

#include 
#include 

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;
}
0
qo'shib qo'ydi

Sizning ajralishingiz maqsad majmuasining uzunligini tasdiqlamaydi. Agar ip.txt so'zlar (bitta bo'shliq yoki vergul bilan ajratilgan) 9 ta belgidan uzun bo'lsa yoki mot.txt faylidagi har qanday qatordagi birinchi so'z 6 dan ortiq bo'lsa belgilar bo'lmasa, aniqlanmagan xatti-harakatlarga olib keladigan bufercha to'ldirishingiz kerak bo'ladi.

Agar ip.txt qatoridagi satrlarda kamida 3 separator bo'lmasa va mot.txt qatoridagi barcha bo'shliqlar bo'lmasa, unda aniq harakatlaringiz bor.

Bufet oqimlarini tekshiradigan va hisobot beruvchi versiya:

#include 
#include 

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;
}
0
qo'shib qo'ydi