2
\$\begingroup\$

Your program is to use the brute-force approach in order to find the answer to Life, the Universe, and Everything. More precisely, rewrite small numbers from input to output. Stop processing input after reading in the number 42. All numbers at input are integers of one or two digits.

I was solving this problem and I submitted 3 solutions and I got "SEGMENTATION FAULT" for the first 2. The third one finally executed successfully, but I wanted to know where I made a mistake while solving.

1st I submitted:

#include <stdio.h>
  int main(void) 
    {
      int i=0,j,a[9];

      while(a[i]!= 42)
       {
         ++i;
         scanf("%d",&a[i]);
       }
     for(j=0;j<i;j++)
     {
      printf("%d",a[j]);
       printf("\n");
      }
    return 0;
  }

2nd I submitted (after reading a comment that output has to be printed immediately after taking the input):

#include <stdio.h>
int main(void) 
 {
  int i=0,j,a[9];

 scanf("%d",&a[i]);
 printf("%d\n",a[i]);

 while(a[i]!=42)
  {
   ++i;
   scanf("%d",&a[i]);
   if(a[i]!=42)
    printf("%d\n",a[i]);
  }
}

Third one (it was correct):

 #include <stdio.h>

  int main(void) 
  {
   int i = 0;
   while (scanf("%d\n", &i) > 0 && i != 42) 
   {
    printf("%d\n", i);
   }
    return 0;
   }

Can anyone point where my approach has gone wrong? When I executed the first 2 on www.ideone.com they both ran successfully over there but on SPOJ there was a runtime error (segmentation fault).

\$\endgroup\$
1
  • 2
    \$\begingroup\$ Welcome to Code Review! Don't worry, we don't have a problem with questions that attack the same challenge. For future reference, we do have a rule against asking for explanation of how your code works. I think this question is OK, though, since you are asking for a review of a working solution and a comparison with two bad solutions. \$\endgroup\$ Nov 11, 2014 at 16:16

2 Answers 2

3
\$\begingroup\$

The working solution is quite good, actually. You check the return value of scanf(), and you use the while loop condition smartly to say exactly what you mean to accomplish. The only thing wrong with it is the indentation.

Here is one reasonable way to format it.

#include <stdio.h>

int main(void)
{
    int i = 0;
    while (scanf("%d\n", &i) > 0 && i != 42) 
    {
        printf("%d\n", i);
    }
    return 0;
}

The initialization of i to 0 and return 0 are actually not needed, but I don't have a problem with making them explicit.

As for your failed attempts, they fail because they attempt to store all of their input, which isn't necessary to do. When there are more than 9 inputs, the buffer overflows.

\$\endgroup\$
1
\$\begingroup\$
#include <stdio.h>

int main(void) 
{
    int i=0,j,a[9]; // this will be past the end of the array after 9 inputs

    // the following 'while' loop will run forever, progressively
    // writing further and further past the end of the 
    // a[] array until a seg fault occurs
    while(a[i]!= 42)  // the a[] array contains garbage 
    {
        ++i;          // this 'pre-increment' results in skipping a[0]
        scanf("%d",&a[i]); // will fail due to no allowance for white space
    }

    // execution will never get here
    for(j=0;j<i;j++)  // tries to print a[0] which is not initialized
    {
        printf("%d",a[j]);
        printf("\n");
    }
    return 0;
}
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.