Resolved Something Really Odd... (C)

Discussion in 'Mac Programming' started by mac2x, Sep 23, 2011.

  1. mac2x, Sep 23, 2011
    Last edited: Sep 24, 2011

    mac2x macrumors 65816

    Joined:
    Sep 19, 2009
    #1
    I'm writing a little command line program in C to do some DNS related stuff, and I've run into an odd problem while writing my function to get two IP addresses from the user. All the code I have so far below...

    I'm prompting the user to enter the first IP address

    Snippet:

    Code:
    fprintf( stdout, "Enter first IP: " );
    And reading the string into a char array with fgets():

    Snippet:

    Code:
    fgets( ip_One, IP_LENGTH, stdin );

    I do this twice, but the first fprintf() (above) does not run till execution reaches the SECOND fprintf(), leaving the output:

    Code:
    Enter the first IP:  Enter the second IP: 
    This behavior seems really bizarre as I can't find any obvious errors in my code, and other programs that use fprintf() to prompt and fgets() to read in strings display the same behavior.

    Here is all my code so far. Please note that this is only the code for I/O; I have not yet written the actual logic for what the program will do. Thanks for any help/advice/criticism. :) Also, this is NOT a school assignment.

    main.c:

    Code:
    /*
    ** This C program checks whether two IPs are from the same ISP
    **
    **
    **
    */
    
    #include <stdio.h>
    #include <stdlib.h>
    #include "IP_defs.h"
    
    const int IP_LENGTH = 46; //array size to accomodate IPv6 addresses including the null
    
    int main( int argc, char *argv[] )
    {
    	char ip_One[IP_LENGTH];
    	char ip_Two[IP_LENGTH];
    	
    	fprintf( stdout, "DNS Comparision Utility\n\n" );
    	fprintf( stdout, "Enter ^D to terminate\n" );
    	
    	getData( stdin, IP_LENGTH, ip_One, ip_Two );
    	return 0;
    
    }
    IP_defs.h:

    Code:
    //Here we declare all our functions
    
    #include <stdio.h>
    
    void getData( FILE * is, const int IP_LENGTH, char ip_One[], char ip_Two[] );
    IP_functions.c:

    Code:
    
    //Function defintions
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <ctype.h>
    #include "IP_defs.h"
    
    void getData( FILE * is, const int IP_LENGTH, char ip_One[], char ip_Two[] )
    {
    	int addrSpaceType = 0;
    	int usedOne = 0, usedTwo = 0;
    	
    	fprintf( stdout, "Enter 4 for IPv4, 6 for IPv6: " );
    	fscanf( stdin, "%i", &addrSpaceType );
    	
    	//get an IPv4 Address
    	if ( addrSpaceType == 4 )
    	{
    		//get first IP
    		fprintf( stdout, "Enter first IP: " );
    		fgets( ip_One, IP_LENGTH, stdin );
    		//printf("\nThe text entered is: %s\n\n", ip_One);
    		ip_One[strlen( ip_One ) - 1] = '\0'; //remove newline
    		usedOne = strlen( ip_One );
    		
    		//check for invalid input
    		for ( int i = 0; i <= usedOne ; i++ ) 
    		{
    			if ( isalpha( ip_One[i]) ) 
    				fprintf( stdout, "Invalid IP: letters not allowed");
    		}
    		
    		//get second IP
    		fprintf( stdout, "Enter second IP: ");
    		fgets( ip_Two, IP_LENGTH, stdin );
    		ip_One[strlen( ip_Two	) - 1] = '\0'; //remove newline
    		usedTwo = strlen( ip_Two );
    		
    		//check for invalid input
    		for ( int j = 0; j <= usedTwo; j++ )
    		{
    			if ( isalpha( ip_Two[j] ) )
    				fprintf( stdout, "Invalid IP: letters not allowed");
    		}
    	}
    	
    	
    }
     
  2. jiminaus macrumors 65816

    jiminaus

    Joined:
    Dec 16, 2010
    Location:
    Sydney
    #2
    Trying adding this just before fgets.
    Code:
    fflush(stdout);
    
     
  3. mac2x thread starter macrumors 65816

    Joined:
    Sep 19, 2009
  4. subsonix macrumors 68040

    Joined:
    Feb 2, 2008
    #4
    Your first scanf() most likely leads to the '\n' being stuck in the input buffer. You can not flush the input buffer, but you can do something similar yourself.

    Code:
    while( getchar() != '\n' );
    
     
  5. mac2x thread starter macrumors 65816

    Joined:
    Sep 19, 2009
    #5
    Thanks, subsonix! The problem was the prompt for IPv4 or IPv6; it was the one leaving a newline in. Your code snippet solved the problem when I put it after that.
     
  6. chown33 macrumors 604

    Joined:
    Aug 9, 2009
    #6
    Or change this:
    Code:
    	fscanf( stdin, [COLOR="Red"]"%i"[/COLOR], &addrSpaceType );
    
    to this:
    Code:
    	fscanf( stdin, [COLOR="red"]"%i "[/COLOR], &addrSpaceType );
    
    To see why it works, read the man page for fscanf, and look for the words white space. Because if you're going to be using the scanf functions regularly, you should know how they really work.
     

Share This Page