Ненормальное поведение для обработки текстовых файлов в C - PullRequest
1 голос
/ 03 декабря 2010

Я пытаюсь смоделировать поведение 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

Извините, если вопрос довольно глупый, я новичок в этом языке.. спасибо всем за помощь и извините за мой английский

Ответы [ 4 ]

4 голосов
/ 03 декабря 2010

Вот что вы делаете:

Считать строку из файла в tmp.

Проверьте, присутствует ли введенная пользователем строка par в tmp.

Если да, вы идете вперед и токенизируете tmp на / и делаете указатель machine, указывающий на первый кусок, и ip_add, указывающий на следующий кусок.

Обратите внимание, что machine и ip_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 тела, так что вы печатаете их, только если нашли совпадение. В настоящее время вы печатаете, даже если совпадение не найдено. В этом случае вы будете печатать ненужную информацию, поскольку ваши указатели server и ip_add не имеют инициализации .

0 голосов
/ 03 декабря 2010
if(strcmp(flag, "1") == 0)

вы не можете проверить это, потому что если флаг не был инициализирован, это неопределенное поведение

strcmp () ищет символ '\ 0' в обоих аргументах

0 голосов
/ 03 декабря 2010

Ниже приведен фиксированный код.Есть несколько мелких ошибок, в основном отсутствующих начальных.Подумайте, что произойдет, если машина не найдена.

Основным является то, что вы используете один и тот же буфер для каждой итерации цикла, таким образом, очищая ранее найденный сервер.Я исправил это, выйдя из цикла.Другим способом может быть копирование найденного результата в другой буфер.

#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;
}
0 голосов
/ 03 декабря 2010

Похоже, ваша проблема может быть связана с переменной 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 не инициализируется в начале функции, что не может дать неожиданные (и неопределенные) результаты.

...