Question

I'm trying to simulate the behavior of a DNS server, which I have a DB named hosts.txt containing machine_names/IP_addresses, for example:

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

Here's my code:

#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;
}

My code reads from standard input, the value of the machine and indicate the IP address that is assigned to that machine on the server. The problem is that the program is not normal behavior, I do not know how to modify my code to an expected output, eg

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

Sorry if the question is rather silly, I'm new to this language .. thank you all for your help and excuse my English

Was it helpful?

Solution

This is what you do:

Read a string from the file into tmp.

Check if user entered string par is present in tmp.

If yes you go ahead and tokenize tmp on / and make the pointer machine point to the first piece and ip_add point to the next piece.

Note that machine and ip_add are just pointers. And they point at various indices of tmp. So later when you continue with the loop you read the new string again into tmp, overwriting it. This causes the problem and your pointer are now pointing to a changed string.

To avoid this just add a break after a successful match:

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

Also your final printf:

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

should be part of your if body, so that you print them only if you've found the match. Currently you are printing even if a match is not found. In which case you'll be printing junk as your pointers server and ip_add have not been initialized.

OTHER TIPS

It looks like your problem might be with the flag variable. Using a string for a flag value seems very unusual. Try this:

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

In your code above, the flag variable is uninitialised at the start of the function which won't may give unexpected (and undefined) results.

Below is the fixed code. There is several minor errors, mostly missing inits. Think what would happen if machine is not found.

The main one is that you use the same buffer for each iteration of the loop, thus clearing up the previously found server. I fixed that by exiting loop. Another method could be to copy the found result in another buffer.

#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;
}
if(strcmp(flag, "1") == 0)

you can't check this because if flag wasn't initializied it's undefined behavior

strcmp() searchs for '\0' character in both arguments

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top