Thread: Recursion

  1. #1
    Registered User
    Join Date
    Apr 2007
    Posts
    12

    Recursion

    Hello,
    I encountered a problem with my code. Its doesn't print correctly. Here my output

    [img]
    http://img413.imageshack.us/img413/8392/outputgsv1.jpg
    [/img]

    and here's my code

    Code:
    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    
    #define XMAX 65
    #define YMAX 32
    
    char screen[XMAX][YMAX];
    
    void printScreen(void);
    void fill(int, int, char*, int);
    
    int main(int argc, char *argv[])
    { FILE *in;
      int x, y;
      char* a;
      int ArraySize;
    
      if (argc!= 5)
      { fprintf(stderr,"Usage:\n\t%s <65x32 text file> <x> <y> <sentences>\n",argv[0]);
        exit(1);
      }
    
      in = fopen(argv[1],"r");
      if (in == NULL)
      { perror("opening input file");
        exit(1);
      }
    
      for (y=0; y<YMAX; y++)
      { for (x=0; x<XMAX; x++)
          screen[x][y] = fgetc(in);
      }
      if (fclose(in))
      { perror("closing input file");
        exit(1);
      }
    
    
      x = atoi(argv[2]);
      y = atoi(argv[3]);
      a = argv[4];
    
      ArraySize = strlen(a);
      while (a[ArraySize] ^ 0) 
    	  ArraySize++;
      fill(x,y,a, ArraySize);
      printScreen();
    }
    
    void printScreen (void)
    { int x,y;
      
      for (y=0; y<YMAX; y++)
          for (x=0; x<XMAX; x++)
              if(screen[x][y]!= EOF)
                  putchar(screen[x][y]);
    		   else		
                  puts("\n");         
    }
    
    void fill(int x, int y, char* a, int i)
    {
      if (screen[x][y] != ' ')
        return;
    
      screen[x][y] = *a;
      
      fill(x+1,y,a++,i);
      if(*a == 0)
     	  a-=i;
      fill(x,y-1,a,i);
      fill(x-1,y,a,i);
      fill(x,y+1,a,i);
    Suppose if I choose ABC as my sentences it should print ABC repetedly but mine got the output kind of mixed up. May I know where's my problem in my code? Ok. Thanks

  2. #2
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,661
    > screen[x][y] = fgetc(in);
    This doesn't take into account newlines (or does it?)

    > if(screen[x][y]!= EOF)
    Surely you mean a newline?
    Why would you be storing EOFs?

    > while (a[ArraySize] ^ 0)
    Excusive or'ing with 0 doesn't do anything.

    > fill(x+1,y,a++,i);
    Beware of calling functions with side effects on parameters.
    This is
    fill(x+1,y,a,i);a++;
    NOT
    fill(x+1,y,a+1,i);

    Also, your fill function should REALLY check the bounds before doing anything else.
    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
    Apr 2007
    Posts
    12
    screen[x][y] = fgetc(in);
    This doesn't take into account newlines (or does it?)

    > if(screen[x][y]!= EOF)
    Surely you mean a newline?
    Why would you be storing EOFs?
    I don't really understand your questions. Can u explain more. The first function above i use to get the data from another .txt file which store the "IX". For EOF sorry i forgot to delete it

    > while (a[ArraySize] ^ 0)
    Excusive or'ing with 0 doesn't do anything.
    This one my friend tell me to put it but I also don't understand why it must be there.

    > fill(x+1,y,a++,i);
    Beware of calling functions with side effects on parameters.
    This is
    fill(x+1,y,a,i);a++;
    NOT
    fill(x+1,y,a+1,i);
    Thanks for reminding me about this. I lmost forgot about this thing.

    Also, your fill function should REALLY check the bounds before doing anything else.
    Can U please explain to me more about the boundary.

    I only want to print string that we choose which is auto assign to argv[4] in my code. if i use argv[4][0] then it only print the first character of the string in argv[4]. But i want the program to print the whole string in the data files.

  4. #4
    Frequently Quite Prolix dwks's Avatar
    Join Date
    Apr 2005
    Location
    Canada
    Posts
    8,057
    > screen[x][y] = fgetc(in);
    This doesn't take into account newlines (or does it?)
    Because of the way you read the data in from the file, with a board that looks like this:
    Code:
    1 2 3
    4 5 6
    7 8 9
    You'd have to store it in the file like this:
    Code:
    123456789
    If you don't have that, you have a problem.

    As for your boundaries:
    Code:
    void fill(int x, int y, char* a, int i)
    {
      if (screen[x][y] != ' ')
        return;
    
      screen[x][y] = *a;
      
      fill(x+1,y,a++,i);
      if(*a == 0)
     	  a-=i;
      fill(x,y-1,a,i);
      fill(x-1,y,a,i);
      fill(x,y+1,a,i);
    What if x is the maximum number? You add one and call the same function again. So the first thing you need to do is
    Code:
    if(x > max) return;
    I only want to print string that we choose which is auto assign to argv[4] in my code. if i use argv[4][0] then it only print the first character of the string in argv[4]. But i want the program to print the whole string in the data files.
    You mean, something like this?
    Code:
    printf("&#37;s\n", argv[4]);
    /* or */
    puts(argv[4]);
    dwk

    Seek and ye shall find. quaere et invenies.

    "Simplicity does not precede complexity, but follows it." -- Alan Perlis
    "Testing can only prove the presence of bugs, not their absence." -- Edsger Dijkstra
    "The only real mistake is the one from which we learn nothing." -- John Powell


    Other boards: DaniWeb, TPS
    Unofficial Wiki FAQ: cpwiki.sf.net

    My website: http://dwks.theprogrammingsite.com/
    Projects: codeform, xuni, atlantis, nort, etc.

  5. #5
    Registered User
    Join Date
    Apr 2007
    Posts
    12
    You mean, something like this?
    Code:
    printf("%s\n", argv[4]);
    /* or */
    puts(argv[4]);
    Ya something like that but this time screen[x][y] works as printf.

    the data file contains this

    Code:
    This is only example. The treal size suppose to be 65 x 32
    
    XXXXXXXXXXXXXXXXXXXX
    X                                    X
    X   XXXXXX    XXXXXXX   X
    X   X        X    X          X   X
    X   X        X    X          X   X
    X   Xxxxxxx   XXXXXXX   X
    X                                    X
    X                                    X
    XXXXXXXXXXXXXXXXXXXX
    so when running the program we have to type

    Code:
    t8 t8data.txt <coordinate of x> <coordinate of y> <sentences to fill up any space according to x-y coordinate >
    that's mean argv[4] = to the sentences because we use function argument. The problem is I can't make the program to print the whole string. If a character then it would be easy just assign char a=argv[4][0]; Then manipulate a little bit in fill function it would work. But for a string It's kinda tricky. That's my problem right now.

  6. #6
    Frequently Quite Prolix dwks's Avatar
    Join Date
    Apr 2005
    Location
    Canada
    Posts
    8,057
    Well then, with that data file, you need to chomp -- err, remove -- the newlines from each line.

    [edit] Like this:
    Code:
      for (y=0; y<YMAX; y++)
      { for (x=0; x<XMAX; x++)
          screen[x][y] = fgetc(in);
    
        fgetc(in);  /* skip over newline */
      }
    Of course, that is completely deviod of error checking. [/edit]

    The problem is I can't make the program to print the whole string. If a character then it would be easy just assign char a=argv[4][0]; Then manipulate a little bit in fill function it would work. But for a string It's kinda tricky. That's my problem right now.
    You use strcpy() for strings. Is that your question?
    Code:
    char buffer[somesize];
    strcpy(buffer, argv[4]);
    But, wait. You could actually just pass argv[4] directly to fill().
    dwk

    Seek and ye shall find. quaere et invenies.

    "Simplicity does not precede complexity, but follows it." -- Alan Perlis
    "Testing can only prove the presence of bugs, not their absence." -- Edsger Dijkstra
    "The only real mistake is the one from which we learn nothing." -- John Powell


    Other boards: DaniWeb, TPS
    Unofficial Wiki FAQ: cpwiki.sf.net

    My website: http://dwks.theprogrammingsite.com/
    Projects: codeform, xuni, atlantis, nort, etc.

  7. #7
    Registered User
    Join Date
    Apr 2007
    Posts
    12
    Well then, with that data file, you need to chomp -- err, remove -- the newlines from each line.

    [edit] Like this:
    Code:
      for (y=0; y<YMAX; y++)
      { for (x=0; x<XMAX; x++)
          screen[x][y] = fgetc(in);
    
        fgetc(in);  /* skip over newline */
      }
    Of course, that is completely deviod of error checking. [/edit]
    But my lecturer said another extra fgetc(in) only need in UNIX to skip over newline

    You use strcpy() for strings. Is that your question?
    Code:
    char buffer[somesize];
    strcpy(buffer, argv[4]);
    But, wait. You could actually just pass argv[4] directly to fill()
    Ya, my question is suppose to be like that. but can we directly pass the strcpy to function fill? And when you said I could actually pass argv[4] directly to fill, May I know how?

  8. #8
    Frequently Quite Prolix dwks's Avatar
    Join Date
    Apr 2005
    Location
    Canada
    Posts
    8,057
    But my lecturer said another extra fgetc(in) only need in UNIX to skip over newline
    Well, your lecturer is wrong. A newline is a character. You need to skip it. It doesn't get skipped for you.

    But maybe you just misinterpreted what your lecturer said. There is a difference between newlines under DOS and under Linux and under Macs. However, you don't need to worry about it if you open your file in text mode, which you do. (Actually, you do need to worry about line endings othat don't belong on the system, like DOS files under Linux. But let's just assume here that the line endings will be correct for your platform.)

    Ya, my question is suppose to be like that. but can we directly pass the strcpy to function fill? And when you said I could actually pass argv[4] directly to fill, May I know how?
    Umm . . . it's just like you'd expect.
    Code:
    fill(x,y, argv[4], ArraySize);
    dwk

    Seek and ye shall find. quaere et invenies.

    "Simplicity does not precede complexity, but follows it." -- Alan Perlis
    "Testing can only prove the presence of bugs, not their absence." -- Edsger Dijkstra
    "The only real mistake is the one from which we learn nothing." -- John Powell


    Other boards: DaniWeb, TPS
    Unofficial Wiki FAQ: cpwiki.sf.net

    My website: http://dwks.theprogrammingsite.com/
    Projects: codeform, xuni, atlantis, nort, etc.

  9. #9
    Registered User
    Join Date
    Apr 2007
    Posts
    12
    Well, your lecturer is wrong. A newline is a character. You need to skip it. It doesn't get skipped for you.

    But maybe you just misinterpreted what your lecturer said. There is a difference between newlines under DOS and under Linux and under Macs. However, you don't need to worry about it if you open your file in text mode, which you do. (Actually, you do need to worry about line endings othat don't belong on the system, like DOS files under Linux. But let's just assume here that the line endings will be correct for your platform.)
    OIC. Maybe u r right

    Umm . . . it's just like you'd expect.
    Code:
    fill(x,y, argv[4], ArraySize);
    I got error when compiling with this format.

    if we use this format as a function call than in the header of function definition will be like this right

    Code:
    void fill(int x, int y, char a, int i)

  10. #10
    Frequently Quite Prolix dwks's Avatar
    Join Date
    Apr 2005
    Location
    Canada
    Posts
    8,057
    Well, you would get an error if you pass a string to a function that expects a char. Make both of them strings or both of them chars.

    What do you want fill to do with its argument (a)? Do you want to fill everything with one character? If so, then pass one character with argv[4][0] and declare the function to take char a. If you want to somehow deal with all of the characters in argv[4] then pass argv[4] and make the function take char*a as its parameter.
    dwk

    Seek and ye shall find. quaere et invenies.

    "Simplicity does not precede complexity, but follows it." -- Alan Perlis
    "Testing can only prove the presence of bugs, not their absence." -- Edsger Dijkstra
    "The only real mistake is the one from which we learn nothing." -- John Powell


    Other boards: DaniWeb, TPS
    Unofficial Wiki FAQ: cpwiki.sf.net

    My website: http://dwks.theprogrammingsite.com/
    Projects: codeform, xuni, atlantis, nort, etc.

  11. #11
    Registered User
    Join Date
    Apr 2007
    Posts
    12
    Quote Originally Posted by dwks View Post
    Well, you would get an error if you pass a string to a function that expects a char. Make both of them strings or both of them chars.

    What do you want fill to do with its argument (a)? Do you want to fill everything with one character? If so, then pass one character with argv[4][0] and declare the function to take char a. If you want to somehow deal with all of the characters in argv[4] then pass argv[4] and make the function take char*a as its parameter.
    I want to pass all the character

    Here's my new code
    Code:
    ArraySize = strlen(a);
      while (a[ArraySize] ^ 0) 
    	  ArraySize++;
      fill(x,y,*argv[4], ArraySize);
      printScreen();
    
    void fill(int x, int y, char a, int i)
    {
      if (screen[x][y] != ' ')
        return;
      else 
        screen[x][y] = a;
      
      a++;
      if(a == '\0')
         a-=i;
      fill(x+1,y,a,i);
      fill(x-1,y,a,i);
      fill(x,y-1,a,i);
      fill(x,y+1,a,i);
      
    }
    But it's kinda weird and not working properly.

  12. #12
    Frequently Quite Prolix dwks's Avatar
    Join Date
    Apr 2005
    Location
    Canada
    Posts
    8,057
    Code:
    while (a[ArraySize] ^ 0)
    You realize that that code is the same as
    Code:
    while (a[ArraySize])
    right? (I think, anyway.)

    Actually, that loop is always executed once because ArraySize is set to strlen(a).

    But it's kinda weird and not working properly.
    Not compiling properly or not running properly? If it compiles, it won't run properly, because you still don't have boundary checking in fill().

    [edit]
    I want to pass all the character
    Right now you're passing one character. To iterate through each character is going to take more code. [/edit]
    dwk

    Seek and ye shall find. quaere et invenies.

    "Simplicity does not precede complexity, but follows it." -- Alan Perlis
    "Testing can only prove the presence of bugs, not their absence." -- Edsger Dijkstra
    "The only real mistake is the one from which we learn nothing." -- John Powell


    Other boards: DaniWeb, TPS
    Unofficial Wiki FAQ: cpwiki.sf.net

    My website: http://dwks.theprogrammingsite.com/
    Projects: codeform, xuni, atlantis, nort, etc.

  13. #13
    Registered User
    Join Date
    Apr 2007
    Posts
    12
    Quote Originally Posted by dwks View Post
    Code:
    while (a[ArraySize] ^ 0)
    You realize that that code is the same as
    Code:
    while (a[ArraySize])
    right? (I think, anyway.)

    Actually, that loop is always executed once because ArraySize is set to strlen(a).


    Not compiling properly or not running properly? If it compiles, it won't run properly, because you still don't have boundary checking in fill().

    [edit]
    Right now you're passing one character. To iterate through each character is going to take more code. [/edit]

    Ok. Now I've changed like you said.Here's my code. But can u please tell me the code that i should add to iterate each character

    Code:
     x = atoi(argv[2]);
      y = atoi(argv[3]);
      a = argv[4]
    
      ArraySize = strlen(a));
      while (a[ArraySize] != 0) 
    	  ArraySize++;
      fill(x,y,a, ArraySize);
      printScreen();
    
    void fill(int x, int y, char *a, int i)
    {
      if ((screen[x][y] != ' ')|| (x > 65))
        return;
       
      screen[x][y] = *a;
      
      a++;
      if(*a == '\0')
     	  a-=i;
      fill(x+1,y,a,i);
      fill(x-1,y,a,i);
      fill(x,y-1,a,i);
      fill(x,y+1,a,i);
      
        
    }

  14. #14
    Frequently Quite Prolix dwks's Avatar
    Join Date
    Apr 2005
    Location
    Canada
    Posts
    8,057
    You need to check to see if x<0, y<0, and y>max too. And if an array has N elements, you want to check for x>=max, because C arrays are zero-based.
    But can u please tell me the code that i should add to iterate each character
    It's a little complicated. I guess that you want to increment the character you use when you travel right and decrement the character you use when you travel right, but use the same one if you go up or down. Assuming I'm right, you need an index of sorts to keep track of which character you are using, and wrap it as required. (If it gets below zero, add strlen(a), and vise versa.)
    dwk

    Seek and ye shall find. quaere et invenies.

    "Simplicity does not precede complexity, but follows it." -- Alan Perlis
    "Testing can only prove the presence of bugs, not their absence." -- Edsger Dijkstra
    "The only real mistake is the one from which we learn nothing." -- John Powell


    Other boards: DaniWeb, TPS
    Unofficial Wiki FAQ: cpwiki.sf.net

    My website: http://dwks.theprogrammingsite.com/
    Projects: codeform, xuni, atlantis, nort, etc.

  15. #15
    Registered User
    Join Date
    Apr 2007
    Posts
    12
    Quote Originally Posted by dwks View Post
    You need to check to see if x<0, y<0, and y>max too. And if an array has N elements, you want to check for x>=max, because C arrays are zero-based.

    It's a little complicated. I guess that you want to increment the character you use when you travel right and decrement the character you use when you travel right, but use the same one if you go up or down. Assuming I'm right, you need an index of sorts to keep track of which character you are using, and wrap it as required. (If it gets below zero, add strlen(a), and vise versa.)
    Ya. U R exactly right. If going right and down I can get it correctly. But left and up it will be reversible. Assuming I choose ABC, for left and down or should I say decrement it would be CBA. Is there anyway I can fix it.

    Can u xplain more on "index of sorts to keep track of which character you are using, and wrap it as required". I'm not clear about that.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Template Recursion Pickle
    By SevenThunders in forum C++ Programming
    Replies: 20
    Last Post: 02-05-2009, 09:45 PM
  2. Recursion... why?
    By swgh in forum C++ Programming
    Replies: 4
    Last Post: 06-09-2008, 09:37 AM
  3. a simple recursion question
    By tetra in forum C++ Programming
    Replies: 6
    Last Post: 10-27-2002, 10:56 AM
  4. To Recur(sion) or to Iterate?That is the question
    By jasrajva in forum C Programming
    Replies: 4
    Last Post: 11-07-2001, 09:24 AM
  5. selection sorting using going-down and going-up recursion
    By Unregistered in forum C Programming
    Replies: 1
    Last Post: 11-02-2001, 02:29 PM