【问题标题】:Abnormal behavior to handle text files in C在 C 中处理文本文件的异常行为
【发布时间】:2010-12-03 07:25:25
【问题描述】:

我正在尝试模拟 DNS 服务器的行为,我有一个名为 hosts.txt 的数据库,其中包含 machine_names/IP_addresses,例如:

equipo_00/169.0.1.169
sala_oeste_01/200.1.2.200
sala_oeste_02/200.2.3.200
sala_oeste_03/200.3.4.200
MEMFIS_04/201.4.5.201
ICARO_05/200.5.6.200
equipo_06/169.6.7.169
sala_este_07/201.7.8.201
sala_este_08/201.8.9.201
CEC_09/189.9.10.189

这是我的代码:

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

int main(int argc, char** argv)
{
    char* machine, *ip_add;
    FILE* db;
    char* flag;
    char  tmp[256];
    char  par[256];
    printf("> ");
    scanf("%s", par);
    db = fopen("hosts.txt", "r");
    while(db != NULL && fgets(tmp, sizeof(tmp), db) != NULL)
    {
        if(strstr(tmp, par))
        {
            flag = "1"; // flag setting to 1 means find the line
            machine = strtok(tmp, "/");//here's supposed to get the value of the machine
            ip_add = strtok(NULL, "/");//here's supposed to get the value of the ip adress
        }
    }//while

    if(strcmp(flag, "1") == 0) //
    {
        printf("here\n");
    }
    else
    {
        flag = "0"; //flag setting to 0
        printf("there\n");
    }

    printf("flag= %s pc=%s server=%s\n", flag, machine, ip_add);
    return 0;
}

我的代码从标准输入读取机器的值并指示分配给服务器上该机器的 IP 地址。问题是程序行为不正常,我不知道如何将我的代码修改为预期的输出,例如

input: equipo_00
output: flag = 1 pc = equipo_00 server=169.0.1.169

对不起,如果这个问题很愚蠢,我是这门语言的新手.. 谢谢大家的帮助,请原谅我的英语

【问题讨论】:

  • 现在有什么问题/您的代码有什么问题?

标签: c file pointers strtok strstr


【解决方案1】:

这就是你要做的:

将文件中的字符串读入tmp

检查用户输入的字符串par是否存在于tmp中。

如果是,您继续在/ 上标记tmp,并使指针machine 指向第一个片段,ip_add 指向下一个片段。

请注意,machineip_add 只是指针。它们指向tmp 的各种索引。因此,稍后当您继续循环时,您将新字符串 再次读入 tmp,并覆盖它。这会导致问题,并且您的指针现在指向已更改的字符串。

为避免这种情况,只需在成功匹配后添加一个中断:

if (strstr(tmp, par)) {
   flag = "1";
   machine = strtok(tmp, "/");
   ip_add = strtok(NULL, "/");
   break;       
}

还有你最后的printf

printf("flag= %s pc=%s server=%s\n", flag, machine, ip_add);

应该是您的if 正文的一部分,以便您仅在找到匹配项时打印它们。 当前,即使未找到匹配项,您也正在打印。在这种情况下,您将打印垃圾,因为您的指针 serverip_add 尚未未初始化

【讨论】:

  • +1 用于推荐break,而不是像许多人那样推荐strdup
【解决方案2】:

看起来您的问题可能与 flag 变量有关。使用字符串作为标志值似乎很不寻常。试试这个:

int flag = 0; // always initialise your variables

if (strstr(tmp, par) == 0) {
    flag = 1; // just an integer value
}

if (flag) { // easier to test the value too!
    // ...
}

printf("flag=%d\n", flag); // ints use %d format value

在您上面的代码中,flag 变量在函数开始时未初始化,这不会产生意外(和未定义)的结果。

【讨论】:

    【解决方案3】:

    以下是固定代码。有几个小错误,主要是缺少初始化。想想如果找不到机器会发生什么。

    主要的一点是您对循环的每次迭代都使用相同的缓冲区,从而清除先前找到的服务器。我通过退出循环解决了这个问题。另一种方法是将找到的结果复制到另一个缓冲区中。

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <unistd.h>
    
    int main(int argc, char** argv)
    {
        char* machine = "";
        char* ip_add = "";
        FILE* db;
        char* flag;
        char  tmp[256];
        char  par[256];
        printf("> ");
        scanf("%s", par);
        db = fopen("hosts.txt", "r");
        while(db != NULL && fgets(tmp, sizeof(tmp), db) != NULL)
        {
            char * found = strstr(tmp, par);
            if(found)
            {
                flag = "1"; // flag setting to 1 means find the line
                machine = strtok(found, "/");//here's supposed to get the value of the machine
                ip_add = strtok(NULL, "/");//here's supposed to get the value of the ip adress
                break;
            }
        }//while
    
        if(strcmp(flag, "1") == 0)
        {
            flag = "0"; //flag setting to 0
        }
    
        printf("flag= %s pc=%s server=%s\n", flag, machine, ip_add);
        return 0;
    }
    

    【讨论】:

      【解决方案4】:
      if(strcmp(flag, "1") == 0)
      

      你不能检查这个,因为如果标志没有被初始化它是未定义的行为

      strcmp() 在两个参数中搜索 '\0' 字符

      【讨论】:

        猜你喜欢
        • 2021-12-08
        • 2018-08-31
        • 2013-11-19
        • 1970-01-01
        • 2011-12-28
        • 2021-06-21
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多