Overclock.net › Forums › Software, Programming and Coding › Coding and Programming › Application Programming › Why doesn't my console program pause when I ask it to? (pure C)
New Posts  All Forums:Forum Nav:

Why doesn't my console program pause when I ask it to? (pure C)

post #1 of 4
Thread Starter 
Take for example, this simple code snippet:
Code:
int someValue = 0;

printf( "Type a value: " );
scanf( "%d", &someValue );

if ( someValue == 10 )
{
        // do something
        return;
}

// wait for keypress (pause program)
getchar();

So what? Looks normal to me, what can go wrong?

When we run this program and type a value other than 10, we would expect the program to halt and not close until we press a key, right? Wrong. You'll notice that it exits immediately! How can that be you say? Turns out, scanf() isn't too good when it comes to flushing characters from the input buffer, in this case stdin. I guess I should also note that scanf() is actually not a very safe function in terms of buffer overruns. The actual problem is that scanf() ignores all characters that did not match the input format. When we press ENTER, a carriage return gets put on the input stream - this does not match the format supplied and scanf() does not remove it from the input.

The problem is that when control finally transfers to the getchar() function, it notices that there is still characters on the input buffer, and returns immediately. This makes sense when we realize that getchar() doesn't usually return until someone presses a key (the function basically sits there waiting for data from stdin, and when it gets some it says "OK I'm done!").

Because of this behavior we can also get all sorts of bugs if a user inputs invalid data (infinite loops come to mind).

Buffer overruns? Infinite loops? They don't sound too good! How do I solve this?

Some compilers (Microsoft VC++ compiler is one example) will issue either an error or a warning during the build process that alerts you that you have used deprecated or insecure functions like scanf() and often offer alternatives. The obvious solution though is to make sure that we flush the input buffer before we call a function such as getchar(), like so:
Code:
fflush( stdin ); // remove all data from the stdin buffer
getchar(); // now waits as expected for a keypress.

However that still doesn't solve the real issues with scanf() (i.e. buffer overruns and infinite loops). If you are using Microsoft VC++ Compiler and are paying attention to its warnings, you'll notice it offers sscanf() as an alternative function, however this function doesn't quite work the exact same way as scanf() so you can't just go ahead and find/replace! What we need to do is read into our own buffer a certain amount of bytes from the stdin stream and then pass that to sscanf() for processing, like below:
Code:
/*
 * GetInput: An alternative to C runtime scanf to clean up flawed data
 * entry in C where scanf does not consume the content of stdin if the
 * conversion fails (i.e. char entered for int).
 */
int GetInput( const char* format, void* input )
{
        char buffer[ 100 ];

        fgets( buffer, 99, stdin );
        return sscanf( buffer, format, input );
}

And there we have it - both problems solved!
Edited by tompsonn - 9/16/12 at 12:45am
My System
(30 items)
 
"Zeus"
(13 items)
 
 
CPUMotherboardGraphicsRAM
Intel Core i5 2500K (4.5ghz @ 1.320v) Gigabyte Z68X-UD3R-B3 MSI R7970 Lightning Corsair 16GB (4x4GB) 
Hard DriveHard DriveHard DriveHard Drive
Plextor PX-256M5S 256GB Crucial M4 128GB Hitachi HDS721010CLA332 Hitachi HDS723020BLA642 
Hard DriveHard DriveHard DriveOptical Drive
Hitachi HDS723020BLA642 Hitachi HUA722010CLA330 WDC WD10EARS-00Z5B1 TSSTcorp CDDVDW SH-S223B 
CoolingCoolingOSMonitor
Phanteks PH-TC14PE with TY-140's Lamptron FCv5 (x2) Windows 7 Ultimate 64-bit Dell U2412M 
MonitorMonitorMonitorKeyboard
Dell U2412M Dell U2212HM Dell U2212HM Ducky DK9087 G2 Pro 
PowerCaseMouseMouse Pad
Corsair AX-750 Corsair Obsidian 650D Microsoft IntelliMouse Optical  XTRAC Ripper XXL 
AudioAudioAudioAudio
Westone W3 IEMs RE-272 IEMs Shure SE-215 IEMs Schiit Bifrost DAC 
AudioAudio
Schiit Asgard 2 amp HiVi Swan M50W 2.1 
CPUMotherboardGraphicsRAM
Intel Core i7 950 GA-X58-UD3R Radeon HD 5450  24GB Corsair @ 1333mhz 
Hard DriveOSPowerCase
4x WD Cavair Red 1TB in RAID 0 Windows Server 2008 R2 x64 Corsair HX-520 LianLi LanCool 
  hide details  
Reply
My System
(30 items)
 
