LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Programming (https://www.linuxquestions.org/questions/programming-9/)
-   -   C: non elegant way to convert filename to unix... :( (https://www.linuxquestions.org/questions/programming-9/c-non-elegant-way-to-convert-filename-to-unix-4175453535/)

Xeratul 03-10-2013 03:26 PM

C: non elegant way to convert filename to unix... :(
 
Hello,

In C programming language, this code below is working well. It is fine.
It allows to convert. I need sthg compatible and Posix. So it is posix ;) :)
"file with spaces.txt" to "file\ with\ spaces.txt"
It does convert the string (array of chars) to *nix.

However this code is really not elegant at all.

Would you know
Qu(1) how to avoid:
Code:

        j = snprintf( charo, 5 , "%c", aoption[i]);
The above use of snprintf is a sort of trick to avoid the error which occurs with :
Code:

strncat( buffer , aoption[i] , PATH_MAX - strlen(buffer) - 1);
because aoption is a pointer.
I would rather use strncat but no idea how.

snprintf is not sexy, and it is not a reliable work-around.


The use of strncat is more reliable.
How to use strncat with this line above?


Qu(2)
The whole code is not elegant and it may crash depending
on the file names which are passed to aoption.




Code:

char *filename_c_to_unix( char aoption[PATH_MAX] ){

        char buffer[PATH_MAX];
        char charo[PATH_MAX];
        int i, chd, cx , j ;
        strncpy( buffer, "" , PATH_MAX);
        werase( stdscr);

        for ( i=0; ( i <= strlen( aoption ) ) ; i++ )
        {
                //        printw(  ">%c ", aoption[i]);
                //        refresh();
                // strncat( buffer , "-" , PATH_MAX - strlen(buffer) - 1);
                j = snprintf( charo, 5 , "%c", aoption[i]);
                switch ( charo[0] ) {
                        case '&':
                                strncat( buffer , "\\" , PATH_MAX - strlen(buffer) - 1);
                                strncat( buffer , "&" , PATH_MAX - strlen(buffer) - 1);
                                break;



                        case '\'':
                                strncat( buffer , "\\'" , PATH_MAX - strlen(buffer) - 1);
                                break;



                        case ' ':
                                strncat( buffer , "\\ " , PATH_MAX - strlen(buffer) - 1);
                                break;

                        default:
                                strncat( buffer , charo , PATH_MAX - strlen(buffer) - 1);
                                break;
                }

        }
        size_t len = strlen(buffer);
        char *r = malloc(len+1);
        return r ? memcpy(r, buffer, len+1) : NULL;
}


The most important question to me is to learn how to use
strncat with converting/using a pointer to my regular array of chars (knowing that I all the time use a regular array of chars). Would you have a better line for question (1)?

This question/issue qu(1) is the most important to me.

Looking forward to reading you !
Many thanks

NevemTeve 03-10-2013 04:04 PM

I don't really understand your code, but please, please, don't put strlen into cycle-condition, it is extremely in-efficient.

Code:

old: j = snprintf( charo, 5 , "%c", aoption[i]);
new: charo[0]= aoption[i]; charo[1]= 0; j= 1;

PS: What is the transformation you're trying to perform? Please explain in words.

chrism01 03-10-2013 11:27 PM

Normally at the cli you'd use eg sed to convert spaces to underscores in a string; better than '\ '.
C has a regex lib, so I'd use that.

mina86 03-11-2013 08:03 AM

Use a char pointer to iterate over both the file name and the output buffer, as in:
Code:

char *filename_escape(const char *path){
    char buffer[PATH_MAX], *out = buffer;
    const char *in = path;

#define PUTCHAR(ch) do { \
    *out = ch; \
    if (++out == buffer + sizeof buffer) \
        return NULL;
} while (0)

    for (; *in; ++in) {
        PUTCHAR(*in);
        /* do your magic here */
    }

#undef PUTCHAR

    /* ... */
}

You might be better off having a dynamic buffer though, since path is not limited by PATH_MAX.

Sergei Steshenko 03-11-2013 05:24 PM

Quote:

Originally Posted by Xeratul (Post 4908715)
...
The whole code is not elegant
...

If you are not sure the wheels should be reinvented, start from the following:

http://freecode.com/projects/bstring
http://freecode.com/projects/vstr
http://freecode.com/projects/str
http://freecode.com/projects/libstrvar
http://freecode.com/projects/libsbuf
http://freecode.com/projects/libtext
http://www.and.org/ustr/
http://libhx.sourceforge.net/
http://www.theiling.de/projects/erwin.html
http://www.koanlogic.com/libu/api/html/index.html
http://judy.sourceforge.net/ - I once got truly interested in this.


All times are GMT -5. The time now is 10:40 AM.