Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations gkittelson on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

scanf error

Status
Not open for further replies.

mikeajose

Technical User
Sep 23, 2004
1
GB
The following section of code does not read the character in from the command line. Instead the execution skips this line and executes the action in the last else clause of the program. Does anyone have any ideas as to why scanf is failing here?

char c ;
printf("Would you like to alter anyone's details? n -for name, a - address, i - age, q - quit\n");
scanf("%c",&c); //this line is skipped

int j;
char* oldName;
char* newName;

char* newAdd;
struct person temp;
int newAge = 0;

printf("The char c is %c",c);

if(c == 'n')
{
printf("Enter the name of the person to change\n");
scanf("%s", oldName);

for(j = 0; j < 5; j++){
temp = people[j];
if(strcmp(temp.name,oldName) == 0)
break;
}
printf("Enter the new name to change o\n");
scanf("%s",newName);
temp.name = newName;
}
else if(c == 'a'){

printf("Enter the name of the person to change\n");
scanf("%s", oldName);
printf("Enter the new address to change to\n");
scanf("%s",newAdd);

for(j = 0; j < 5; j++){
temp = people[j];

if(strcmp(temp.name,oldName) == 0)
temp.address = newAdd;

}

}
else if(c=='i'){

printf("Enter the name of the person to change\n");
scanf("%s", oldName);
printf("Enter the new age to change to\n");
scanf("%i",&newAge);

for(j = 0; j < 5; j++){
temp = people[j];
if(strcmp(temp.name,oldName) == 0)
temp.age = newAge;
}
}
else if(c == 'q')
printf("Closing system\n");
else
printf("See ya later!"); //executes this line before exiting

return 0;

}
 
Well there are several things wrong.

1. you're using scanf()
scanf() functions only process the MINIMUM number of characters necessary to satisfy the current conversion, or until some error is encountered.
The result is, there is an awful lot of instances where input is left on the input stream ready to mess up some future input.

Also, scanf() mixes input status returns with conversion status returns, and as a result, using it properly gets really messy really quickly.

The hacky way out of tidying up your input stream, before trying to read a single character with %c is to do this
Code:
void stdin_tidy(void){
  int ch;
  while ( (ch=getchar()) != EOF && ch != '\n' );
}

Then you could do
Code:
stdin_tidy();
scanf("%c",&c);


The safe way to read a line of input is as follows
Code:
char buff[BUFSIZ];  // BUFSIZ is a constant in stdio.h
if ( fgets( buff, BUFSIZ, stdin ) != NULL ) {
  // use sscanf() or something to extract info from buff
  // check the conversion result of sscanf() to make sure your input is valid
} else {
  // end of input - finish off whatever needs finishing
  // and exit the program, no more input
}
This allows you to separate input errors and conversion errors.

2. Your 'strings' are not allocated.
Code:
    char* oldName;
        scanf("%s", oldName);
oldName does not point anywhere in particular, so as a result, your input goes nowhere in particular. It might be harmless now, but for sure it will trash something important sooner or later.

Try
Code:
char oldName[100];
scanf( "%s", oldName );
Though you should really use fgets() and strncpy() to ensure that there is no possibility of buffer overflow if you intend this to be robust.

--
 
Status
Not open for further replies.

Similar threads

Part and Inventory Search

Sponsor

Back
Top