cancel
Showing results for 
Search instead for 
Did you mean: 

scanf() can only read one character

LittleYe233
Associate II

I am trying to use scanf() in STM32H743, referring a webpage (here). More specifically, after setting up USART1 in STM32CubeMX, I add some function prototypes like:

 

 

 

#ifdef __GNUC__
#define PUTCHAR_PROTOTYPE int __io_putchar(int ch)
#define GETCHAR_PROTOTYPE int __io_getchar(void)
#else
#define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)
#define GETCHAR_PROTOTYPE int fgetc(FILE *f)
#endif

PUTCHAR_PROTOTYPE
{
  HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, HAL_MAX_DELAY);
  return ch;
}

GETCHAR_PROTOTYPE
{
  uint8_t ch = 0;

  /* Clear the Overrun flag just before receiving the first character */
  __HAL_UART_CLEAR_OREFLAG(&huart1);

  /* Wait for reception of a character on the USART RX line and echo this
   * character on console */
  HAL_UART_Receive(&huart1, (uint8_t *)&ch, 1, HAL_MAX_DELAY);
  // HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, HAL_MAX_DELAY);
  return ch;
}

 

 

 

and add a scanf() in the main function before infinite while loop:

 

 

 

scanf("%c", &c);

 

 

 

where c is a char.

I found that if I read one character (e.g. a char variable) every time, the function works well. But if I try to read more like integers and strings, the function seems being stuck. I don't know where it is stuck and why it happened. Please help. Any help is appreciated.

 

EDIT: I have added "setvbuf(stdin, NULL, _IONBF, 0);" before any scanf() call.

1 ACCEPTED SOLUTION

Accepted Solutions
LittleYe233
Associate II

@Peter BENSCH @SMarie @Andrew Neil Thanks for your fast replies. I forget to mention in the first thread that I actually added "setvbuf()" before any scanf() call. And I found that this situation happened because I forgot to automatically add LF after my input in the serial termial. With LF or CR/LF, scanf() begins to work well again. That's all my fault and thank you all again.

View solution in original post

5 REPLIES 5
Peter BENSCH
ST Employee

Try deactivating the buffering before scanf():

setvbuf(stdin, NULL, _IONBF, 0);

Regards
/Peter

In order to give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.
SMarie
Senior

Did you add the config indicated in the link you gave ?

setvbuf(stdin, NULL, _IONBF, 0);

If not could you try it ?
If you did, could you show us the rest of your code ?

S. Marie

Andrew Neil
Evangelist III

@LittleYe233 wrote:

But if I try to read more like integers and strings, the function seems being stuck.


How, exactly, are you testing that?

@Peter BENSCH and @SMarie have suggested disabling buffering - so does your input work as-is if you terminate entry with CR and/or LF ?

 

EDIT:

See this thread on the buffering of stdin, etc:

https://community.st.com/t5/stm32-mcus-products/stm32g030-usart-and-hal-delay-strange-behavior/m-p/640684

 

LittleYe233
Associate II

@Peter BENSCH @SMarie @Andrew Neil Thanks for your fast replies. I forget to mention in the first thread that I actually added "setvbuf()" before any scanf() call. And I found that this situation happened because I forgot to automatically add LF after my input in the serial termial. With LF or CR/LF, scanf() begins to work well again. That's all my fault and thank you all again.

Good to hear - please mark the solution:

https://community.st.com/t5/community-guidelines/help-others-to-solve-their-issues/ta-p/575256

I think this is defined behaviour for stdin in the standard C library.