Thread: Scanf ruining my problem!

  1. #1
    Registered User
    Join Date
    Oct 2007
    Location
    Glasvegas, Scotland.
    Posts
    68

    Scanf ruining my problem!

    Hello again experts!

    I have another problem with a program i'm learning. You guys are gonna get sick of me soon!
    But since theres no one else who knows c.. here goes:

    I'm teaching myself c by giving myself a problem and trying to solve it.
    Basically i'm trying to code a sudoku solver.

    My program so far takes a 9x9 matrix, goes through each element and if its non zero, removes it from a row array, a column array and a set array. Thus leaving a set of possible values for that square.

    Anyhow, my program is working so far to a point. my problem is reading in the matrix. I'm trying to use scanf. But its not working.

    I wanted to use scanf untill i figured out how to make my program read from a file. (Don't know how to do that yet!!)

    So my program is as follows:

    Code:
    #include <stdio.h>
    
    int main()
    {
    
    int originalarray[9][9]; // 9x9 matrix, note that the elements are numbered from 0 and that (9,9) isn't used.
    int x, y, a, i, c;
    int row[9][9], col[9][9];
    
    
    for (x = 0; x <= 8; x++) // Goes through rows
    {
    	for (y = 0; y <= 8; y++) //Goes through columns
    	//scanf( "%d", &c ); // reads character input
    	originalarray[x][y] = y; // makes the integer value of the matrix equal to the character input
    }
    
    for (x = 0; x <= 8; x++) // Goes through rows
    {
    	for (y = 0; y <= 8; y++) //Goes through columns
    	row[x][y] = y + 1; // makes the integer value of the matrix equal to the column number + 1
    }
    
    for (x = 0; x <= 8; x++) // Goes through rows
    {
    	for (y = 0; y <= 8; y++) //Goes through columns
    	col[x][y] = x + 1; // makes the integer value of the matrix equal to the row number + 1
    }
    
    
    for (x = 0; x <= 8; x = x++) //Goes through rows
    {
    	printf("\n"); //print newline
    		for (y = 0; y <= 8; y = y++) //Goes through columns
    		printf("%d", originalarray[x][y]); // prints each value of the original matrix in turn
    }
    
    
    printf("\n");
    
    for (x = 0; x <= 8; x++) //Goes through rows
    {
    	for (y = 0; y <= 8; y++) //Goes through rows
    	{
    		if(originalarray[x][y] != 0) // if the instant value of the original matrix is not 0, continue
    		{
    		a = originalarray[x][y]; //a takes on the insantaneous value of the original matrix
    		row[x][a - 1] = 0; // removes that value from the corresponding row table
    		col[y][a - 1] = 0; // removes that value from corresponding column table
    		}
    	}
    }
    
    printf("\n");
    
    for (x = 0; x <= 8; x = x++) //Goes through rows
    {
    	printf("\n"); //print newline
    		for (y = 0; y <= 8; y = y++) //Goes through columns
    		printf("%d", row[x][y]); // prints each value of the row matrix in turn
    }
    
    printf("\n");
    for (x = 0; x <= 8; x = x++) //Goes through rows
    {
    	printf("\n"); //print newline
    		for (y = 0; y <= 8; y = y++) //Goes through columns
    		printf("%d", col[x][y]); // prints each value of the column matrix in turn
    }
    printf("\n");
    
    }

    Note that in the first for loop, scanf is commented out and the matrix is just set to take the value of the column.

    i.e the matrix will look like this:
    Code:
    012345678
    012345678
    012345678
    012345678
    012345678
    012345678
    012345678
    012345678
    012345678
    the output i'm getting is fine for that matrix:
    Code:
    012345678
    012345678
    012345678
    012345678
    012345678
    012345678
    012345678
    012345678
    012345678
     
     
    000000009
    000000009
    000000009
    000000009
    000000009
    000000009
    000000009
    000000009
    000000009
     
    111111111
    022222222
    303333333
    440444444
    555055555
    666606666
    777770777
    888888088
    999999909
    but when i uncomment scanf and try to input my own matrix - tedious value by value it doesn't work and i get this:

    Code:
    0
    2
    0
    5
    0
    0
    6
    4
    0
    7
    0
    0
    0
    0
    0
    5
    0
    0
    0
    3
    0
    2
    0
    8
    0
    0
    7
    4
    0
    0
    0
    0
    7
    2
    9
    0
    2
    8
    0
    0
    0
    0
    0
    6
    3
    0
    7
    3
    9
    0
    0
    0
    0
    4
    6
    0
    0
    8
    0
    1
    0
    7
    0
    0
    0
    5
    0
    0
    0
    0
    0
    6
    0
    9
    7
    0
    0
    2
    0
    8
    0
     
    000007750287368253722127749105091836272709
    000000000
    000587202560129729336117002087201967202404942743655976237088
    71145380912808591444129248591187996134513180013451310932
    0116710011315641073831960410738326681297333612974256134513147
    31292064613451314724641422134513044-10737580761297417621073832720
    4118687709151090-1073758076000
    024641422-10737579521297384000116346810738319600
    6134519116-107375804013451328900-10737580081345145901292227
    Segmentation fault (core dumped)
    the big long line of numbers is me trying to input the matrix value by value.
    it should look like this:

    Code:
    020500640
    700000500
    030208007
    400007290
    280000063
    073900004
    600801070
    005000006
    097002080

    I would really appreciate if someone could have a brief look at this. I know you must enjoy the challenge!!

    I don't want to be told how to solve the problem, just whats wrong with my code.
    Although, suggestions on how to read the matrix in from a file would be cool.

    Thank you in advance.
    Simon.

  2. #2
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    I'll try to help you help yourself instead of doing the job for you.

    Add the red code after this line:
    Code:
    		a = originalarray[x][y]; //a takes on the insantaneous value of the original matrix
    
                     if (a < 0 || a > 8) {
                       printf("Huh? x = %d, y = %d, a = %d", x, y, a);
                       continue;
                     }
    
    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  3. #3
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    > for (x = 0; x <= 8; x = x++)
    This is undefined.
    x++ is sufficient.

    Also, saying < 9 is more usual than saying <= 8, if you consider that arrays should be declared with a constant size and not a magic number.

    Eg.
    Code:
    #define SUDOKU_SIZE 9
    
    int game[SUDOKU_SIZE][SUDOKU_SIZE];
    
    for ( i = 0 ; i < SUDOKU_SIZE ; i++ )
    Also, write some functions, say
    Code:
    void initBoard ( int board[SUDOKU_SIZE][SUDOKU_SIZE] ) {
      int i, j;
      for ( i = 0 ; i < SUDOKU_SIZE ; i++ ) {
        for ( j = 0 ; j < SUDOKU_SIZE ; j++ ) {
          board[i][j] = 0;
        }
      }
    }
    Which you would call with
    Code:
    initBoard( game );
    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.

  4. #4
    Registered User
    Join Date
    Oct 2007
    Location
    Glasvegas, Scotland.
    Posts
    68
    So the variable 'a' is going out of bounds? I can't find why it would be doing that.

    if i comment out that entire part of code i still get the same output.

    Its only when i'm using scanf. Although i had it working earlier.

    Basically if i have :

    Code:
    for (x = 0; x <= 8; x++) // Goes through rows
    {
    	for (y = 0; y <= 8; y++) //Goes through columns
    	scanf( "%d", &c ); // reads character input
    	originalarray[x][y] = c; // makes the integer value of the matrix equal to the character input
    }
    instead of:

    Code:
    for (x = 0; x <= 8; x++) // Goes through rows
    {
    	for (y = 0; y <= 8; y++) //Goes through columns
    	originalarray[x][y] = y; // makes the integer value of the matrix equal to the character input
    }

    It gives me the wrong output. Even with the lower section commented out.

  5. #5
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Well, a is out of range because the "originalarray[x][y]" is out of range, so you have to check that to see what's happening.

    Good excercise for learnign bug-finding/fixing.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  6. #6
    Registered User
    Join Date
    Oct 2007
    Location
    Glasvegas, Scotland.
    Posts
    68
    Code:
    #include <stdio.h>
    
    int main()
    {
    
    int originalarray[9][9]; // 9x9 matrix, note that the elements are numbered from 0 and that (9,9) isn't used.
    int x, y, c;
    
    
    
    for (x = 0; x <= 8; x++) // Goes through rows
    {
    	for (y = 0; y <= 8; y++) //Goes through columns
    	\\scanf( "%d", &c ); // reads character input
    	originalarray[x][y] = y; // makes the integer value of the matrix equal to the character input
    }
    
    for (x = 0; x <= 8; x++) //Goes through rows
    {
    	printf("\n"); //print newline
    		for (y = 0; y <= 8; y++) //Goes through columns
    		printf("%d", originalarray[x][y]); // prints each value of the original matrix in turn
    }
    
    }
    gives me:

    Code:
    012345678
    012345678
    012345678
    012345678
    012345678
    012345678
    012345678
    012345678
    012345678
    whereas this:
    Code:
    #include <stdio.h>
    
    int main()
    {
    
    int originalarray[9][9]; // 9x9 matrix, note that the elements are numbered from 0 and that (9,9) isn't used.
    int x, y, c;
    
    
    
    for (x = 0; x <= 8; x++) // Goes through rows
    {
    	for (y = 0; y <= 8; y++) //Goes through columns
    	scanf( "%d", &c ); // reads character input
    	originalarray[x][y] = c; // makes the integer value of the matrix equal to the character input
    }
    
    for (x = 0; x <= 8; x++) //Goes through rows
    {
    	printf("\n"); //print newline
    		for (y = 0; y <= 8; y++) //Goes through columns
    		printf("%d", originalarray[x][y]); // prints each value of the original matrix in turn
    }
    
    }
    gives me:
    Code:
    000007750287368253722127749105091836272709
    100000000
    100587202560129729336117002087201967202404942743655976237088
    111453809128085914441390380315532188134513180013451310932
    115511292154757561073741848410737425561395228013953200134513147
    11389959013451314724641422134513044-10737608761395312021073742608
    1118687709151090-1073760876000
    124641422-107376075213952784001550766010737418480
    1134518340-107376084013451328900-107376080813451381415636419
    Only difference is scanf commented out and variable changed from c to y so the matrix takes the value of its columns.

    I'm really sorry if its something really obvious but i can't see it.
    Thanks for your help.

  7. #7
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Add a piece of code to check the input (c) from scanf, to see that this is correct. If it's not "correct" try again. I don't see anything wrong.

    Cutting your code down to be smaller does indeed help to solve the problem.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  8. #8
    Registered User
    Join Date
    Oct 2007
    Location
    Glasvegas, Scotland.
    Posts
    68
    haha, braces!!!! Damn!

    Code:
    for (x = 0; x <= 8; x++) // Goes through rows
    {
    	for (y = 0; y <= 8; y++) //Goes through columns
    	{ // *************** braces!!
    	scanf( "%d", &c ); // reads character input
    	originalarray[x][y] = c; // makes the integer value of the matrix equal to the character input
    	printf("The value of c is %d", originalarray[x][y]);
    	} // *************** braces!!!
    }
    works now!! Thanks guys!!

  9. #9
    Registered User
    Join Date
    Oct 2007
    Location
    Glasvegas, Scotland.
    Posts
    68
    I guess it just shows all the newbie errors!!

    Thanks Salem for the x = x++, didn't notice that either, and some good ideas!

    Matsp, I think i'll put a line in to put out an error message if any of the values get out of bounds. Thanks for the tip!

    Just need to figure out how to read in from a file now. Any ideas?

    would fgets() work? How do i use that?

    Si.

  10. #10
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    fgets() + sscanf() or fscanf() will both work. fscanf() is ok as long as you have a program generating the file in the first place [all variants of scanf are bad for "user generated data" because it's simple to "fool" *scanf into doing something other than you expect, e.g. input 1a somewhere in your 81 integer stream of data, and it's going to fill the rest with "garbage" [0 or repeats of what you last input] because it never "uses" the 'a' that is in the input buffer].

    For program generated data, scanf() is fine [as long as you trust the program generating the data, that is].

    Doh! I missed the missing braces. This is where an editor that auto-indents is a very good tool.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  11. #11
    Registered User
    Join Date
    Oct 2007
    Location
    Glasvegas, Scotland.
    Posts
    68
    So would it be possible to output the stream of integers to a file such that i can call it back in?

    or a file where i could type in the 81 integers and call it?
    I'll be honest i don't even know where to begin on this one.

    Also what editors are good, and whats auto indentation?
    I'm using kate at work i never could get to grips with vi or emacs!

    Thanks.

  12. #12
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Well, I'm an Emacs fan, but that's probably because I used AMIS/TinyAMIS on PDP-11 about two centuries ago.

    Auto-indentation is where the editor KNOWS that you are writing C, and knows where the line of code starts. Emacs does this very well [there are several different "styles" of C formatting to choose from].

    Many other editors support this. vim does [but I can NEVER get my head around editing in "vi" - probably because I'm used to Emacs - once you know one of them, the other is so hideously different that it's not easy to get along with it].

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  13. #13
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Quote Originally Posted by AmbliKai View Post
    So would it be possible to output the stream of integers to a file such that i can call it back in?

    or a file where i could type in the 81 integers and call it?
    I'll be honest i don't even know where to begin on this one.
    Yes, certainly.

    You need to read up on "file handling in C" [there should be a tutorial somewhere on this site that covers the basics].

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  14. #14
    Registered User
    Join Date
    Oct 2007
    Location
    Glasvegas, Scotland.
    Posts
    68
    Trying to learn some basic file handling, as usual us Scottish come to the rescue

    Found a good tutorial and trying to write up a basic program which displays the basic properties of each component.

    So it has

    fopen, fclose,
    putc, getc
    fprintf
    fscanf
    and hopefully
    sscanf
    sprintf and so on

    My problem is that all the input ones work great.
    so putc and fprintf are fine but i can't get the input ones to work.

    Code:
    #include <stdio.h>
    
    int main()
    {
    printf("\nfile I/O\n");
    
    char c;
    int i;
    FILE *output_file;
    FILE *input_file;
    FILE *formatted_file;
    FILE *formatted_input_file;
    // opens an output file and takes a character from the keyboard
    // and inserts it into the file before closing it
    if ((output_file = fopen("output_file", "w")) == NULL)
               fprintf(stderr, "Cannot open %s\n", "output_file");
    
    c = getchar();
    putc(c, output_file);
    fclose(output_file);
    
    if ((input_file = fopen("input_file", "w")) == NULL)
               fprintf(stderr, "Cannot open %s\n", "input_file");
    
    c = getc(input_file);
    printf("%c", c);
    fclose(input_file);
    
    if ((formatted_file = fopen("formatted_file", "w")) == NULL)
               fprintf(stderr, "Cannot open %s\n", "formatted_file");
    
    fprintf(formatted_file, "Some formatted text into a file");
    
    fclose(formatted_file);
    
    
    if ((formatted_input_file = fopen("formatted_input_file", "w")) == NULL)
               fprintf(stderr, "Cannot open %s\n", "formatted_input_file");
    
    for (i = 0; i < 9; i++)
    {
    fscanf(formatted_input_file, "%c", &c);
    printf("%c", c);
    }
    
    fclose(formatted_file);
    }
    I'm probably doing something pretty simple all wrong!

    My input files are

    input file is a single character and the formatted_input_file is just 123456789

    Any help would be appreciated.
    Si.

  15. #15
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    A bit too much copy'n'paste, perhaps?
    Code:
    if ((input_file = fopen("input_file", "w")) == NULL)
    if ((formatted_input_file = fopen("formatted_input_file", "w")) == NULL)
    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Problem with RPC and scanf
    By Ricardo_R5 in forum C Programming
    Replies: 11
    Last Post: 01-08-2007, 06:15 PM
  2. Problem with scanf float..
    By aydin1 in forum C Programming
    Replies: 6
    Last Post: 03-06-2005, 01:35 PM
  3. scanf problem
    By gsoft in forum C Programming
    Replies: 3
    Last Post: 01-05-2005, 12:42 AM
  4. problem with looping scanf
    By crag2804 in forum C Programming
    Replies: 6
    Last Post: 09-12-2002, 08:10 PM
  5. scanf problem
    By Flikm in forum C Programming
    Replies: 2
    Last Post: 11-05-2001, 01:48 PM