Shop OBEX P1 Docs P2 Docs Learn Events
scan verse scanf — Parallax Forums

scan verse scanf

BTL24BTL24 Posts: 54
edited 2014-07-13 07:45 in Propeller 1
I have been experimenting with scan and scanf in an attempt to understand their differences. I have read on the forums that "simpletools.h" really can reduce code and that scan is the preferred input function over scanf, as it will l save program space.

BUT... they don't seem to operate/perform the same. Case in point.. see the following code....
/*
  input test scan1.c
*/

#include "simpletools.h"

char servostr [15];                       // Filename - Includes null char... usable space 14 characters

int main(void)                            // main function
{
  print("Enter filename: ");
  scanf("%14s", servostr);                // Scan in string from debug terminal (have to hit enter) <= 14 characters  
  print("Filename entered: %14s\n\n", servostr);

  print("Enter Servo filename: ");
  scan("%14s", servostr);                 // Scan in string from debug terminal (have to hit enter) <= 14 characters  
  print("Filename entered: %14s\n", servostr);
} // end main

Upon execution, the debug monitor prompts the user to enter a text file name e.g."bozo" via the keyboard and then prints it out. The scanf input function does fine and prints out the name "bozo".

Next, the debug monitor again prompts the user to input another filename, e.g., "clown", but the scan function does not receive the new input, but instead, prints out "bozo", the previous file name. Apparently, the scan function did not receive the keyboard input and defaulted to the previously entered data.

WHY? What is wrong in my assumption that the two functions should behave correctly? Does scan not receive/store any character text?

BTW...They both appear to work OK with numeric inputs using &variable as the pointer to variable upon input.

Any advice would be greatly appreciated...

Regards,
Brian (BTL24)

Comments

  • BTL24BTL24 Posts: 54
    edited 2014-07-08 21:53
    Well I just discovered getStr function and it appears to read in a char string just fine.... and uses way less code space than scanf. So I will continue to use getStr until otherwise notified or I run into an issue.

    I still want to know the differences between scan and scanf....

    Regards,
    Brian (BTL24)
  • jazzedjazzed Posts: 11,803
    edited 2014-07-08 21:59
    You found a bug maybe?

    I'll have a closer look tomorrow.
  • Sir GawainSir Gawain Posts: 32
    edited 2014-07-08 22:28
    From what I remember, the scanf() function in normal C assigns variables values parsed from a source, using a formatting pattern to make that association. So you must pass it the addresses of the variables.
    Your Code:
    scanf("%14s", servostr); // Scan in string from debug terminal (have to hit enter) <= 14 charact
    Try this:
    scanf("%14s", &servostr); // Scan in string from debug terminal (have to hit enter) <= 14 charact
    In Spin the name of the variable is like a label; points to the first memory location of the variable. But if I remember correctly, this is the way to do in in C.

    Hope it helps.
  • BTL24BTL24 Posts: 54
    edited 2014-07-09 22:02
    Sir Gawain wrote: »
    From what I remember, the scanf() function in normal C assigns variables values parsed from a source, using a formatting pattern to make that association. So you must pass it the addresses of the variables.
    Your Code:

    Try this:

    In Spin the name of the variable is like a label; points to the first memory location of the variable. But if I remember correctly, this is the way to do in in C.

    Hope it helps.

    Scanf works fine without the pointer as demostrated in my original code. The issue is that scanf uses a lot of memory so it is best to use scan instead. Scan is the function not working. I did take your advice though and did try the pointer approach with scan.... but it didn't work.

    I am no longer using scanf since getStr is working fine.

    Thanks for the suggestion...
    Brian (BTL24)
  • LoopyBytelooseLoopyByteloose Posts: 12,537
    edited 2014-07-10 04:53
    The issue with GCC on small microcontrollers is the 'printXXX' and 'scanXXX' functions are comparatively demanding of resources.

    This is not specifically a Propeller issue. The same situation applies in the AVR code and their documents mention that even though these functions have been in the tutorial material for C from the very beginning, it may be best to avoid them and just get and put characters one at a time from the input and output buffers.

    In other words, if you really want to use these io features, expect some slow down in just about any microcontroller. If you desire speed, there are faster ways with a bit more coding.
  • jazzedjazzed Posts: 11,803
    edited 2014-07-12 11:03
    The Simple Library scan functions do not accept %Ns formatting.

    Change scan("%14s", servostr); to scan("%s", servostr);
  • whickerwhicker Posts: 749
    edited 2014-07-12 11:59
    jazzed wrote: »
    The Simple Library scan functions do not accept %Ns formatting.

    Change scan("%14s", servostr); to scan("%s", servostr);

    And thus another buffer overflow exploit was created.
    Any way to add an extra parameter to scan( ) for a maximum length?
  • jazzedjazzed Posts: 11,803
    edited 2014-07-12 12:17
    whicker wrote: »
    And thus another buffer overflow exploit was created.
    Any way to add an extra parameter to scan( ) for a maximum length?

    Use getStr() which has such protections.
  • BTL24BTL24 Posts: 54
    edited 2014-07-13 07:45
    Thanks a million Jazzed....you always come through. Good to know for future projects regarding no formatting of scan function.

    As you have read above, I already switched to getStr and am happy to report all is well. Regarding buffer overflow protection...yes it works. I overran one filename by accident and getStr properly processed the char string without issue.

    Regards,
    Brian (BTL24)
Sign In or Register to comment.