Thread: MSVC getline(istream&, string&) stops program

  1. #1
    Registered User Chris87's Avatar
    Join Date
    Dec 2007
    Posts
    139

    MSVC getline(istream&, string&) stops program

    Following my last post about the regex library of C++11/14, I did a bit of MSVC debugging and discovered regex wasn't the issue at all, but instead it was getline() from the string library. I thoroughly debugged my code and I placed breakpoints on 2 consecutive lines. No matter what I try, execution exits without error when it reaches getline()'s call.

    Code:
    #include <fstream>
    #include <iostream>
    #include <regex>
    #include <string>
    
    bool parseScript(const char * filename)
    {
    	std::ifstream scriptFile(filename);
    	std::regex labelSyntax("([A-Z]+)([0-9]*)[ \t]+\\{(.*)\\}[\r\n]");
    	std::string line;
    
    	if (!scriptFile) return false; // breakpoint 1, this line was added during debugging with no change in behavior
    	std::getline(scriptFile, line); // breakpoint 2 is never reached
    	std::cout << line << std::endl;
    
    	while (std::getline(scriptFile, line))
    	{
    		std::smatch m;
    		if (std::regex_match(line, m, labelSyntax))
    		{
    			if (m[1].str() == "LANGUAGE")
    				std::cout << "Locale set to " << m[3].str() << std::endl;
    			else if (m[1].str() == "ITEMTOT")
    				std::cout << "There are " << m[3].str() << " total items." << std::endl;
    			else if (m[1].str() == "SPLTOT")
    				std::cout << "There are " << m[3].str() << " total spells." << std::endl;
    			else if (m[1].str() == "MOBTOT")
    				std::cout << "There are " << m[3].str() << " total monsters." << std::endl;
    			else if (m[1].str() == "WEPTOT")
    				std::cout << "There are " << m[3].str() << " total weapons." << std::endl;
    			else if (m[1].str() == "BARTOT")
    				std::cout << "There are " << m[3].str() << " total barriers." << std::endl;
    			else if (m[1].str() == "TRPTOT")
    				std::cout << "There are " << m[3].str() << " total traps." << std::endl;
    			else if (m[1].str() == "TRETOT")
    				std::cout << "There are " << m[3].str() << " total treasures." << std::endl;
    			else if (m[1].str() == "TELTOT")
    				std::cout << "There are " << m[3].str() << " total teleports." << std::endl;
    			else
    			{
    				switch (m[1].str()[0])
    				{
    					case 'I': // item
    						break;
    					case 'S': // spell
    						break;
    					case 'M': // monster
    						break;
    					case 'W': // weapon
    						break;
    					case 'B': // barrier
    						break;
    					case 'X': // trap
    						break;
    					case 'T': // treasure
    						break;
    					case 'P': // teleport
    						break;
    					case 'L': // level
    						break;
    					default:
    						std::cerr << "Error: Unknown label" << std::endl;
    						return false;
    				}
    			}
    		}
    	}
    	scriptFile.close();
    	return true;
    }
    
    int main(int argc, char ** argv)
    {
    	if (argc != 2)
    	{
    		std::cerr << "Usage: " << argv[0] << " <input file>" << std::endl;
    		return 1;
    	}
    	if (!parseScript(argv[1]))
    		std::cerr << "Oops!" << std::endl;
    	return 0;
    }
    As you can see, if there was an error with the file stream itself, the function would've returned 'false' and "Oops!" would be output, but I get no output whatsoever.

  2. #2
    Guest
    Guest
    I can see nothing wrong. Long shot, but have you tried uncommenting any regex code? Surely std::getline and std::ifstream have no blatant bugs in them, even in Microsoft's implementation. Mind sharing the error message and first few lines of your input file?

  3. #3
    Registered User Chris87's Avatar
    Join Date
    Dec 2007
    Posts
    139
    I've tried that with the same results unfortunately. Here's what the debugger outputs:

    Code:
    'ConsoleApplication1.exe' (Win32): Loaded 'C:\Users\admin\AppData\Local\Temp\ConsoleApplication1\Debug\ConsoleApplication1.exe'. Symbols loaded.
    'ConsoleApplication1.exe' (Win32): Loaded 'C:\Windows\SysWOW64\ntdll.dll'. Cannot find or open the PDB file.
    'ConsoleApplication1.exe' (Win32): Loaded 'C:\Windows\SysWOW64\kernel32.dll'. Cannot find or open the PDB file.
    'ConsoleApplication1.exe' (Win32): Loaded 'C:\Windows\SysWOW64\KernelBase.dll'. Cannot find or open the PDB file.
    'ConsoleApplication1.exe' (Win32): Loaded 'C:\Windows\SysWOW64\vcruntime140d.dll'. Cannot find or open the PDB file.
    'ConsoleApplication1.exe' (Win32): Loaded 'C:\Windows\SysWOW64\ucrtbased.dll'. Cannot find or open the PDB file.
    'ConsoleApplication1.exe' (Win32): Loaded 'C:\Windows\SysWOW64\msvcp140d.dll'. Cannot find or open the PDB file.
    'ConsoleApplication1.exe' (Win32): Loaded 'C:\Windows\SysWOW64\advapi32.dll'. Cannot find or open the PDB file.
    'ConsoleApplication1.exe' (Win32): Loaded 'C:\Windows\SysWOW64\msvcrt.dll'. Cannot find or open the PDB file.
    'ConsoleApplication1.exe' (Win32): Loaded 'C:\Windows\SysWOW64\sechost.dll'. Cannot find or open the PDB file.
    'ConsoleApplication1.exe' (Win32): Loaded 'C:\Windows\SysWOW64\rpcrt4.dll'. Cannot find or open the PDB file.
    'ConsoleApplication1.exe' (Win32): Loaded 'C:\Windows\SysWOW64\sspicli.dll'. Cannot find or open the PDB file.
    'ConsoleApplication1.exe' (Win32): Loaded 'C:\Windows\SysWOW64\cryptbase.dll'. Cannot find or open the PDB file.
    'ConsoleApplication1.exe' (Win32): Loaded 'C:\Windows\SysWOW64\bcryptprimitives.dll'. Cannot find or open the PDB file.
    'ConsoleApplication1.exe' (Win32): Loaded 'C:\Windows\SysWOW64\kernel.appcore.dll'. Cannot find or open the PDB file.
    The thread 0x254 has exited with code 0 (0x0).
    The thread 0x49c has exited with code 0 (0x0).
    The thread 0x1f6c has exited with code 0 (0x0).
    The program '[8040] ConsoleApplication1.exe' has exited with code 0 (0x0).
    Also, first few lines of input:
    Code:
    LANGUAGE {English/ANSI}
    LEVEL6 {}
    ITEMTOT {124}
    INAM1    {dagger}
    IDES1    {a dagger}
    ISTT1    {15 10 0 1 3 1 0 0 0 1 0 0 0 0 0 0}
    IEFF1    {}

  4. #4
    Guest
    Guest
    No idea man, I copy/pasted your program and it prints LANGUAGE English/ANSI here as one would expect. Couting hard-coded values after line 14 doesn't show up either?

    (Forum Gurus, how does one write curly braces inline without tripping the forum's code detection? I tried the [noparse] bbcode tag, but that doesn't seem to work.)
    Last edited by Guest; 06-13-2016 at 06:06 PM.

  5. #5
    Registered User Chris87's Avatar
    Join Date
    Dec 2007
    Posts
    139
    Correct. I've been trying this with both MinGW 6.1.1 and MSVC 2015

    I just ran it without the debugger on cmd.exe and it prints "LANGUAGE English/ANSI" after all it seems. Not sure why it stops there though

  6. #6
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    Can you add these things to your code.
    Code:
    #include <exception>
    
    int main(int argc, char ** argv)
    {
        if (argc != 2)
        {
            std::cerr << "Usage: " << argv[0] << " <input file>" << std::endl;
            return 1;
        }
        try {
            if (!parseScript(argv[1]))
                std::cerr << "Oops!" << std::endl;
        } 
        catch (exception& e)
        {
            cout << "Standard exception: " << e.what() << endl;
        }
        catch (...) {
          cout << "Exception occurred";
        }
        return 0;
    }

    Also, your first getline call should be like this
    Code:
        if ( std::getline(scriptFile, line) ) { // breakpoint 2 is never reached
            std::cout << line << std::endl;
        } else {
            std::cerr << "Failed to read first line" << std::endl;
            return false;
        }
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  7. #7
    Registered User Chris87's Avatar
    Join Date
    Dec 2007
    Posts
    139
    Turns out MSVC was hiding the output. Runs fine with cmd.exe. However, now I'm stuck with std::regex not working again. Linux it runs fine but MS's std::regex, and boost::regex don't match anything. There has to be something under the hood of both if regex won't work on Win32.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. string stops at first letter
    By brillpsycho in forum C++ Programming
    Replies: 2
    Last Post: 11-06-2012, 12:14 AM
  2. program stops before EOF
    By doia in forum C Programming
    Replies: 2
    Last Post: 03-22-2010, 12:10 PM
  3. Program stops executing
    By bargomer in forum C++ Programming
    Replies: 16
    Last Post: 04-26-2008, 12:05 PM
  4. MSVC getline() header location?
    By Hunter2 in forum C++ Programming
    Replies: 3
    Last Post: 08-14-2004, 12:01 PM
  5. istream::getline()
    By mousey in forum C++ Programming
    Replies: 4
    Last Post: 10-18-2003, 09:06 PM

Tags for this Thread