0

我想做一个简单的程序(但对我来说很难),它将通过字母(部分姓名使用数字输入)和数字(部分数字)查找联系人。输入 - 数字,来自标准输入(txt 文件),输出 - 包含这些数字(字母)的联系人。联系人文件看起来像

(姓名)
(号码)
(姓名)
(…)

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

#define MAX_NAME (128)
#define MAX_NUM (32)
/*
IN :
contacts.txt :
    Sad Mirrow
    38074025
    Deniel Kovalski
    78032596
    Miky Trance
    88055535
    Martin Worried
    77432651

    96 [key number from standard entry]

OUT:

    Deniel Kovalski 
    [because 96 matches in his number]
    Martin Worried
    [96 matches in his name Wo]
*/


typedef struct Contact {
    char* name;
    char* number;
} Contact;

char matchTable[10][9] = {
    "0+", "1", "2abcABC", "3defDEF", "4ghiGHI",
    "5jklJKL", "6mnoMNO", "7pqrsPQRS", "8tuvTUV", "9wxyWXY"
};


bool find(char c, char key){

    int j = key - '0';
    for (int i = 0; matchTable[j][i] != '\0'; i++){
        if (c == matchTable[j][i])
            return true;
    }
    return false;

}

bool matches(char* src, char* key){

    unsigned int i,j;

    for (i = 0; src[i] != '\0'; i++){
        int tmp = i;
        for (j = 0; key[j] != '\0'; j++){
            if (find(src[tmp], key[j]))
                tmp++;
            else
                break;
        }
        if (j == strlen(key))
            return true;
    }
    return false;
}

int main(){

    char key[MAX_NUM];
    scanf("%s", key);
    size_t arrSize = 32;

    Contact* contacts = malloc(arrSize * sizeof(Contact));

    int k = 0;
    size_t nameSize = MAX_NAME;
    size_t numSize = MAX_NUM;
    char *nameBuf = malloc(MAX_NAME);
    char *numBuf = malloc(MAX_NUM);

    FILE* f = fopen("contacts.txt", "r");


    while (fgets(nameBuf, nameSize, f)
            && fgets(numBuf, numSize, f)){
        contacts[k].name = malloc(MAX_NAME);
        contacts[k].number = malloc(MAX_NUM);
        strcpy(contacts[k].name, nameBuf);
        strcpy(contacts[k].number, numBuf);

        k++;
        if (k == arrSize);
            arrSize <<= 1;
        contacts = realloc(contacts, arrSize * sizeof(Contact));
    }

    for (int i = 0; i < k; i++){
        bool matchesName = matches(contacts[i].name, key);
        bool matchesNumber = matches(contacts[i].number, key);

        if (matchesName || matchesNumber)
            printf("%s\n", contacts[i].name);
    }

    for (int i = 0; i < k; i++){
        free(contacts[i].name);
        free(contacts[i].number);
    }
    free(contacts);
    free(nameBuf);
    free(numBuf);
    fclose(f);

    return 0;
}

起初我们尽我们所能。然后是完成任务条件的时间,问题来了。它需要在没有 malloc/calloc/fopen 的情况下完成。我试图解决所有问题,但遇到了程序无法运行的问题,在我看来我很困惑。

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>
#define MAX_NAME (128)
#define MAX_NUM (64)

struct Folio
{
    char name[1000];
    char num[1000];
};

static char matchTable[10][9] = {
    "0+", "1", "2abcABC", "3defDEF", "4ghiGHI",
    "5jklJKL", "6mnoMNO", "7pqrsPQRS", "8tuvTUV", "9wxyWXY"
};


int find(char c, char key){

    int j = key - '0';
    for (int i = 0; matchTable[j][i] != '\0'; i++){
        if (c == matchTable[j][i])
            return 1;
    }
    return 0;

}

int matches(char* src, char* key){

   unsigned int i,j;

    for (i = 0; src[i] != '\0'; i++){
        unsigned int tmp = i;
        for (j = 0; key[j] != '\0'; j++){
            if (find(src[tmp], key[j]))
                tmp++;
            else
                break;
        }
        if (j == strlen(key))
            return 1;
    }
    return 0;
}


int main(){

    char key[MAX_NUM];
    scanf("%s", key);

    struct Folio contacts[42]; //Entry entries[42]

    int contacts_count = 0; //entries_count = 0;


    //FILE* f = fopen("seznam.txt", "r");
    char name[1000];
    char num[1000]; //number[1000]



    while (fgets(name, MAX_NAME, stdin) != NULL && fgets(num, MAX_NUM, stdin) != NULL)
    {
        // copy to struct
        strcpy(contacts[contacts_count].name, name);
        strcpy(contacts[contacts_count].num, num);

        contacts_count++;
    }

    for (int i = 0; i < contacts_count; i++){
        int matchesName = matches(contacts[contacts_count].name, key);
        int matchesNumber = matches(contacts[contacts_count].num, key);

        if (matchesName || matchesNumber)
            printf("%s%s\n", contacts[contacts_count].name, contacts[contacts_count].num);
    }

    //fclose(f);

    return 0;
}

我想请有经验的程序员帮忙。

4

2 回答 2

0

matchTable[10][9]太小,无法根据需要保存"7pqrsPQRS"字符串matchTable[j][i] != '\0';。需要10。

建议

//static char matchTable[10][9] = {
//    "0+", "1", "2abcABC", "3defDEF", "4ghiGHI",
//    "5jklJKL", "6mnoMNO", "7pqrsPQRS", "8tuvTUV", "9wxyWXY"
//};

static char *matchTable[10] = {
    "0+", "1", "2abcABC", "3defDEF", "4ghiGHI",
    "5jklJKL", "6mnoMNO", "7pqrsPQRS", "8tuvTUV", "9wxyWXY"
};

也许还有其他问题。

于 2019-11-17T17:50:48.663 回答
0

我认为主要问题是搜索逻辑。代码循环遍历所有联系人,但会尝试匹配不存在的联系人条目。

   for (int i = 0; i < contacts_count; i++){
        int matchesName = matches(contacts[contacts_count].name, key);
        int matchesNumber = matches(contacts[contacts_count].num, key);
        ...

这应该使用第 i 个联系人吗?

   for (int i = 0; i < contacts_count; i++){
        int matchesName = matches(contacts[i].name, key);
        int matchesNumber = matches(contacts[i].num, key);
        if (matchesName || matchesNumber)
            printf("%s%s\n", contacts[i].name, contacts[contacts_count].num);
    }

甚至

   for (int i = 0; i < contacts_count; i++){
        struct Folio con_p = &contacts[i] ;
        int matchesName = matches(con_p->name, key);
        int matchesNumber = matches(con_p->num, key);
        if (matchesName || matchesNumber)
            printf("%s%s\n", con_p->name, con_p->num);
    }

也看看答案chux - Reinstate Monica

于 2019-11-17T18:38:05.470 回答