Thread: Trapped between conditionals and booleans

  1. #1
    Registered User
    Join Date
    May 2020
    Posts
    39

    Trapped between conditionals and booleans

    Hey, so I'm about to finish my damn task with IP pings and whatnot! Thanks a lot for your support, guys. But now, while trying to improve one of my modules, just found out how useless I'm trying to cope with conditionals and booleans. It looks like this:

    Code:
    // Process to find a substring between two strings in order to attain a certain digit.
        fp = fopen("dns1.txt", "r");
        while (fgets(line, sizeof(line), fp))
            if (start = strstr(line, PATTERN1))
            {
                start += strlen(PATTERN1);
                if (end = strstr(start, PATTERN2))
                {
                    target = (char*)malloc(end - start + 1);
                    memcpy(target, start, end - start);
                    target[end - start] = '\0';
                }
            }
    
        // Printing the result of DNS 1
        if (target) printf("\n\n    Medium value for DNS1 %s", target);
        else printf("\n    DNS 1 shows error of connectivity");
    
    ...
    
        // Comparing both DNS.
        if (target < target2) (comparing a time of response, that's why < equals actually better)
            printf("\n\n    DNS 1 is better than DNS 2.");
        else if (target > target2)
            printf("\n\n    DNS 2 is worse than DNS 1.");
        else if (target == target2)
            printf("\n\n    Both coincide.");
        else printf("\n\n    There was an error.");
    Now what I want to do:
    I'd like to fix those bold parts. I mean, if I cannot find such substring in the output .txt file I'm accessing, that would return false and print the second printf (that else if).

    If I got true (i.e., that substring was found), store it as variable target and print the first sentence (Medium value for DNS1 %s).

    Then, I'd like to aitoi it to make it an integer. No worries for that part at all (even though I've gotten my share of compiling and runtime errors, but I guess it just had to do with the previous and following part).

    If DNS 1 and DNS 2 got me true in both cases (DNS1 = true && DNS2 = true), so to speak, compare them. If one of them fails (DNS1 = false || DNS2 = false), print an error.

    So far I'm having bad luck with else... statements, which get printed all along during the execution of a certain read or ping.

    Thanks in advance for your time and attention once again...
    Last edited by JSteel; 05-08-2020 at 02:27 PM.

  2. #2
    Registered User
    Join Date
    Dec 2017
    Posts
    1,127
    To compare strings you need to use strcmp.
    Code:
    int result = strcmp(target, target2));
    if      (result < 0) printf("DNS1 better\n");
    else if (result > 0) printf("DNS2 better\n");
    else                 printf("Same\n");
    What exactly do target and target2 look like, though?
    Should they be compared numerically?
    The best argument against democracy is a five minute conversation with the average voter. - Churchill

  3. #3
    Registered User
    Join Date
    May 2020
    Posts
    39
    Quote Originally Posted by john.c View Post
    To compare strings you need to use strcmp.
    Code:
    int result = strcmp(target, target2));
    if      (result < 0) printf("DNS1 better\n");
    else if (result > 0) printf("DNS2 better\n");
    else                 printf("Same\n");
    What exactly do target and target2 look like, though?
    Should they be compared numerically?
    Thanks for the reply. Yes, that's it. I want to take a number inside a string taken off an output .txt file (like "Medium length = 234ms") and compare it between different instances, so I take for granted that a conversion from string to integer is needed and, yes, now that I look up for it, some strcmp may do the trick!

  4. #4
    Registered User
    Join Date
    Dec 2017
    Posts
    1,127
    You might be able to do something like this. The %*[^0-9] scanf format spec will skip and discard non-digits. %d will then read the integer starting at that point.
    Code:
    #include <stdio.h>
     
    int main()
    {
        char s[] = "Medium length = 123ms";
        char t[] = "Medium length = 321ms";
     
        int ns = 0, nt = 0;
        sscanf(s, "%*[^0-9] %d", &ns); 
        sscanf(t, "%*[^0-9] %d", &nt); 
     
        printf("ns: %d  nt: %d\n", ns, nt);
     
        if (ns < nt)
            printf("s < t\n");
     
        return 0;
    }
    Last edited by john.c; 05-08-2020 at 08:12 PM.
    The best argument against democracy is a five minute conversation with the average voter. - Churchill

  5. #5
    Registered User
    Join Date
    May 2020
    Posts
    39
    Just implemented the strcmp bit - works great, thanks!
    I'm toying around a bit with the later piece, will keep you posted.

    What troubles me is to be able to print error if the IP doesn't show connectivity, and therefore be able to omit the comparison bit printing some kind of extra error à la "the program couldn't compare between both DNS". That's why I tried, to no avail, with something in the lines of:

    Code:
        if (a = true) printf("\n\n    La velocidad media de DNS 1 es %s ms.", target);
        if (a = false) printf("\n    DNS 1 muestra error de conectividad.");
    I should be able to print it for both results, i.e. duplicating the code with a different variable (instead of a, let's say b) and only do the comparison bit if both a and b are true, else print me an error. It's an option, but I don't know how to proceed, and the program crashes everytime...

    Edit: Trying implementing the second one. Looks like a mess the way I did, haha..., maybe I'm able to compare both results without converting to int? When both IP's responded well, I could do the math and compare both as strings...

    So that's what I have so far, which crashes by the end of the program if one of the IP's doesn't show connectivity:

    Code:
    void compararDns() {
        FILE* fp;
        char dns1[16], dns2[16], str[50], line[50];
        const char* PATTERN1 = "Media = "; // Declararemos las variables mediante las cuales extraemos la cadena de caracteres relativa a las velocidades en nuestro diagnóstico ping.
        const char* PATTERN2 = "ms";
        char* target = NULL;
        char* target2 = NULL;
        char* start, * end;
        int ns = 0, nt = 0;
        int val1, val2;
        bool a, b;
    
        // Bloque a través del cual el usuario analiza las IP's correspondientes para analizar. 
        printf("\n    Escribe la primera IP: ");
        scanf("%s", dns1);
        printf("    Escribe la segunda IP: ");
        scanf("%s", dns2);
    
        // Bloque mediante el cual el ping es lanzado y se nos informa del proceso en curso.
        printf("\n\n    Lanzando ping sobre %s...", dns1);
        strcpy(str, "ping ");
        strcat(str, dns1);
        strcat(str, " > dns1.txt");
        system(str);
    
        printf("\n    Lanzando ping sobre %s...", dns2);
        strcpy(str, "ping ");
        strcat(str, dns2);
        strcat(str, " > dns2.txt");
        system(str);
    
        // Proceso interno mediante el cual extraemos la información del archivo redireccionado mediante los delimitadores declarados.
        fp = fopen("dns1.txt", "r");
        while (fgets(line, sizeof(line), fp))
            if (start = strstr(line, PATTERN1))
            {
                start += strlen(PATTERN1);
                if (end = strstr(start, PATTERN2))
                {
                    target = (char*)malloc(end - start + 1);
                    memcpy(target, start, end - start);
                    target[end - start] = '\0';
                }
            }
    
        // Printamos el resultado de la velocidad de DNS 1.
        if (target) printf("\n\n    La velocidad media de DNS 1 es %s ms.", target);
        else printf("\n    DNS 1 muestra error de conectividad.");
    
        // Proceso interno mediante el cual extraemos la información del archivo redireccionado mediante los delimitadores declarados.
        fp = fopen("dns2.txt", "r");
        while (fgets(line, sizeof(line), fp))
            if (start = strstr(line, PATTERN1))
            {
                start += strlen(PATTERN1);
                if (end = strstr(start, PATTERN2))
                {
                    target2 = (char*)malloc(end - start + 1);
                    memcpy(target2, start, end - start);
                    target2[end - start] = '\0';
                }
            }
    
        // Printamos el resultado de la velocidad de DNS 2.
        if (target2) printf("\n    La velocidad media de DNS 2 es %s ms.", target2);
        else printf("\n    DNS 2 muestra error de conectividad.");
    
        // Comparamos ambas velocidades y printamos la superior.
        int result = strcmp(target, target2);
        if (result < 0) printf("\n    DNS1 ofrece mejor respuesta.\n");
        else if (result > 0) printf("\n    DNS2 ofrece mejor respuesta.\n");
        else                 printf("\n    La respuesta ha sido la misma.\n");
    
        // Liberamos las variables que contienen los resultados de las velocidades medias almacenadas.
        free(target);
        free(target2);
    Last edited by JSteel; 05-09-2020 at 05:03 AM.

  6. #6
    Registered User
    Join Date
    Dec 2017
    Posts
    1,127
    If the numbers you want to compare are in strings like these:
    Code:
        char s[] = "Media = 234ms";
        char t[] = "Media = 99ms";
    Then comparing with strcmp will show t as being greater than s (since 9 is greater than 2). I.e., it compares them char by char and returns their "dictionary" order. This will seem to work as long as the two integers being compared have the same number of digits, but not otherwise.

    But in order to help you I need to know exactly what the strings can look like, which I guess I still don't know. Still, maybe something like this:
    Code:
    int get_response_time(const char *ip)
    {
        char cmd[64];
        printf("Pinging %s...\n", ip);
        sprintf(cmd, "ping %s", ip);
        int ms = 0;
        FILE *p = _popen(cmd, "r");
        char line[256];
        while (fgets(line, sizeof(line), p))
            if (sscanf(line, "Media = %dms", &ms) == 1)
                break;
        _pclose(p);
        return ms;
    }
     
    void compareIPs() {
        char ip1[32], ip2[32];
        printf("Enter first IP: ");
        scanf("%s", ip1);
        printf("Enter second IP: ");
        scanf("%s", ip2);
      
        int response1 = get_response_time(ip1);
        int response2 = get_response_time(ip2);
     
        if      (response1 < response2) printf("IP1 offers better response.\n");
        else if (response1 > response2) printf("IP2 offers better response.\n");
        else                            printf("The response times are the same.\n");
    }
    Last edited by john.c; 05-09-2020 at 09:20 AM.
    The best argument against democracy is a five minute conversation with the average voter. - Churchill

  7. #7
    Registered User
    Join Date
    May 2020
    Posts
    39
    Quote Originally Posted by john.c View Post
    If the numbers you want to compare are in strings like these:
    Code:
        char s[] = "Media = 234ms";
        char t[] = "Media = 99ms";
    Then comparing with strcmp will show t as being greater than s (since 9 is greater than 2). I.e., it compares them char by char and returns their "dictionary" order. This will seem to work as long as the two integers being compared have the same number of digits, but not otherwise.

    But in order to help you I need to know exactly what the strings can look like, which I guess I still don't know. Still, maybe something like this:
    Code:
    int get_response_time(const char *ip)
    {
        char cmd[64];
        printf("Pinging %s...\n", ip);
        sprintf(cmd, "ping %s", ip);
        int ms = 0;
        FILE *p = _popen(cmd, "r");
        char line[256];
        while (fgets(line, sizeof(line), p))
            if (sscanf(line, "Media = %dms", &ms) == 1)
                break;
        _pclose(p);
        return ms;
    }
     
    void compareIPs() {
        char ip1[32], ip2[32];
        printf("Enter first IP: ");
        scanf("%s", ip1);
        printf("Enter second IP: ");
        scanf("%s", ip2);
      
        int response1 = get_response_time(ip1);
        int response2 = get_response_time(ip2);
     
        if      (response1 < response2) printf("IP1 offers better response.\n");
        else if (response1 > response2) printf("IP2 offers better response.\n");
        else                            printf("The response times are the same.\n");
    }
    Oh, yes, my bad.
    That output file I'm scanning would look like:

    Haciendo ping a 8.8.8.8 con 32 bytes de datos:
    Respuesta desde 8.8.8.8: bytes=32 tiempo=11ms TTL=54
    Respuesta desde 8.8.8.8: bytes=32 tiempo=11ms TTL=54
    Respuesta desde 8.8.8.8: bytes=32 tiempo=11ms TTL=54
    Respuesta desde 8.8.8.8: bytes=32 tiempo=11ms TTL=54

    Estad¡sticas de ping para 8.8.8.8:
    Paquetes: enviados = 4, recibidos = 4, perdidos = 0
    (0% perdidos),
    Tiempos aproximados de ida y vuelta en milisegundos:
    M¡nimo = 11ms, M ximo = 11ms, Media = 11ms
    I would need to extract the last number in the last line after the "Media = " substring, minus the "ms" unit. In this case, the 11. Then, as I see now, convert to integer and finally compare IF and only if the two offered some response, i.e. the output file saved that "Media" info that could be scanned.

  8. #8
    Registered User
    Join Date
    Dec 2017
    Posts
    1,127
    So maybe something like this then:
    Code:
    int get_response_time(const char *ip)
    {
        char cmd[64];
        printf("Pinging %s...\n", ip);
        sprintf(cmd, "./ping %s", ip);
        int ms = -1;
        FILE *p = _popen(cmd, "r");
        char line[256];
        while (fgets(line, sizeof(line), p))
        {
            char *s = NULL;
            if ((s = strstr(line, "Media = ")) != NULL)
                if (sscanf(s, "Media = %d", &ms) == 1)
                    break;
        }
        _pclose(p);
        if (ms == -1)
        {
            fprintf(stderr, "Error: cannot read timing.\n");
            exit(EXIT_FAILURE);
        }
        return ms;
    }
     
    void compareIPs() {
        char ip1[32], ip2[32];
        printf("Enter first IP: ");
        scanf("%s", ip1);
        printf("Enter second IP: ");
        scanf("%s", ip2);
     
        int response1 = get_response_time(ip1);
        int response2 = get_response_time(ip2);
     
        if      (response1 < response2) printf("IP1 offers better response.\n");
        else if (response1 > response2) printf("IP2 offers better response.\n");
        else                            printf("The response times are the same.\n");
    }
    Or it might be written like this:
    Code:
    int get_response_time(const char *ip)
    {
        const char* const Delim = "Media = ";
     
        printf("Pinging %s...\n", ip);
     
        char cmd[64];
        sprintf(cmd, "./ping %s", ip);
     
        FILE *p = _popen(cmd, "r");
     
        char line[256];
        while (fgets(line, sizeof(line), p))
        {
            char *s = NULL;
            if ((s = strstr(line, Delim)) != NULL)
            {
                 _pclose(p);
                return atoi(s + strlen(Delim));
            }
        }
     
         _pclose(p);
     
        fprintf(stderr, "Error: cannot read timing.\n");
        exit(EXIT_FAILURE);
     
        return -1; // unreachable
    }
    Last edited by john.c; 05-09-2020 at 10:46 AM.
    The best argument against democracy is a five minute conversation with the average voter. - Churchill

  9. #9
    Registered User
    Join Date
    May 2020
    Posts
    39
    Quote Originally Posted by john.c View Post
    So maybe something like this then:
    Code:
    int get_response_time(const char *ip)
    {
        char cmd[64];
        printf("Pinging %s...\n", ip);
        sprintf(cmd, "./ping %s", ip);
        int ms = -1;
        FILE *p = _popen(cmd, "r");
        char line[256];
        while (fgets(line, sizeof(line), p))
        {
            char *s = NULL;
            if ((s = strstr(line, "Media = ")) != NULL)
                if (sscanf(s, "Media = %d", &ms) == 1)
                    break;
        }
        _pclose(p);
        if (ms == -1)
        {
            fprintf(stderr, "Error: cannot read timing.\n");
            exit(EXIT_FAILURE);
        }
        return ms;
    }
     
    void compareIPs() {
        char ip1[32], ip2[32];
        printf("Enter first IP: ");
        scanf("%s", ip1);
        printf("Enter second IP: ");
        scanf("%s", ip2);
     
        int response1 = get_response_time(ip1);
        int response2 = get_response_time(ip2);
     
        if      (response1 < response2) printf("IP1 offers better response.\n");
        else if (response1 > response2) printf("IP2 offers better response.\n");
        else                            printf("The response times are the same.\n");
    }
    Or it might be written like this:
    Code:
    int get_response_time(const char *ip)
    {
        const char* const Delim = "Media = ";
     
        printf("Pinging %s...\n", ip);
     
        char cmd[64];
        sprintf(cmd, "./ping %s", ip);
     
        FILE *p = popen(cmd, "r");
     
        char line[256];
        while (fgets(line, sizeof(line), p))
        {
            char *s = NULL;
            if ((s = strstr(line, Delim)) != NULL)
            {
                pclose(p);
                return atoi(s + (sizeof Delim - 1));
            }
        }
     
        pclose(p);
     
        fprintf(stderr, "Error: cannot read timing.\n");
        exit(EXIT_FAILURE);
     
        return -1; // unreachable
    }
    Man, that works wonderfully. I've finally implemented the latter to my code and modified quite some things but works excellently. Only one more thing: would it be possible to store those numbers as variables and print them as such?

    DNS 1 response: X ms.
    DNS 2 response: Y ms.

    Once again, THANKS a lot.

  10. #10
    Registered User
    Join Date
    Dec 2017
    Posts
    1,127
    Note that there is an error in the last part of the code you've quoted. I fixed it in the original (it should've used strlen instead of sizeof since Delim is just a pointer).
    BTW, you don't need to quote everything ... or anything, really, if you're just responding to the last post!

    And printing the responses is easy. They're in response1 and response2 in the code I posted, so just print them with printf like normal.
    The best argument against democracy is a five minute conversation with the average voter. - Churchill

  11. #11
    Registered User
    Join Date
    May 2020
    Posts
    39
    Yeah, sure. That was easy indeed, I might be too fed up with all this homework to even function properly, and I'm taking note of the quote thing as well. Cheers and, once again, thanks for your support.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. conditionals
    By s_siouris in forum C Programming
    Replies: 3
    Last Post: 03-11-2008, 07:29 AM
  2. Help plz, Booleans
    By tagman in forum C++ Programming
    Replies: 2
    Last Post: 07-26-2005, 08:30 AM
  3. Booleans in C
    By KneeLess in forum C Programming
    Replies: 6
    Last Post: 09-09-2004, 09:47 AM
  4. Conditionals
    By uniqueniq in forum C Programming
    Replies: 6
    Last Post: 02-13-2003, 06:20 PM
  5. booleans
    By Unregistered in forum C++ Programming
    Replies: 8
    Last Post: 03-10-2002, 12:01 PM

Tags for this Thread