Thread: Search through file and print an IP

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

    Search through file and print an IP

    Hi there, new to the board and noob at programming.
    Hope I'm not asking something too redundant, since I'm having quite some bad time at programming a somewhat easy task.

    Just got to the point I've been able to browse through a file (var x in my program) containing several IP's, pinging them consecutively and redirecting the results to a .txt, namely "out.txt". Now I must browse through the file, search for something that gives idea of a good response at the ping (I'm working in Spanish, so in this case it would be "Media: ", since it gives the medium response rate that's unavailable unless the IP is responding).

    As adviced by my teacher, I need to find some command in the string.h library that helps me to do so, but I cannot for the life of me find anything that would help me browse through a certain file (this out.txt) instead of a string in my actual code. So far, that's what I've got:

    Code:
    void seleccionarArchivo()
    {
    
        FILE* fp, *fp2;
        char ch[500], x[225], str[80];
        
        printf("\n    Escribe la ruta del documento deseado\n\n");
        scanf("%s", x);
    
        fp = fopen(x, "r");
        fp2 = fopen("out.txt", "r"); // Entiendo que necesitaré declararlo para hacer referencia a éste para búsqueda
        freopen("out.txt", "a", stdout);
    
    
        if (fp == NULL)
        {
            printf("El archivo no se ha podido encontrar.");
            exit(0);
        }
    
        while (fgets(ch, 100, fp)) 
        {
            printf("%s", ch);
        }
    
                rewind(fp);
    
                while (!feof(fp))
                {
                    fgets(ch, 100, fp);
                    strcpy(str, "ping ");
                    strcat(str, ch);
                    system(str);
                }
    }
    Many, many thanks in advance. And sorry for my clumsy English, that stuff is getting my nerves...

  2. #2
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,660
    > while (fgets(ch, 100, fp))
    Avoid the magic numbers, by doing
    while (fgets(ch, sizeof(ch), fp))

    > while (!feof(fp))
    Your first loop was so much better.
    Why it's bad to use feof() to control a loop - Cprogramming.com

    > strcpy(str, "ping ");
    > strcat(str, ch);
    You should make str a slightly larger buffer than ch, so you know you can always safely append whatever fgets reads from the file.
    You probably need to remove the \n from the end before passing it to system().
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  3. #3
    Registered User
    Join Date
    May 2020
    Posts
    39
    Hi Salem. Thanks for your prompt answer. I took notice of your improvements and implemented them in my code.

    I don't understand this part, though:

    Quote Originally Posted by Salem View Post
    > strcpy(str, "ping ");
    > strcat(str, ch);
    You should make str a slightly larger buffer than ch, so you know you can always safely append whatever fgets reads from the file.
    You probably need to remove the \n from the end before passing it to system().
    As of now, that's how my code looks like, after revision of my teacher as well:

    Code:
    void seleccionarArchivo()
    {
    
        FILE* fp, * fp2;
        char ch[500], x[225], str[80];
    
        printf("\n    Escribe la ruta del documento deseado\n\n");
        scanf("%s", x);
    
        fp = fopen(x, "r");
        fp2 = fopen("out.txt", "r");
        freopen("out.txt", "a", stdout);
    
    
        if (fp == NULL)
        {
            printf("El archivo no se ha podido encontrar.");
            exit(0);
        }
    
        while (fgets(ch, sizeof(ch), fp))
        {
            printf("%s", ch);
        }
    
        rewind(fp);
    
        while (fgets(ch, sizeof(ch), fp) != NULL) {
            fgets(ch, sizeof(ch), fp);
            strcpy(str, "ping ");
            strcat(str, ch);
            system(str);
        }
    }

  4. #4
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,660
    Code:
        while (fgets(ch, sizeof(ch), fp) != NULL) {
            fgets(ch, sizeof(ch), fp);
    Just ONE fgets - the one inside the loop condition.
    Having another one just means you process alternate lines from the file.

    > I don't understand this part, though:

    > char ch[500], x[225], str[80];
    ...
    > while (fgets(ch, sizeof(ch), fp) != NULL)
    ...
    > strcat(str, ch);
    ch is up to 500 characters
    str is 80 characters (minus "ping ")
    Guess what happens if you read in a line longer than 80 chars.

    And don't forget about the \n issue.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  5. #5
    Registered User
    Join Date
    May 2020
    Posts
    39
    Oh, I see. Fixed.

    Now, what I don't understand:

    Quote Originally Posted by Salem View Post
    And don't forget about the \n issue.
    Where do you see the \n? I only have it on my initial printf that doesn't affect the function. Maybe you mean some other implicit \n that escapes my eye? Thanks in advance.

    Code:
    void seleccionarArchivo()
    {
    
        FILE* fp, * fp2;
        char ch[500], x[500], str[500], line[BUFSIZ];
        int linenumber = 1;
        char term[20] = "Media";
    
        printf("\n    Escribe la ruta del documento deseado\n\n");
        scanf("%s", x);
    
        fp = fopen(x, "r");
        fp2 = fopen("out.txt", "r");
        freopen("out.txt", "a", stdout);
    
    
        if (fp == NULL)
        {
            printf("El archivo no se ha podido encontrar.");
            exit(0);
        }
    
        while (fgets(ch, sizeof(ch), fp))
        {
            printf("%s", ch);
        }
    
        rewind(fp);
    
        while (fgets(ch, sizeof(ch), fp) != NULL) {
            strcpy(str, "ping ");
            strcat(str, ch);
            system(str);
            if (fp2 != NULL);
            {
                fgets(ch, sizeof(ch), fp2);
                while (fgets(ch, sizeof(ch), fp2))
                    if (strstr(ch, term) != NULL)
                    {
                        printf("IP responde", linenumber);
                    }
                ++linenumber;
            }
        }
    
        fclose(fp);
    
    }
    Last edited by JSteel; 05-04-2020 at 06:10 AM. Reason: Just messed up between different codes...

  6. #6
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,660
    > while (fgets(ch, sizeof(ch), fp) != NULL)
    It's the one that will be in here
    www.google.com\n
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  7. #7
    Registered User
    Join Date
    May 2020
    Posts
    39
    How do I fix it, then? Not sure if I get it yet.
    Please notice I messed it up badly with my pasted code. What I ideally had, with some strstr implemented, was this:

    Code:
    void seleccionarArchivo()
    {
    
        FILE* fp, * fp2;
        char ch[500], x[500], str[500], line[BUFSIZ];
        int linenumber = 1;
        char term[20] = "Media";
    
        printf("\n    Escribe la ruta del documento deseado\n\n");
        scanf("%s", x);
    
        fp = fopen(x, "r");
        fp2 = fopen("out.txt", "r");
        freopen("out.txt", "a", stdout);
    
    
        if (fp == NULL)
        {
            printf("El archivo no se ha podido encontrar.");
            exit(0);
        }
    
        while (fgets(ch, sizeof(ch), fp))
        {
            printf("%s", ch);
        }
    
        rewind(fp);
    
        while (fgets(ch, sizeof(ch), fp) != NULL) {
            strcpy(str, "ping ");
            strcat(str, ch);
            system(str);
            if (fp2 != NULL)
            {
                while (fgets(ch, sizeof(ch), fp2)) {
                    if (strstr(ch, term) != NULL)
                    {
                        printf("IP responde", linenumber);
                    }
                }
                ++linenumber;
            }
        }
    
        fclose(fp);
    
    }
    Last edited by JSteel; 05-04-2020 at 06:34 AM.

  8. #8
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,660
    Get a line of text from the user/keyboard (C) - Cprogramming.com

    fp2 = fopen("out.txt", "r");
    freopen("out.txt", "a", stdout);

    To be honest, you're going to be better off using popen.
    This redirect stdout and read just isn't going to work.

    Code:
        while (fgets(ch, sizeof(ch), fp) != NULL) {
            strcpy(str, "ping ");
            strcat(str, ch);
            FILE *fp2 = popen(str,"r");
            while( fgets(ch,sizeof(ch),fp2) != NULL ) {
                // do something with the output of ping
            }
            pclose(fp);
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  9. #9
    Registered User
    Join Date
    May 2020
    Posts
    39
    Thanks for your reply.
    Now, a different question arises: how do I print my standard output both as file.txt whilst showing the results on the console?
    Now my teacher just told me that I need to do so (I was told otherwise before).

    Just got rid of freopen and I'm toying with different "fprintf(fp2, "%s", stdout)" and similar options to no avail. Also, I've tried the following but just saves the second IP (without displaying on the screen):

    Code:
        while (fgets(ch, sizeof(ch), fp) != NULL) {
            strcpy(str, "ping ");
            strcat(str, ch);
    strcat(str, "> out.txt");
            system(str);
                }

  10. #10
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    It may or may not be beyond the scope of what your teacher intended, but one idea is to define your own version of fprintf that has the exact same parameters, implemented by forwarding the va_list (and a copy thereof via va_copy) to vprintf (to print to stdout) and vfprintf (to print to the designated file, e.g., file.txt). So you call jsteel_fprintf once and it'll print to stdout and file.txt at one go.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  11. #11
    Registered User
    Join Date
    May 2020
    Posts
    39
    Fine, I'm still stuck in the same problem yet with a different approach. I've tried getting rid of freopen and now I'm trying to export the ping results through ">out.txt". So far I've been able to ping the IP's but I don't know how I messed up badly and I can't for the life of me ping the former, it just goes to the second line of my initial file (variable x).

    I've tried with fseek, rewind and so on, but to no avail. Please help!

    BTW - yes, the while is incomplete. I just want to be able to ping the first line and then I'll work my way for a proper iteration.

    Code:
        while (fgets(ch, sizeof(ch), fp))
        {
            printf("%s", ch);
        }
        fclose(fp);
    
        fp = fopen(x, "a");
            strcpy(str, "ping ");
            strcat(str, ch);
            strcat(str, ">out.txt");
            system(str);
            fclose(fp);
            fp2 = fopen("out.txt", "r");
            while (fgets(line, sizeof(line), fp2)) {
                if (strstr(line, term) != NULL) {
                    printf("%s", "\n\n   IP responde positivamente: ");
                    printf("%s", ch);
                }
            }

  12. #12
    Registered User
    Join Date
    Dec 2017
    Posts
    1,626
    Maybe try something like this.
    Code:
    void ping(const char *ip) {
        char ping_cmd[256];
        sprintf(ping_cmd, "ping %s", ip);
        FILE *f = popen(ping_cmd, "r");  // popen is a posix function
        while (fgets(line, sizeof line, f))
            if (strstr(line, term))
                printf("\n\n   IP responde positivamente: %s", ip);
        pclose(f);
    }
    A little inaccuracy saves tons of explanation. - H.H. Munro

  13. #13
    Registered User
    Join Date
    May 2020
    Posts
    39
    Hey, thanks for your fast reply. But please take in mind that I'm using Windows, if I'm not mistaken, popen is not supported (maybe I'm just speaking nonsense, but I cannot find any way to compile it properly). OTOH, thanks for the much cleaner code at the end.

  14. #14
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,660
    _popen, _wpopen | Microsoft Docs
    You need an initial underscore for Windosw
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  15. #15
    Registered User
    Join Date
    May 2020
    Posts
    39
    Now, with a different block of my program... I need to search through a .txt file and print those strings (i.e. lines) containing some terms. I'm having quite some bad luck printing them, for they come out with null values. I guess it has to do with such \n in fgets, but still I'm unable to remove it, nor even with the link provided before by Salem, maybe a different command should do better?

    Code:
        char str[500], line[100], line2[100], line3[100], line4[100];
    char termIp[20] = "IPv4", termMask[20] = "subred", termDoor[20] = "Puerta", termDNS[20] = "Servidores DNS";
    
    strcpy(str, ">> ip.out.txt ");
    strcat(str, "ipconfig /allcompartments /all");
    system(str);
    
    fp = fopen("ip.out.txt", "r");
    
    while (fgets(line, sizeof(line), fp)) {
        if (strstr(line, termIp) != NULL)
            printf("%s", line);
        if (strstr(line2, termMask) != NULL)
            printf("%s", line2);
        if (strstr(line3, termDoor) != NULL)
            printf("%s", line3);
        if (strstr(line4, termDNS) != NULL)
            printf("%s", line4);
    }

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Cant print a file
    By Gainborought in forum C Programming
    Replies: 5
    Last Post: 02-07-2014, 11:45 PM
  2. Replies: 3
    Last Post: 02-01-2014, 06:50 PM
  3. Replies: 3
    Last Post: 03-13-2013, 07:10 PM
  4. Print to file
    By metaTron in forum C Programming
    Replies: 14
    Last Post: 01-19-2006, 04:10 PM
  5. how to print it to a file
    By xlordt in forum C Programming
    Replies: 4
    Last Post: 10-04-2002, 11:44 AM

Tags for this Thread