0

I have an old project in Visual C++ and I'm trying to migrate it to Visual Studio 2013. When I verify if a txt file exists, CFile returns debug assertion error. The code is:

if (!txt_file.Open(txt_name,    CFile::modeWrite | CFile::shareDenyWrite  | CFile::typeText))
{
    //action if the file exists
}

What is the problem, I'm doing something wrong ? Thank you

L.E. :

txt_file is declared as : CStdioFile txt_file in the class trace
txt_name is declared as : private CString txt_name in the method named open_file from class trace
The method open_file contains the if statement that returns debug assertion error.

Madalin
  • 129
  • 15
  • 1
    You should be able to step through the code and determine the cause of the assertion. – rrirower Jan 19 '16 at 13:48
  • I'm using my crystal ball here, but if it's an older application, it was probably written for an older version of Windows where the security restrictions were not as strictly enforced. Where is this file located? Is it in the root directory of the disk or in a subdirectory of a common directory (like Program Files), where you (as a normal user) would not be able to open it for writing? If so, you need to move the file some place else more appropriate for a normal user to have read/write access, like the My Documents folder. – Cody Gray - on strike Jan 19 '16 at 13:50
  • 1
    It would help a lot of you would say what the assertion error is. That said, in my experience, Visual C++ makes the curious assertion that the creation date of any file you try to open is later than 00:00 1/1/1970. Some file import sources leave a zero in the creation date field, which results in that particular assertion failure. I have never understood why that assertion is there. – Logicrat Jan 19 '16 at 13:50
  • @CodyGray The txt file is in `D:\my_project\sub-folder` – Madalin Jan 19 '16 at 13:52
  • @Logicrat The assertion is : `Debug Assertion Failed! File: f:\dd\vctools\vc7libs\ship\atlmfc\src\mfc\filecore.cpp line 179 ` P.S.: I don't have that path locally in my machine. The actual path of that file is `C:\ ..` – Madalin Jan 19 '16 at 13:53
  • 2
    @Madalin This isn't the full assertion failure message, and the part you pasted is missing the reason for assertion. – Algirdas Preidžius Jan 19 '16 at 13:59
  • @AlgirdasPreidžius I've pasted the whole message that appears in the window. I don't see in the message window the reason for assertion. – Madalin Jan 19 '16 at 14:06
  • 1
    @Madalin I find that hard to believe, since all asserts that I saw, contained the actual expression that caused the assertion. – Algirdas Preidžius Jan 19 '16 at 14:12
  • @AlgirdasPreidžius I've checked again. This is the whole message: `Debug Assertion Failed! File: f:\dd\vctools\vc7libs\ship\atlmfc\src\mfc\filecore.cpp Line: 179 For information on how your program can cause an assertion failure, see the Visual C++ documentation on asserts. (Press Retry to debug the application)` – Madalin Jan 19 '16 at 14:15
  • 2
    So you press "Retry", which drops you into the MFC source code. Then you look at the Call Stack window and trace back to the top most code file in the list that is part of *your* application. This will tell you which line of code caused the error. – Cody Gray - on strike Jan 19 '16 at 14:16
  • @CodyGray The code that caused the error is the `if` statement from the current question. I've done what you said and in the call stack is the same line. – Madalin Jan 19 '16 at 14:22
  • @Madalin And, what was the condition, _in MFC code_ that caused the assertion? – Algirdas Preidžius Jan 19 '16 at 14:33
  • `// shouldn't open an already open file (it will leak) ASSERT(m_hFile == INVALID_HANDLE_VALUE);` – Madalin Jan 19 '16 at 14:35
  • 1
    If it's saying that the file is already open, do you run that code more than once? If so, do you close the file if it succeeds? – Roger Rowland Jan 19 '16 at 14:39
  • That piece of code is running only once. I've tried the solution posted by Danny below and now the debug assertion error is triggered at : `txt_file.Close();` – Madalin Jan 19 '16 at 15:12
  • Your code looks wrong, or the comment looks wrong. If `CFile::Open` fails, it returns zero. But your comment says "action if the file exists" - that's the wrong way round. – Roger Rowland Jan 19 '16 at 15:15
  • 1
    That's the wrong way to check for file existence. See [Superstition: Why is GetFileAttributes the way old-timers test file existence?](https://blogs.msdn.microsoft.com/oldnewthing/20071023-00/?p=24713) – IInspectable Jan 19 '16 at 18:24

2 Answers2

1

You are probably using:

CFile txt_file;

CFile does not support text mode.

To open in text mode, you can change to:

CStdioFile txt_file;

