I have been trying to write a sample code block to remove multiple backward or forward slashes from a path (e.g. //a//b
should be /a/b
; on Windows, c:\\a\\b\\\c
should be c:\a\b\c
).
I am assuming that:
- Code must be platform independent
- Should work in all cases (or report a proper error)
- It should be readable and maintainable
- It shouldn't be over-complex and shouldn't have errors
Please provide point-wise comments for the following code sample (you may ignore main
and assume that path
is not NULL
- it is just for demonstration purposes). Or else you may provide a better mechanism for the same.
void
die( int error_code, char* message )
{
fprintf( stderr, message );
exit( error_code );
}
/*Following function removes duplicate slashes from a given path*/
char*
validate_path ( char* path )
{
char* path_copy = path;
int dup_flag = 0;
char* path_without_dup_slash = (char*)malloc(strlen(path)+1);
if ( path_without_dup_slash == NULL ) {
die( EXIT_FAILURE, "Failed to allocate memory for processing path.");
}
char* copy_pwds = path_without_dup_slash;
/* Travel through given path */
while( *path_copy != '\0' ) {
/* If there is '\' or '/' then copy a single '/'
* , ignore others until a real char comes */
if ( (( *path_copy == '\\') || ( *path_copy == '/' )) &&
(dup_flag == 0) ) {
*copy_pwds = *path_copy;
dup_flag = 1;
copy_pwds++;
}else if (( *path_copy != '\\') && ( *path_copy != '/' )) {
*copy_pwds = *path_copy;
dup_flag = 0;
copy_pwds++;
}
path_copy++;
}
*copy_pwds = '\0';
path_without_dup_slash = (char *)realloc( path_without_dup_slash,
strlen( path_without_dup_slash ) + 1 );
if ( path_without_dup_slash == NULL ) {
die( EXIT_FAILURE, "Failed to allocate memory for processing path.");
}
return path_without_dup_slash;
}
/*You please ignore the parts written in main - it is just for demonstration purpose. */
int
main( void ) {
char* bad_path_1 = malloc(100);
char* bad_path_2 = malloc(100);
char* p1 = bad_path_1;
char* p2 = bad_path_2;
char* path_1;
char* path_2;
bad_path_1 = "//a//b//c";
bad_path_2 = "c:\\\\a\\\\b\\\\c";
path_1 = validate_path(bad_path_1);
printf( "Good path:%s Bad Path:%s\n",path_1,bad_path_1);
path_2 = validate_path(bad_path_2);
printf( "Good path:%s Bad Path:%s\n",path_2,bad_path_2);
free(path_1);
free(path_2);
free(p1);
free(p2);
return EXIT_SUCCESS;
}
/a///b
? \$\endgroup\$ – Simon Kirsten Oct 22 '16 at 16:55/a/b
. Note that I'm not OP. \$\endgroup\$ – Incomputable Oct 22 '16 at 17:06\\ComputerName\Share\blah\zzx.txt
? \$\endgroup\$ – 200_success Oct 22 '16 at 20:01///foo/bar
is the same as (and can be canonicalized to)/foo/bar
, and/foo//bar
is the same as (and can be canonicalized to)/foo/bar
, but//foo/bar
,//foo//bar
, etc. can not be canonicalized. Their meaning is implementation-defined, and the "extra" slashes are semantically meaningful. \$\endgroup\$ – Jörg W Mittag Oct 23 '16 at 2:11/a/b/\\\\c
\$\endgroup\$ – Shivendra Mishra Oct 23 '16 at 8:50