"Zeus"
(13 items)
 
 
CPUMotherboardGraphicsRAM
Intel Core i5 2500K (4.5ghz @ 1.320v) Gigabyte Z68X-UD3R-B3 MSI R7970 Lightning Corsair 16GB (4x4GB) 
Hard DriveHard DriveHard DriveHard Drive
Plextor PX-256M5S 256GB Crucial M4 128GB Hitachi HDS721010CLA332 Hitachi HDS723020BLA642 
Hard DriveHard DriveHard DriveOptical Drive
Hitachi HDS723020BLA642 Hitachi HUA722010CLA330 WDC WD10EARS-00Z5B1 TSSTcorp CDDVDW SH-S223B 
CoolingCoolingOSMonitor
Phanteks PH-TC14PE with TY-140's Lamptron FCv5 (x2) Windows 7 Ultimate 64-bit Dell U2412M 
MonitorMonitorMonitorKeyboard
Dell U2412M Dell U2212HM Dell U2212HM Ducky DK9087 G2 Pro 
PowerCaseMouseMouse Pad
Corsair AX-750 Corsair Obsidian 650D Microsoft IntelliMouse Optical  XTRAC Ripper XXL 
AudioAudioAudioAudio
Westone W3 IEMs RE-272 IEMs Shure SE-215 IEMs Schiit Bifrost DAC 
AudioAudio
Schiit Asgard 2 amp HiVi Swan M50W 2.1 
CPUMotherboardGraphicsRAM
Intel Core i7 950 GA-X58-UD3R Radeon HD 5450  24GB Corsair @ 1333mhz 
Hard DriveOSPowerCase
4x WD Cavair Red 1TB in RAID 0 Windows Server 2008 R2 x64 Corsair HX-520 LianLi LanCool 
  hide details  
Reply
post #2 of 4
very interesting.

thanks for sharing smile.gif
    
CPUMotherboardGraphicsRAM
Intel 3930K 4.5GHz @ 1.34V Asus rampage extreme IV Shaphire 6950 unlocked to 6970 Corsair Dominators GT 16GB 4GBX4 OCed @ 2400MHz... 
Hard DriveHard DriveOptical DriveCooling
Intel SSD 330 series 180GB WD Black 1TB 64Mb Cache + Blue 500GB 16mb Cache... LG DVD EK-Supreme HF - EN (Nickel) 
CoolingCoolingCoolingCooling
EK-FB KIT RE4 - Acetal Laing D5 Vario 12V DC Pump (MCP 655)  EK-BAY SPIN Reservoir - Plexi EK-CoolStream RAD XT (240) 
CoolingOSMonitorKeyboard
EK-CoolStream RAD XTX (120) Windows 7 64-bit LG W2261 22inch 1920X1080@60Hz Razer Lycosa 
PowerCase
Cooler Master Silent Pro Gold 1000W Thermaltake Level 10 GT 
  hide details  
Reply
    
CPUMotherboardGraphicsRAM
Intel 3930K 4.5GHz @ 1.34V Asus rampage extreme IV Shaphire 6950 unlocked to 6970 Corsair Dominators GT 16GB 4GBX4 OCed @ 2400MHz... 
Hard DriveHard DriveOptical DriveCooling
Intel SSD 330 series 180GB WD Black 1TB 64Mb Cache + Blue 500GB 16mb Cache... LG DVD EK-Supreme HF - EN (Nickel) 
CoolingCoolingCoolingCooling
EK-FB KIT RE4 - Acetal Laing D5 Vario 12V DC Pump (MCP 655)  EK-BAY SPIN Reservoir - Plexi EK-CoolStream RAD XT (240) 
CoolingOSMonitorKeyboard
EK-CoolStream RAD XTX (120) Windows 7 64-bit LG W2261 22inch 1920X1080@60Hz Razer Lycosa 
PowerCase
Cooler Master Silent Pro Gold 1000W Thermaltake Level 10 GT 
  hide details  
Reply
post #3 of 4
Thread Starter 
Quote:
Originally Posted by Fantasy View Post

very interesting.
thanks for sharing smile.gif

No problem biggrin.gif
My System
(30 items)
 
"Zeus"
(13 items)
 
 
CPUMotherboardGraphicsRAM
Intel Core i5 2500K (4.5ghz @ 1.320v) Gigabyte Z68X-UD3R-B3 MSI R7970 Lightning Corsair 16GB (4x4GB) 
Hard DriveHard DriveHard DriveHard Drive
Plextor PX-256M5S 256GB Crucial M4 128GB Hitachi HDS721010CLA332 Hitachi HDS723020BLA642 
Hard DriveHard DriveHard DriveOptical Drive
Hitachi HDS723020BLA642 Hitachi HUA722010CLA330 WDC WD10EARS-00Z5B1 TSSTcorp CDDVDW SH-S223B 
CoolingCoolingOSMonitor
Phanteks PH-TC14PE with TY-140's Lamptron FCv5 (x2) Windows 7 Ultimate 64-bit Dell U2412M 
MonitorMonitorMonitorKeyboard
Dell U2412M Dell U2212HM Dell U2212HM Ducky DK9087 G2 Pro 
PowerCaseMouseMouse Pad
Corsair AX-750 Corsair Obsidian 650D Microsoft IntelliMouse Optical  XTRAC Ripper XXL 
AudioAudioAudioAudio
Westone W3 IEMs RE-272 IEMs Shure SE-215 IEMs Schiit Bifrost DAC 
AudioAudio
Schiit Asgard 2 amp HiVi Swan M50W 2.1 
CPUMotherboardGraphicsRAM
Intel Core i7 950 GA-X58-UD3R Radeon HD 5450  24GB Corsair @ 1333mhz 
Hard DriveOSPowerCase
4x WD Cavair Red 1TB in RAID 0 Windows Server 2008 R2 x64 Corsair HX-520 LianLi LanCool 
  hide details  