That should fix the problem (at least, using CFile in this case generates an assertion).


If you are using CStdioFile already, there's probably a problem with the (combination of) open modes. As a test, try to remove CFile::shareDenyWrite. There could be security restrictions too.

mfc\filecore.cpp Line: 179

It might be best to step through it with the debugger, or have a look at filecore.cpp Line: 179 to see what gets checked there (I would look it up for you, but don't have Visual Studio 2013 at hand right now - probably open modes).

Update:

This is line 179:

// shouldn't open an already open file (it will leak)

ASSERT(m_hFile == INVALID_HANDLE_VALUE);

The file is already opened. So no need to open it again, or first needs to be closed, to open with other open modes.

txt_file.Close();

Or to test if the file is open (not valid for CMemFile):

if (txt_file.m_hFile != CFile::hFileNull) { // file already open
    txt_file.Close();
}
Community
  • 1
  • 1
Danny_ds
  • 11,201
  • 1
  • 24
  • 46
  • Actually, txt_file is declared as : `CString txt_file` and it contains the path to the txt file. – Madalin Jan 19 '16 at 13:59
  • @Madalin - That would be `txt_name` ? – Danny_ds Jan 19 '16 at 14:00
  • Sorry, I'm very tired... So : `CString txt_name` and `CStdioFile txt_file`. This is how they are declared now. Sorry again for the confusion. – Madalin Jan 19 '16 at 14:03
  • This is line 179 : `// shouldn't open an already open file (it will leak) ASSERT(m_hFile == INVALID_HANDLE_VALUE);` I've removed `CFile::shareDenyWrite` and I have the same issue. – Madalin Jan 19 '16 at 14:28
  • Thank you for the solution Danny. I've added the `if` statement and now the debug assertion error is triggered at this new line ( where I check if the file is open ). Exactly at : `txt_file.Close();` – Madalin Jan 19 '16 at 15:11
  • @Madalin - Strange, tested this here. Try `if (txt_file.m_hFile != INVALID_HANDLE_VALUE) {` instead - but this is actually the same. But it would be better to close the file where it needs to be closed, or not reopen it at all. – Danny_ds Jan 19 '16 at 15:18
  • Danny, I've modified the `if` statement. I have the same issue. At : `txt_file.Close()` the debug assertion error appears. LE : I've noticed now that if I press continue in the error window the file is created ( if it doesn't exist ). So the code it's working, but why the error ? – Madalin Jan 19 '16 at 15:39
  • @Madalin - Very strange, but you'll have to step through it with the debugger to see what's happening. Do you mean you had an assertion with `Open()` even if the file didn't exist yet? Is the file used elsewhere in the program? Is there a memory mapping created over the file? – Danny_ds Jan 19 '16 at 15:46
  • No, there is no memory mapping over the file. Yes, the file is used elsewhere in the program ( after it is created or succesfully opened ). – Madalin Jan 19 '16 at 16:08
  • @Madalin - I mean, is the file used before you try to open it here? And where do you get the assertion if you step through it with the debugger? To make sure: you first check the file handle, if not `CFile::hFileNull` you try to close it, and that asserts? – Danny_ds Jan 19 '16 at 16:21
  • No, the file is not used anywhere. If I step through it with the debugger I get the assertion when I call `txt_file.Close()`. And if I remove `txt_file.Close()` I get the assertion just after the if statement from the question. – Madalin Jan 19 '16 at 16:41
  • @Madalin - Ok, but where is the assertion triggered in filecore.cpp/filetxt.cpp? That's where the information, and possible solution is. – Danny_ds Jan 19 '16 at 16:46
  • Yes, in filecore.cpp/filetxt.cpp it's triggered. At the following line ( 380 ) : `ASSERT_VALID(this); ASSERT(m_pStream != NULL);` – Madalin Jan 19 '16 at 16:48
  • @Madalin sound like memory corruption due to another problem somewhere else in your code. Please show how `txt_file` is declared; is it an class/struct member member, is it a local variable, a global variable.. Please show also more relevant code. – Jabberwocky Jan 19 '16 at 17:47
  • @MichaelWalz Thank you for your comment ! I've updated the question. – Madalin Jan 20 '16 at 09:18
0

SOLVED !

Instead of using the piece of code from the question to check if the file exists, I've used the following code :

  CFileStatus sts; //status flag
        bool chkifFileExists = CFile::GetStatus(txt_name, sts); // return TRUE if the file exists else return false




        if (!(chkifFileExists))

{
 //do something
}

Thank you all for your support !

Madalin
  • 129
  • 15