Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. C / C++ / MFC
  4. Get File Extension

Get File Extension

Scheduled Pinned Locked Moved C / C++ / MFC
announcementdebugginghelp
19 Posts 9 Posters 3 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • L Lost User

    Well, I realize that it is just a code sample... but there are alot of novice programmers learning by reading these forums. You might want to free() the memory you allocated for the extension and you forgot to return an integer for the main() function. Best Wishes, -David Delaune

    enhzflepE Offline
    enhzflepE Offline
    enhzflep
    wrote on last edited by
    #8

    Thanks David, I certainly had overlooked both of these points. Time I exercised a little more diligence..:thumbsup: Simon

    1 Reply Last reply
    0
    • enhzflepE enhzflep

      Thanks mate! Not so sure, I guess it would have been better to explicitly cast the '.' to a wchar_t. I figured since the function takes a wchar_t that this would be implicitly cast for me. Compiling with gcc 4.something, the only warning I get was for line 7 (the wszFilename declaration) - "warning: deprecated conversion from string constant to 'wchar_t*' " It compiles & runs just fine with the -Wall and -Wextra compiler flags. If the line in question is changed to:

      wchar_t *wszFilename = (wchar_t*)"project.config.user";

      Then it compiles with 0 warnings. [EDIT: but crashes like a bus!] The line should read:

      wchar_t *wszFilename = (wchar_t*)L"project.config.user";

      Nice catch! :thumbsup: Simon.

      A Offline
      A Offline
      Aescleal
      wrote on last edited by
      #9

      If you change wszFilename to a const char * you can avoid the cast. I can't see anywhere wszFilename is modified so you should be alright. Another thing you might not be aware of: In C you don't need to cast the return value of malloc or calloc - void * is type compatible with any sort of pointer so (at least in C90, not sure about C99) you can convert them to anything implicitly. Cheers, Ash

      1 Reply Last reply
      0
      • _ _Flaviu

        If you are using MFC, why don't you use CString::ReverseFind('.') ?

        J Offline
        J Offline
        jkirkerx
        wrote on last edited by
        #10

        I should of said it was just a stock win32 project in c++

        1 Reply Last reply
        0
        • L Lost User

          Jim, When you are working with paths on the windows platform I would recommend using the Shell Path Handling Functions[^]. You are probably looking for the PathFindExtension function[^]. Best Wishes, -David Delaune

          J Offline
          J Offline
          jkirkerx
          wrote on last edited by
          #11

          You kidding me, there's an app for that! So PathFinderExtension trumps the sample function posted earlier? Thanks Dave, spent way too much time on it last night.

          _ 1 Reply Last reply
          0
          • L Lost User

            Jim, When you are working with paths on the windows platform I would recommend using the Shell Path Handling Functions[^]. You are probably looking for the PathFindExtension function[^]. Best Wishes, -David Delaune

            J Offline
            J Offline
            jkirkerx
            wrote on last edited by
            #12

            That works great. Thanks But I don't get it. I'm not sure if the wcsncpy_s bombed, or if I have some kind of buffer error, that never got flagged. I have a registry function that's doing the same thing, but just the 1, so far, all others work fine. I'm going to post it in a new post.

            L 1 Reply Last reply
            0
            • J jkirkerx

              That works great. Thanks But I don't get it. I'm not sure if the wcsncpy_s bombed, or if I have some kind of buffer error, that never got flagged. I have a registry function that's doing the same thing, but just the 1, so far, all others work fine. I'm going to post it in a new post.

              L Offline
              L Offline
              Lost User
              wrote on last edited by
              #13

              jkirkerx wrote:

              I have a registry function that's doing the same thing, but just the 1, so far, all others work fine.

              Not sure but if you post the contents of the function and the calling function I might be able to pinpoint your problem. Because I am somewhat familiar with the project you are working on... last comment about path handling: In the future I would recommend that you use the Shell Path Handling Functions[^] when working on the windows platform rather than attempting to implement your own path parser. Over the past 20 years or so there have been hundreds of vulnerabilities associated with path handling/parsing... because many software engineers attempted to implement an algorithm of their own. Best Wishes, -David Delaune

              L 1 Reply Last reply
              0
              • J jkirkerx

                You kidding me, there's an app for that! So PathFinderExtension trumps the sample function posted earlier? Thanks Dave, spent way too much time on it last night.

                _ Offline
                _ Offline
                _Superman_
                wrote on last edited by
                #14

                There's also a CRT function for this - _splitpath_s/_wsplitpath_s

                «_Superman_»  _I love work. It gives me something to do between weekends.

                _Microsoft MVP (Visual C++)

                Polymorphism in C

                1 Reply Last reply
                0
                • L Lost User

                  jkirkerx wrote:

                  I have a registry function that's doing the same thing, but just the 1, so far, all others work fine.

                  Not sure but if you post the contents of the function and the calling function I might be able to pinpoint your problem. Because I am somewhat familiar with the project you are working on... last comment about path handling: In the future I would recommend that you use the Shell Path Handling Functions[^] when working on the windows platform rather than attempting to implement your own path parser. Over the past 20 years or so there have been hundreds of vulnerabilities associated with path handling/parsing... because many software engineers attempted to implement an algorithm of their own. Best Wishes, -David Delaune

                  L Offline
                  L Offline
                  Le Quang Long
                  wrote on last edited by
                  #15

                  Dear Mr. David Delaune, I have received your feedback. Thank you so much. please give me your email! Best Regards, L.Q.LONG

                  L 1 Reply Last reply
                  0
                  • L Le Quang Long

                    Dear Mr. David Delaune, I have received your feedback. Thank you so much. please give me your email! Best Regards, L.Q.LONG

                    L Offline
                    L Offline
                    Lost User
                    wrote on last edited by
                    #16

                    Le Quang Long wrote:

                    Dear Mr. David Delaune,
                    I have received your feedback.

                    :confused: What feedback?

                    1 Reply Last reply
                    0
                    • J jkirkerx

                      I copied this off the internet without fully understanding how it works, and now it's not working when I compile as Release version. In Debug it works fine. Not sure if I should dump it and reinvent the wheel, or if there is just a slight mistake in the code. The part I don't understand is in bold.

                      WCHAR extension [32];
                      WCHAR* peek = szFileName + szFileName [ wcslen( szFileName ) - 1 ];
                      while ( peek >= szFileName )
                      {
                      if (*peek == L'.') {
                      wcsncpy_s ( extension, peek, wcslen( peek ) ); // stuck here
                      break;
                      }
                      peek--;
                      }
                      swprintf_s( szFileExtension, L"%s", extension );

                      Edit: The peek gets stuck with a 2 dot extension, and won't progress forward like project.config.user And then all file extensions are .user after that. But just in Release

                      J Offline
                      J Offline
                      JohnCz
                      wrote on last edited by
                      #17

                      THe code snippet assumes UNICODE is being used. I would suggest to use generic mapping that will work for both: ANSII and UNICODE: As for retrieving parts of the path why not to let CRT do it for you using generic (_tsplitpath_s)? For example:

                      LPTSTR lpszPath = \_T("project.config.user");
                      TCHAR szFilename\[MAX\_PATH\] = {0};
                      TCHAR szExt\[MAX\_PATH\] = {0};
                      
                      \_tsplitpath\_s(lpszPath, NULL, NULL, NULL, NULL, szFilename, \_MAX\_FNAME, szExt, \_MAX\_EXT);
                      

                      JohnCz

                      J 1 Reply Last reply
                      0
                      • enhzflepE enhzflep

                        Further to Flaviu2 said, if you're not using MFC, this will work: Code:

                        #include <stdio.h>
                        #include <stdlib.h>
                        #include <string.h>

                        int main()
                        {
                        wchar_t *wszFilename = L"project.config.user";
                        wchar_t *extension;
                        wchar_t *dotPosition;
                        size_t extensionLength;

                        dotPosition = wcsrchr(wszFilename, '.');
                        extensionLength = wcslen(dotPosition);
                        
                        extension = (wchar\_t\*) malloc(extensionLength \* sizeof(wchar\_t));
                        wcscpy(extension, dotPosition + 1); // add 1 to point to char following the .
                        wprintf(extension);
                        

                        }

                        Output:

                        user

                        J Offline
                        J Offline
                        Joe Woodbury
                        wrote on last edited by
                        #18

                        What if the path is \\server\share\path.path\file?

                        1 Reply Last reply
                        0
                        • J JohnCz

                          THe code snippet assumes UNICODE is being used. I would suggest to use generic mapping that will work for both: ANSII and UNICODE: As for retrieving parts of the path why not to let CRT do it for you using generic (_tsplitpath_s)? For example:

                          LPTSTR lpszPath = \_T("project.config.user");
                          TCHAR szFilename\[MAX\_PATH\] = {0};
                          TCHAR szExt\[MAX\_PATH\] = {0};
                          
                          \_tsplitpath\_s(lpszPath, NULL, NULL, NULL, NULL, szFilename, \_MAX\_FNAME, szExt, \_MAX\_EXT);
                          

                          JohnCz

                          J Offline
                          J Offline
                          jkirkerx
                          wrote on last edited by
                          #19

                          I implemented the PathFinderExtension from Dave's Suggestion, but your suggestion looks quite interesting. hmm. I didn't know about that function and how to implement it. The PathFinderExtension is working quite well now, but let me fix my errors first before making any more changes.

                          1 Reply Last reply
                          0
                          Reply
                          • Reply as topic
                          Log in to reply
                          • Oldest to Newest
                          • Newest to Oldest
                          • Most Votes


                          • Login

                          • Don't have an account? Register

                          • Login or register to search.
                          • First post
                            Last post
                          0
                          • Categories
                          • Recent
                          • Tags
                          • Popular
                          • World
                          • Users
                          • Groups