Extract base path from a pathname in C

后端 未结 8 1823
南笙
南笙 2020-12-30 14:21

Question

How do you extract the base path from pathname in C?

Are there any functions built into the C language or the C-Runtime L

8条回答
  •  别那么骄傲
    2020-12-30 15:19

    I think the best solution on Windows is to use _splitpath as was suggested, to use something like basename on Linux (more on that here).

    That said, since someone has already suggested implementing my own (and since I had already done it while I was waiting for an answer), here is what I came up with. It is not cross-platform and it does not check for /valid/ paths or expand short or relative path names.

    // Retrieves the pathpath from a pathname.
    //
    // Returns: SUCCESS if the basepath is present and successfully copied to the p_base_path buffer
    //          FAILURE_NULL_ARGUMENT if any arguments are NULL
    //          FAILURE_INVALID_ARGUMENTS if either buffer size is less than 1
    //          FAILURE_BUFFER_TOO_SMALL if the p_basepath buffer is too small
    //          FAILURE_INVALID_PATH if the p_pathname doesn't have a path (e.g. C:, calc.exe, ?qwa)
    //          FAILURE_API_CALL if there is an error from the underlying API calls
    int get_base_path_from_pathname( const char*  const p_pathname,
                                     size_t             pathname_size,
                                     char* const        p_basepath,
                                     size_t             basepath_size );
    
    int get_base_path_from_pathname( const char*  const p_pathname,
                                     size_t             pathname_size,
                                     char* const        p_basepath,
                                     size_t             basepath_size )
    {
      char*  p_end_of_path;
      size_t path_length;
      int    return_code;
    
      // Parameter Validation
      if( p_pathname == NULL || p_basepath == NULL ) { return FAILURE_NULL_ARGUMENT; }
      if( pathname_size < 1 || basepath_size < 1 ) { return FAILURE_INVALID_ARGUMENTS; }
    
      // Returns a pointer to the last occurrence of \ in p_pathname or NULL if it is not found
      p_end_of_path = strrchr( p_pathname, '\\' );
      if( p_end_of_path == NULL )
      {
        // There is no path part
        return FAILURE_INVALID_PATH;
      } 
      else 
      {
        path_length = (size_t)( p_end_of_path - p_pathname + 1 );
    
        // Do some sanity checks on the length
        if( path_length < 1 ) { return FAILURE_INVALID_PATH; }
        if( ( path_length + 1 ) > basepath_size ) { return FAILURE_BUFFER_TOO_SMALL; }
    
        // Copy the base path into the out variable
        if( strncpy( p_basepath, p_pathname, path_length ) != 0 ) { return FAILURE_API_CALL; }
        p_basepath[path_length] = '\0';
      }
    
      return SUCCESS;
    }
    

提交回复
热议问题