Like Tree1Likes
  • 1 Post By anduril462

fscanf and fprintf - white space problem :|

This is a discussion on fscanf and fprintf - white space problem :| within the C Programming forums, part of the General Programming Boards category; Good evening. Upon reading a bit ( a lot) more about pipes and forks, I wanted to adapt some code ...

  1. #1
    Registered User
    Join Date
    Apr 2012
    Location
    UK
    Posts
    7

    Question fscanf and fprintf - white space problem :|

    Good evening. Upon reading a bit ( a lot) more about pipes and forks, I wanted to adapt some code I was shown to allow a user input:

    The problem is that the white space seems to make the fscanf and fprintf functions act a bit like a bag of spiders (mad).

    What am I doing wrong? Here is an overview of the code;

    main function

    char userinput[50];


    // create a pipe
    // p[0] is read side of pipe
    // p[1] is write side of pipe

    fscanf for user input


    If
    // child - receives output from ftp
    // open a FILE * to the pipe
    // get output of FTP
    // print to console

    Else

    // parent : sends input to ftp
    // redirect standard out to write side of pipe
    // close unused side of pipe
    // open writeable file to ftp process

    // write something to ftp using fprintf

    return 0

    Code:
    #include <stdio.h>
    #include <string.h>
    #include <errno.h>
    #include <assert.h>
    #include <unistd.h>
    
    
    int main(int argc,char *argv[])
    {
        FILE *inp;
        FILE *pftp;
        int   p[2];
        int   status;
        int   fd;
        char  buf[1024];
        pid_t pid;
        char userinput[50];
        
        
        memset(buf,0,sizeof(buf));
        fscanf(stdin,"%S",userinput);
    
    
        // create a pipe
        // p[0] is read side of pipe
        // p[1] is write side of pipe
        status = pipe(p);
        if (status != 0) {
            perror("pipe");
            return 1;
        }
    
    
        pid = fork();
        if (pid == -1) {
            perror("fork");
            return 1;
        }
        else if (pid == 0) {
            // child - receives output from ftp
            
            // open a FILE * to the pipe
            inp = fdopen(p[0],"r");
                    if (inp == 0) {
                         perror("fdopen");
                          return 1;
                     }
            
            // get output of FTP
            fgets(buf,sizeof(buf),inp);
            
            // print it to console
            printf("***%s***\n",buf);
        }
        else {
            // parent : sends input to ftp
            
            // redirect standard out to write side of pipe
            fd = dup2(p[1],STDOUT_FILENO);
            if (fd == -1) {
                perror("dup2");
                return 1;
            }
            // close unused side of pipe
            close(p[0]);
            
            // open writeable file to ftp process
            pftp = popen("ftp","w");
            if (pftp == 0) {
                perror("popen");
                return 1;
            }
             
            // write something to ftp
            fprintf(pftp,"%S",userinput);
            
            
            
            
        
        }
    
    
        
        return 0;
    }

  2. #2
    Registered User
    Join Date
    Apr 2012
    Location
    UK
    Posts
    7
    Sorry, it compiles under gcc with no problems, but when run, the
    // write something to ftp fprintf(pftp,"%S",userinput);

    line returns only "o" when the fscanf was provided with "o 127.0.0.1" as user input.

  3. #3
    Registered User
    Join Date
    Nov 2010
    Location
    Long Beach, CA
    Posts
    5,309
    I'm not sure %S (upper case S) is a valid format specifier, but %s is. The thing about %s is that it stops at the first white space, so fscanf is working exactly as it should, just you misunderstood it. fgets is probably your best bet if you want to read up to the new line (make sure to strip it when you're done).

  4. #4
    Registered User
    Join Date
    Apr 2012
    Location
    UK
    Posts
    7
    Thank you for the help. Used fget() and it works great. I read something about %S being the same as %ls or something, but got rid of it and placed %s back and it works great!

    Code:
    #include <stdio.h>
    #include <string.h>
    #include <errno.h>
    #include <assert.h>
    #include <unistd.h>
     
     
    int main(int argc,char *argv[])
    {
        FILE *inp;
        FILE *pftp;
        int   p[2];
        int   status;
        int   fd;
        char  buf[1024];
        pid_t pid;
        char userinput[50];
         
         
        memset(buf,0,sizeof(buf));
        
    	fgets(userinput,50,stdin);
    	
    
    
     
     
        // create a pipe
        // p[0] is read side of pipe
        // p[1] is write side of pipe
        status = pipe(p);
        if (status != 0) {
            perror("pipe");
            return 1;
        }
    
    
     
        pid = fork();
        if (pid == -1) {
            perror("fork");
            return 1;
        }
        else if (pid == 0) {
            // child - receives output from ftp
             
            // open a FILE * to the pipe
            inp = fdopen(p[0],"r");
                    if (inp == 0) {
                         perror("fdopen");
                          return 1;
                     }
             
            // get output of FTP
            fgets(buf,sizeof(buf),inp);
             
            // print it to console
            printf("***%s***\n",buf);
        }
        else {
            // parent : sends input to ftp
             
            // redirect standard out to write side of pipe
            fd = dup2(p[1],STDOUT_FILENO);
            if (fd == -1) {
                perror("dup2");
                return 1;
            }
            // close unused side of pipe
            close(p[0]);
             
            // open writeable file to ftp process
            pftp = popen("ftp","w");
            if (pftp == 0) {
                perror("popen");
                return 1;
            }
              
            // write something to ftp
            fprintf(pftp,"%s",userinput);
             
             
             
             
         
        }
     
     
         
        return 0;
    }

  5. #5
    Registered User
    Join Date
    Nov 2010
    Location
    Long Beach, CA
    Posts
    5,309
    I checked in the standard and couldn't find it, so it's probably a compiler-specific extension. I would just stick with "%ls".

    I would also use sizeof in your fgets, similar to how you did on line 55: fgets(userinput, sizeof(userinput), stdin);

    Note, fgets appends the new line to the end of what it reads, so if the user typed foo, fgets puts "foo\n" in userinput. This is almost never what you want, you should probably get rid of it. An example can be found here: FAQ > Get a line of text from the user/keyboard (C) - Cprogramming.com.

  6. #6
    Registered User
    Join Date
    Apr 2012
    Location
    UK
    Posts
    7
    How do I stop the session from ending? It sends the commands and then closes FILE I think. Can I loop the whole thing somehow, to make essentially a "fully functional" client; using an I/O loop so more than one instruction can be given before the session dies?

  7. #7
    Registered User
    Join Date
    Nov 2010
    Location
    Long Beach, CA
    Posts
    5,309
    Yes, both your child and parent need loops if you wish to repeatedly send/receive data. Simply put the code you want to repeat (get a line from a user) in a loop, and don't close the pipe until the user is done (e.g. enters an empty string). Something like:
    Code:
    pipe()
    fork()
    if fork error
        ...
    else if child
        while fgets returns non-NULL
            print the line received
        close pipe
    else // parent
        do
            get line from user
            if input is not empty
                sending line to child
        while input is not empty
        close pipe
    Johnny_010 likes this.

  8. #8
    Registered User
    Join Date
    Apr 2012
    Location
    UK
    Posts
    7
    Thanks again. Getting the hang of this I think ha.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Strings and white space
    By ginom71 in forum C Programming
    Replies: 13
    Last Post: 07-12-2009, 09:48 AM
  2. how to skip white space?
    By kalamram in forum C Programming
    Replies: 9
    Last Post: 06-17-2006, 01:57 PM
  3. Remove white space problem
    By jeffdavis_99 in forum C++ Programming
    Replies: 8
    Last Post: 03-30-2005, 08:29 PM
  4. white space and fscanf
    By DMaxJ in forum C Programming
    Replies: 2
    Last Post: 06-10-2003, 09:18 AM

Tags for this Thread


1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21