Ненормальное поведение для обработки текстовых файлов в C
Я пытаюсь смоделировать поведение 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 ответа
Это то что ты делаешь:
Читать строку из файла в 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
body, чтобы вы печатали их, только если нашли совпадение. В настоящее время вы печатаете, даже если совпадение не найдено. В этом случае вы будете печатать мусор в качестве указателей server
а также ip_add
не были инициализированы.
Похоже, что ваша проблема может быть с 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
переменная не инициализируется в начале функции, что не может дать неожиданные (и неопределенные) результаты.
if(strcmp(flag, "1") == 0)
Вы не можете проверить это, потому что если флаг не был инициализирован, это неопределенное поведение
strcmp() ищет символ '\0' в обоих аргументах
Ниже приведен фиксированный код. Есть несколько мелких ошибок, в основном отсутствующих начальных. Подумай, что будет, если машина не найдена.
Основным является то, что вы используете один и тот же буфер для каждой итерации цикла, таким образом, очищая ранее найденный сервер. Я исправил это, выйдя из цикла. Другим способом может быть копирование найденного результата в другой буфер.
#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;
}