Thread: input redirected

  1. #1
    Registered User
    Join Date
    Sep 2010
    Posts
    15

    input redirected

    Hello, how can you tell if a program that expects the input to be redirected fails to do so? For example:
    Code:
    ./gauss < gauss1.txt
    is called like
    Code:
    ./gauss
    instead.

    The gist of my program is to read from some given files which are formatted like
    Code:
    3
    1 2 3 6
    4 5 6 15
    7 8 9 24
    Where the 3 is the number of rows, and the rest is intended to be put in a 2d array.

    I have been working with scanf() to read each number (as a double).
    My problem is that if there is no input redirection to a file my program will just hang waiting for input, and I need to instead display some sort of error message. I have tried looking at the number of arguments using
    Code:
    main(int argc, char **argv){...}
    but it does not store the redirection.

    Thanks for any suggestions

  2. #2
    Novice
    Join Date
    Jul 2009
    Posts
    568
    You don't need to "store the redirection". You need to call gauss with gauss1.txt as an argument, which will be stores as argv[1]. You then will use this argument to open and read the file.

  3. #3
    Registered User
    Join Date
    Sep 2010
    Posts
    15
    Thanks for the reply, but for the specifications of my program, I do need to use input redirection.
    It is for a class, and they do batch testing so I have to make sure it works according to the way they call the program.

  4. #4
    Novice
    Join Date
    Jul 2009
    Posts
    568
    In that case, program as if you were dealing with user input. If you're using scanf() and it "hangs" it means that you're most likely forgetting skip the \n at the end of each line.

  5. #5
    Registered User
    Join Date
    Sep 2010
    Posts
    15
    I'm doing just that. It hangs because it's as though the user called
    Code:
    ./gauss
    and then walked away from their computer.
    It is treated as though the program is intended to take actual input from a physical user, rather than a file.

  6. #6
    Novice
    Join Date
    Jul 2009
    Posts
    568
    You're doing it wrong, then. Show us the code.

  7. #7
    Registered User
    Join Date
    Sep 2010
    Posts
    15
    That was a rather harsh accusation.
    Code:
    #include <stdio.h>
    #include <stdlib.h>
    
    #define MAXROWS 100
    #define MAXCOLS 101
    
    void printMatrix(int rows, int columns, double matrix[][MAXCOLS]);
    
    /* Add helper functions and global variables here */
    
    int main()
    {
    	/* Add your implementation here */
    	int i = 0;
    	int rows;
    	int r,c;
    	
    	scanf("%d",&rows);				//get the first number (num. of rows)
    	double matrix[rows][rows+1];			//create 2d array based on value of rows
    	
    	//scanf("%lf",&matrix[0][0]);
    	double num = 0;
    	for (r = 0; r < rows; r++) {
    		for (c = 0; c < rows+1; c++) {
    			if((scanf("%lf",&num)) != EOF){		//scanf() until the end of file is reached
    				//printf("scanned: %lf\n",num);
    				matrix[r][c] = num;
    				printf("m[%d][%d] = %lf\n",r,c,matrix[r][c]);
    			}else{
    				printf("Element a[%d][%d] is missing\n",r,c);
    				exit(0);
    			}
    		}
    	}
    	//printf("%d, %d\n",r-1,c-1);
    	printf("\t\ttest: %lf\n",matrix[1][0]);
    	
    	printf("initial matrix\n");
    	printMatrix(rows,rows+1,matrix);
    	
    	return 0;
    }
    
    void printMatrix(int rows, int columns, double matrix[][MAXCOLS])
    {
    	/* Add your implementation here */
    	int j, k;
    	
    	printf("MATRIX: \n");
    	//printf("rows = %d\n",rows);
    	//printf("columns = %d\n",columns);
    	for (j = 0; j <= rows; j++) {
    		for (k = 0; k < columns; k++){
    			printf("m[%d][%d] : %lf\n",j,k,matrix[j][k]);
    		}
    	}
    }
    The section to focus is within the first imbedded for-loop.

    There may be some mistakes that I have not figured out yet because when I attempt to print the array with the printMatrix function it does not work properly, and as to why I honestly have no idea at all.

    Thanks in advance.

  8. #8
    Novice
    Join Date
    Jul 2009
    Posts
    568
    That was a rather harsh accusation.
    It's accurate, though. You're not skipping over newlines anywhere in that code.

    Here is my implementation, it lacks your error checking, but it works with the sample input you provided.
    Code:
    // Read data...
    for( i = 0; i < rows; ++i )
    {
        for( t = 0; t < ROW_LEN; ++t )
        {
            scanf( "%lf", &data[i][t] );
        }
        clean_buff( );
    }
    
    
    void clean_buff( void )
    {
        int ch;
        while( ( ch = getchar() ) != EOF && ch != '\n' );
    }
    You'll also need to skip the newline after you read the number of rows.
    Last edited by msh; 10-12-2010 at 02:03 AM. Reason: For completeness.

  9. #9
    Registered User
    Join Date
    Sep 2010
    Posts
    15
    I think you have a misconception of what the program is intended to do. If the program is called as such:
    Code:
    ./gauss
    rather than
    Code:
    ./gauss < gauss1.txt
    then it should not wait for any input, but instead return
    Code:
    Expected N (number of equations)
    and nothing further.

    After having implemented your code my program looks like
    Code:
    #include <stdio.h>
    #include <stdlib.h>
    
    #define MAXROWS 100
    #define MAXCOLS 101
    
    void printMatrix(int rows, int columns, double matrix[][MAXCOLS]);
    void clean_buff( void);
    
    /* Add helper functions and global variables here */
    
    int main()
    {
    	/* Add your implementation here */
    	int i = 0;
    	int rows;
    	int r,c;
    	
    	scanf("%d",&rows);
    	double matrix[rows][rows+1];
    	
    	//scanf("%lf",&matrix[0][0]);
    	double num = 0;
    	/*for (r = 0; r < rows; r++) {
    		for (c = 0; c < rows+1; c++) {
    			if((scanf("%lf",&num)) != EOF){
    				//printf("scanned: %lf\n",num);
    				matrix[r][c] = num;
    				printf("m[%d][%d] = %lf\n",r,c,matrix[r][c]);
    			}else{
    				printf("Element a[%d][%d] is missing\n",r,c);
    				exit(0);
    			}
    		}
    	}*/
    	for(r=0; r < rows; ++r){
    		for(c = 0; c < rows+1; ++c){
    			scanf("%lf",&matrix[r][c]);
    		}
    		clean_buff();
    	}
    	
    	
    	
    	//printf("%d, %d\n",r-1,c-1);
    	printf("\t\ttest: %lf\n",matrix[1][0]);
    	
    	printf("initial matrix\n");
    	printMatrix(rows,rows+1,matrix);
    	
    	return 0;
    }
    
    void clean_buff( void ){
    	int ch;
    	while (( ch = getchar() ) != EOF && ch != '\n');
    }
    
    void printMatrix(int rows, int columns, double matrix[][MAXCOLS])
    {
    	/* Add your implementation here */
    	int j, k;
    	
    	printf("MATRIX: \n");
    	//printf("rows = %d\n",rows);
    	//printf("columns = %d\n",columns);
    	for (j = 0; j <= rows; j++) {
    		for (k = 0; k < columns; k++){
    			printf("m[%d][%d] : %lf\n",j,k,matrix[j][k]);
    		}
    	}
    	
    }
    After typing
    Code:
    gcc test.c -o test1
    ./test1
    the program will sit and await user input.
    If I type any amount of characters and press return it says "Illegal Instruction" and terminates

  10. #10
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    Quote Originally Posted by AChrapko View Post
    I'm doing just that. It hangs because it's as though the user called
    Code:
    ./gauss
    and then walked away from their computer.
    It is treated as though the program is intended to take actual input from a physical user, rather than a file.
    Well there isn't a lot you can do about that, especially in a "standard C" student work scenario.

    There are a few ways out, but none of them are what you would call "easy 1-liners" that a new student would be expected to know.

    If your program spec says "redirected input from a file", them you just have to take them at their word.

    These are synonymous
    ./gauss (and you type in your input)
    ./gauss < file.txt
    cat file.txt | ./gauss

    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.

  11. #11
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    > It's accurate, though. You're not skipping over newlines anywhere in that code.
    Except %lf (and %d) SKIP white-space automatically, so it seems a moot point to me.

    > If I type any amount of characters and press return it says "Illegal Instruction" and terminates
    What exactly did you type?

    Use script to capture your terminal session of what you typed in, and what it printed in response.
    UNIX man pages : script ()
    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.

  12. #12
    Registered User
    Join Date
    Sep 2006
    Posts
    8,868
    I think this is what he's looking for:

    Compile this, and run it in a terminal window. It shows what you want.

    Code:
    /* compile this into an exe, first. then run it with some words after the name of the 
    program: ie:
    
    
    >argcargv hello world how are you <enter>
    
    Output similar to:
    
    Argc: 6
    
    1. argv hello
    2. argv world
    3. argv how
    4. argv are
    5. argv you
    */
    
    #include <stdio.h>
    
    int main(int argc, char *argv[]) {
      int i, n; 
      printf("\n\n");
      printf("Argc: %d \n\n", argc);
      i=0;
      while(*argv[i]) {
        printf("Argv %d: %s\n", i, argv[i]);
        ++i;
      }
      printf("\n\n\t\t\t     press enter when ready");
    
      i = getchar(); ++i;
      return 0;
    }

  13. #13
    Registered User
    Join Date
    Sep 2006
    Posts
    8,868
    What you want is an usage message for the user, telling them to redirect input to your program.

    That is not unusual, at all. Check the argc number. If that int is less than 2, then the user has NOT redirected any input to your program.

    print an error message, and terminate the program with return, right from the top of main.

  14. #14
    Registered User
    Join Date
    Sep 2010
    Posts
    15
    the specs do not directly say "redirected input from a file" however they are tested by machine and called with
    Code:
    ./gauss < file.txt
    and with my problem of not having any clue as to how to do the bulk of the program, I figured I would get at least the matrix to input properly and make sure the user input proper arguments. Though I don't think "arguments (flags,parameters whatever)" is the proper term for "< fileName.txt" redirecting the input. Anyways, the other problem I was having is if you refer to my first post of the full code, my array does not print off properly.

    the first printf()
    Code:
    printf("m[%d][%d] = %lf\n",r,c,matrix[r][c]);
    gets the correct number, and the loops control where it is placed. After the for-loops I even printed one of the problem elements, the first being "matrix[1][0]" and that worked properly, but when using the printMatrix() function my results look like
    Code:
    m[0][0] : 7.000000
    m[0][1] : 8.000000
    m[0][2] : 10.000000
    m[0][3] : 25.000000
    m[1][0] : 899156430874148739915381448845229089616319085089529831162663631101506972863985960828040243303953133619257521263629665420168260295724615073305771911999367898772537344.000000
    m[1][1] : 0.000000
    m[1][2] : 17676154007756128403861346874008211219880184843688977024706402509217698083584330072617614175375678388925763597874710561778820251748349828351438029372236052957308649472.000000
    m[1][3] : 0.000000
    m[2][0] : 0.000000
    m[2][1] : 0.000000
    m[2][2] : 0.000000
    m[2][3] : 0.000000
    m[3][0] : 0.000000
    m[3][1] : 0.000000
    m[3][2] : 258686043184358362686196289935145724172259836220883361143274666226839157675633155966362818606293835110643936222715950291052218218230256283650594491132653621739520.000000
    m[3][3] : 0.000000
    the file I input with looks like this:
    Code:
    3
    7 8 10 25
    1 2 3 6
    4 5 6 15

  15. #15
    Registered User
    Join Date
    Sep 2010
    Posts
    15
    Adak, that is exactly correct in that I want a Usage message, however I tried using argc and argv already, but when I printed the value of argc after calling the program
    Code:
    ./gauss < file.txt
    the value is still 1. It seems like the system does not consider "< ..." to be part of the arguments, I think because it is a platform specific operation(?) Like that is how you use a file for stdin on a Unix machine (what I'm working on) but not others? At least that's how I believed it to be

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Linked List from Standard Input
    By mercuryfrost in forum C Programming
    Replies: 14
    Last Post: 08-24-2009, 12:05 AM
  2. Input statement problem
    By une in forum C Programming
    Replies: 3
    Last Post: 05-29-2007, 11:16 PM
  3. For loop problems, input please.
    By xIcyx in forum C Programming
    Replies: 2
    Last Post: 04-22-2007, 03:54 AM
  4. I would love some input on my BST tree.
    By StevenGarcia in forum C++ Programming
    Replies: 4
    Last Post: 01-15-2007, 01:22 AM
  5. Simple Console Input for Beginners
    By jlou in forum C++ Programming
    Replies: 0
    Last Post: 06-21-2005, 01:50 PM