solid.py
solid.py

Reputation: 2812

Why multiple arguments in scanf() function in c crash the app?

I cant really understand if its the syntax of the following scanf()

The purpose of this program is to read math inputs like: 6x+7y+8z=2 (x3 times)
and then output an array that holds the numerical values of the input.

After successfully giving the input the application crashes
Although the compiler shows no error or warning of any kind

#include <stdio.h>
int main()  
{
    int number[3][4],i,j;
    char vch[3][4];

for(i=0;i<3;i++){
scanf("%d%c%d%c%d%c%c%d",&number[i][0],&vch[i][0],&number[i][1],&vch[i][1],&number[i][2],&vch[i][2],&vch[i][3],&number[i][3]);
printf("\n");
}
for(i=0;i<3;i++)
    for(j=0;j<4;j++)
        printf("%d",number[i][j]);
return 0;
}

Upvotes: 1

Views: 945

Answers (2)

Floris
Floris

Reputation: 46415

To read the equation you are showing, you really need to read two characters between the first sets of numbers (instead of one). So you would want to do

#include <stdio.h>
int main()
{
    int number[3][4],i,j;
    char vch[3][6];

for(i=0;i<3;i++){
printf("enter equation %d:\n", i);
scanf("%d %c %c %d %c %c %d %c %c %d",&number[i][0], &vch[i][0], &vch[i][1], \
                                      &number[i][1], &vch[i][2], &vch[i][3], \
                                      &number[i][2], &vch[i][4], &vch[i][5], \
                                      &number[i][3]);
}
for(i=0;i<3;i++) {
    for(j=0;j<4;j++)
        printf("%4d ",number[i][j]);
    printf("\n");
}
return 0;
}

output:

enter equation 0:
2x+3y+4z=0
enter equation 1:
2x+5y+10z=-15
enter equation 2:
5x+7y+9z=3
   2    3    4    0 
   2    5   10  -15 
   5    7    9    3 

EDIT an improved program that does not use scanf and handles various other inputs could look like this:

#include <stdio.h>
#include <string.h>

int interpret(char* s) {
  // interpret the string as a number
  // if there is only a sign, return +1 or -1 as appropriate

  int it;
  if(sscanf(s, "%d", &it) == 1) return it;
  // look for just a sign with no number
  if( strstr(s, "-") > 0) return -1;
  return 1;
}

void squeezeWhite(char* s) {
  // remove all spaces
  char *t = s;
  int ii = 0;
  while(*t !='\0') {
    if (*t != ' ') s[ii++] = *t;
    t++;
  }
  s[ii] = '\0';
}

void tokenize(char *buf, int *arr) {
  char *temp;
  int it;
  squeezeWhite(buf);
  temp = strtok(buf, "xyz");
  // handle the case of nothing in front of x:
  if(temp == buf + 1) {
    arr[0] = 1;
    arr[1] = interpret(temp);
  }
  else {
    arr[0] = interpret(temp);
    temp = strtok(NULL, "xyz");
    arr[1] = interpret(temp);
  }
  temp = strtok(NULL, "xyz");
  arr[2] = interpret(temp);
  temp = strtok(NULL, "=");
  arr[3] = interpret(temp);
}

int main()
{
    int number[3][4],i,j;
    char vch[3][6];
    char buffer[100];

  for(i=0;i<3;i++){
    printf("enter equation %d:\n", i);
    fgets(buffer, 100, stdin);
    tokenize(buffer, number[i]);
  }
  for(i=0;i<3;i++) {
    for(j=0;j<4;j++)
      printf("%4d ",number[i][j]);
    printf("\n");
  }
  return 0;
}

Example of input/output:

enter equation 0:
-x+y+z=1
enter equation 1:
2x + 3 y + 4 z = 7
enter equation 2:
+2x+2y+2z=+2
  -1    1    1    1 
   2    3    4    7 
   2    2    2    2 

As you can see it handles coefficients gracefully, even if there are no numbers (just + or - signs). The basic idea I am showing here - to process the input in steps - is a good idea when your user may not conform to your input specification. It is much more robust than reading scanf, which will fall at the first hurdle. It did involve writing a few "helper functions". That's usually how it works...

Upvotes: 1

haccks
haccks

Reputation: 106092

Try this

scanf("%d %c %c %d %c %c %d %c %c %d",&number[i][0],&vch[i][0],&vch[i][1] &number[i][1],&vch[i][2],&vch[i][3],&number[i][2],&vch[i][4],&vch[i][5],&number[i][3]);  

with an extra space before %c to eat up the newline character \n left behind by the previous scanf.

Upvotes: 0

Related Questions