Reply
My System
(30 items)
 
"Zeus"
(13 items)
 
 
CPUMotherboardGraphicsRAM
Intel Core i5 2500K (4.5ghz @ 1.320v) Gigabyte Z68X-UD3R-B3 MSI R7970 Lightning Corsair 16GB (4x4GB) 
Hard DriveHard DriveHard DriveHard Drive
Plextor PX-256M5S 256GB Crucial M4 128GB Hitachi HDS721010CLA332 Hitachi HDS723020BLA642 
Hard DriveHard DriveHard DriveOptical Drive
Hitachi HDS723020BLA642 Hitachi HUA722010CLA330 WDC WD10EARS-00Z5B1 TSSTcorp CDDVDW SH-S223B 
CoolingCoolingOSMonitor
Phanteks PH-TC14PE with TY-140's Lamptron FCv5 (x2) Windows 7 Ultimate 64-bit Dell U2412M 
MonitorMonitorMonitorKeyboard
Dell U2412M Dell U2212HM Dell U2212HM Ducky DK9087 G2 Pro 
PowerCaseMouseMouse Pad
Corsair AX-750 Corsair Obsidian 650D Microsoft IntelliMouse Optical  XTRAC Ripper XXL 
AudioAudioAudioAudio
Westone W3 IEMs RE-272 IEMs Shure SE-215 IEMs Schiit Bifrost DAC 
AudioAudio
Schiit Asgard 2 amp HiVi Swan M50W 2.1 
CPUMotherboardGraphicsRAM
Intel Core i7 950 GA-X58-UD3R Radeon HD 5450  24GB Corsair @ 1333mhz 
Hard DriveOSPowerCase
4x WD Cavair Red 1TB in RAID 0 Windows Server 2008 R2 x64 Corsair HX-520 LianLi LanCool 
  hide details  
Reply
post #4 of 4
A word of caution: fflush(stdin) should NOT be used. A deeper explanation can be found here.

http://www.gidnetwork.com/b-57.html

A friend gave me this code snippet that apparently does the same as an fflush(stdin), but safer.
Code:
scanf("*[^\n]");
        scanf("%*c");

Edited by Icekilla - 11/21/12 at 10:57pm
Vanessa
(18 items)
 
  
CPUMotherboardGraphicsRAM
Intel Core i5 2500k Gigabyte GA-Z77-D3H EVGA GTX 660ti SuperClocked PNY Optima MD4096SD3-1333 
Hard DriveHard DriveHard DriveOptical Drive
Western Digital WD500AAKX 500GB SATA Seagate ST2000DL003 ADATA AS510S3-120GM-C 120GB SSD Lite-On iHAS224-06 
CoolingOSMonitorMonitor
Cooler Master Hyper 212+ Windows 7 Ultimate x64 Samsung B1930  Benq G92HDA 
PowerCaseAudio
Corsair TX750 750W PSU Gray Acteck Octanux Logitech Z623 2.1CH 
  hide details  
Reply
Vanessa
(18 items)
 
  
CPUMotherboardGraphicsRAM
Intel Core i5 2500k Gigabyte GA-Z77-D3H EVGA GTX 660ti SuperClocked PNY Optima MD4096SD3-1333 
Hard DriveHard DriveHard DriveOptical Drive
Western Digital WD500AAKX 500GB SATA Seagate ST2000DL003 ADATA AS510S3-120GM-C 120GB SSD Lite-On iHAS224-06 
CoolingOSMonitorMonitor
Cooler Master Hyper 212+ Windows 7 Ultimate x64 Samsung B1930  Benq G92HDA 
PowerCaseAudio
Corsair TX750 750W PSU Gray Acteck Octanux Logitech Z623 2.1CH 
  hide details  
Reply
New Posts  All Forums:Forum Nav:
  Return Home
  Back to Forum: Application Programming
Overclock.net › Forums › Software, Programming and Coding › Coding and Programming › Application Programming › Why doesn't my console program pause when I ask it to? (pure C)