Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/64.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 测试LinkedList中是否存在字符串_C_Linked List - Fatal编程技术网

C 测试LinkedList中是否存在字符串

C 测试LinkedList中是否存在字符串,c,linked-list,C,Linked List,我对LinkedList几乎没有经验,也无法理解测试字符串是否在其中一个节点中的逻辑。整个程序正在等待客户端发送DNS查询,然后在无限循环中发回响应。我想做的是: 确定LinkedList是否具有客户端请求的主机名。如果不存在,请将其添加到LinkedList,并在执行查找后将答案保存到同一节点。如果有,只需向客户提供我已经查找并存储在answer[]中的答案 以下是代码的简化部分: struct queryCache { char* hostName; uint8_t answ

我对LinkedList几乎没有经验,也无法理解测试字符串是否在其中一个节点中的逻辑。整个程序正在等待客户端发送DNS查询,然后在无限循环中发回响应。我想做的是:

确定LinkedList是否具有客户端请求的主机名。如果不存在,请将其添加到LinkedList,并在执行查找后将答案保存到同一节点。如果有,只需向客户提供我已经查找并存储在
answer[]
中的答案

以下是代码的简化部分:

struct queryCache {
    char* hostName;
    uint8_t answer[UDP_RECV_SIZE];
    struct queryCache* next;
};
struct queryCache* qcRoot;

int main (int argc, char** argv) {
    // ...unrelated code

    qcRoot = malloc(sizeof(struct queryCache));
    qcRoot->hostName = 0;
    qcRoot->next = 0;

    while (1) {
        // Wait for client with recvfrom()

        char* cqHostName;
        // Code that malloc()s and strcpy()s the client hostname into cqHostName

        // Determine if cqHostName is in the cache
        int hostNameInCache = 0;
        struct queryCache* currQC = qcRoot;
        while (currQC) {
            if (!strcmp(currQC->hostName, cqHostName)) {
                puts("In the cache");
                hostNameInCache = 1;
                break;
            }
            currQC = currQC->next;
        }

        // If cqHostName is not in the cache add its name
        if (!hostNameInCache) {
            currQC->hostName = malloc(strlen(cqHostName)+1);
            strcpy(currQC->hostName, cqHostName);
            printf("Added HOSTNAME: %s to the cache\n", cqHostName);

            currQC->next = malloc(sizeof(struct queryCache));
            currQC = currQC->next;
            currQC->hostName = 0;
            currQC->next = 0;
        }

        // Code that does a recursive DNS

        // Code that will copy the response into the appropriate answer[] of the LinkedList
    }
}

在第一个客户端请求之后,程序似乎只是在没有给出错误的情况下退出。如果我删除LinkedList代码,它就可以正常工作,因此我非常确定出错的原因与我如何检查LinkedList中是否有字符串有关。

hostNameInCache
为0时,很可能
currQC
NULL
,因此您不能延迟它

将while循环的条件更改为

#------------v
while (currQC->next) {
    if (!strcmp(currQC->hostName, cqHostName)) {
            puts("In the cache");
            hostNameInCache = 1;
            break;
        }
        currQC = currQC->next;
}

在C语言中,通常有两种方法来处理单个链表:作为堆栈或作为队列

将列表作为堆栈处理时,可以在标题处添加新项。将其作为队列处理时,在尾部添加新项目


最简单的是堆栈方法:

struct node
{
    int data;
    struct node *next;
};

...

struct node *head = NULL;

/* Add one node */
struct node *n1 = malloc(sizeof(struct node));
n1->data = 1;
n1->next = head;   /* This and the next line is what adds the node */
head = n1;

/* Add another node */
struct node *n2 = malloc(sizeof(struct node));
n2->data = 2;
n2->next = head;   /* This and the next line is what adds the node */
head = n2;
在上述代码之后,列表包含两个节点:

2 --> 1 --> NULL 在此之后,列表如下所示

1 --> 2 --> NULL 1-->2-->空

我建议你把这个答案读几遍,想想你对列表的处理与这里使用的方法有何不同。我还建议您使用调试器逐行检查代码,以了解列表处理无法按预期工作的原因。

根据您的代码,当您尝试执行
currQC->hostName=malloc(strlen(cqHostName)+1)时,currQC为null

您接受的答案恰好是为了解决这一特定情况,但在while循环中,如果您执行
while(currQC->next)
操作,则会错过检查列表中的最后一项

因此,这段代码引入了另一个问题,并没有立即显现出来。我建议检查下一个元素是否为null,如果它与
if(!currQC->next)break类似,则改为break;else currQC=currQC->next


编辑:当然,我的建议意味着您将希望用do{}while(1)替换while循环;相反,因为while条件将不再被测试。

您可能希望在调试器中逐行检查代码。它可能会帮助您定位问题。顺便说一下,您的代码中可能存在未定义行为的情况。在执行查找循环之后,变量
currQC
将为
NULL
,但是您在创建新条目时会取消对它的引用。哦,您还可以使用
NULL
指针调用
strcmp
,另一种情况会导致未定义的行为。解决方案是在while循环中测试
currCQ->next
?是的,这是一个开始,但这不是所有的问题。谢谢,那以后会很头疼。我只是在while循环后添加了一个条件语句来检查最后一个。编辑:似乎是维护工作字符串的简单解决方案check@asimes如果没有将currQC添加到列表中的最后一个元素,以便添加新元素,则在循环后添加条件并不能解决问题。编辑:啊,你的意思是你保持了while(currQC->next)条件……当然,这也可以做到。
if(currQC->next&&!strcmp(currQC->next->hostName,cqHostName))
@asimes这可能会导致你错过列表最后一项的相等值,因为如果currQC->next为0,比较将不会被检查。我认为这是另一种方式。您可以使用单链表实现堆栈和队列。主要是因为我可以在SLL中混合使用这两种方法,这使得它更加通用。这没什么关系,但我认为这不正确。 1 --> 2 --> NULL