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.
  • 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

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

    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 1 Reply Last reply
    0
    • 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