2

I don't know the title correctly addresses my problem or not. So, I will just go with it. Here is the problem, I have to input a char array of a file path (in Windows) containing lots of backslashes in it, eg. "C:\myfile.txt" and return an unsigned char array of C-style file paths, eg. "C:\myfile.txt".

I tried to write a function.

unsigned char* parse_file_path(char *path);
{
   unsigned char p[60];
    int i,j;
    int len = strlen(path);
    for(i=0,j=0; i<len; i++, j++)
    {
        char ch = path[i];
        if(ch==27)
        {

            p[j++]='\\';
            p[j]='\\';
        }
        else
            p[j] = path[i];
    }
    p[j]='\0';
    return p;
}

The weird thing (for me) I am encountering is, here path contains only one backslash '\'. In order to get one backslash, I have to put '\' in path. This is not possible, cause path cannot contain '\'. When I call it like this parse_file_path("t\es\t \it), it returns t←s it. But parse_file_path("t\\es\\t \\it") returns t\es\t \it.

How can I accomplish my task? Thanks in advance.

muntasir2000
  • 204
  • 1
  • 3
  • 11
  • The C language specification states that to get a single backslash in a literal string, you have to escape it. – Some programmer dude Jul 02 '13 at 11:30
  • You seem to expect backslashes in the input to be escaped by an actual escape (ASCII 27), that is probably not correct. – unwind Jul 02 '13 at 11:44
  • @JoachimPileborg The string already contains some single escaped backslashes somehow. How can I make each single backslash double? – muntasir2000 Jul 02 '13 at 12:30
  • 1
    No, the string literal `"t\es\t \it"` does *not* contain any backslashes, because the compiler checks for those during compilation and replaces e.g. `\t` in the string with a tab. For escape codes that doesn't exist (like `\i` in your string) the compiler will give you a warning, and remove the backslash. It only have backslashes in the file, not after the code passed through the compiler. – Some programmer dude Jul 02 '13 at 12:41
  • Possible duplicate of [How do i print escape characters as characters?](http://stackoverflow.com/questions/6684976/how-do-i-print-escape-characters-as-characters) – jww Dec 22 '14 at 07:55

1 Answers1

4

If I can just mention another problem with your code.

You are returning a local variable (your unsigned char p). This is undefined behavior. Consider declaring a char* p that you assign memory to dynamically using malloc and then returning p as you do. E.g. something like:

char* p = malloc(60);

A common practice is to use sizeof when allocating memory with malloc but here I've passed 60 directly as the C standard guarantees that a char will be 1 byte on all platforms.

But you have to free the memory assigned with malloc.

Or alternatively, you can change the function to take a buffer as an input argument that it then writes to. That way you can pass a normal array where you would call this function.

Regarding your slashes issue, here:

p[j++]='\\';
p[j]='\\';

Position j in p will be changed to \\, then j will be incremented and at the very next line you do the same for the succeeding char position. Are you sure you want the two assignments?

By the way if you are inputting the path from the command line, the escaping will be taken care of for you. E.g. consider the following code:

#include <stdio.h>
#include <string.h> /* for strlen */
#include <stdlib.h> /* for exit */

int main() 
{
    char path[60];

    fgets(path, 60, stdin); /* get a maximum of 60 characters from the standard input and store them in path */

    path[strlen(path) - 1] = '\0'; /* replace newline character with null terminator */

    FILE* handle = fopen(path, "r");

    if (!handle)
    {
        printf("There was a problem opening the file\n");
        exit(1); /* file doesn't exist, let's quite with a status code of 1 */
    }

    printf("Should be good!\n");

    /* work with the file */

    fclose(handle);

    return 0; /* all cool */
}

And then you run it and input something like:

C:\cygwin\home\myaccount\main.c

It should print 'Should be good!' (provided the file does exist, you can also test with 'C:\').

At least on Windows 7 with cygwin this is what I get. No need for any escapes as this is handled for you.

Nobilis
  • 7,310
  • 1
  • 33
  • 67
  • May be you can add these things in your post above: Along with the `free`, make the p point to `NULL` or it will be a dangling pointer –  Jul 02 '13 at 11:37
  • 1
    +1, but `char *p = malloc(60);` is sufficient enough, sizeof(char) is guaranteed to be 1 byte – David Ranieri Jul 02 '13 at 11:48
  • @DavidRF Thanks, I'll update my answer and I'll explain why there's no need for `sizeof` just thought that this may be a little less confusing, but a bad habit nevertheless :) – Nobilis Jul 02 '13 at 11:51
  • @Nobilis Sorry if I couldn't make my question clear. Think of this, you input a file path in the console and want it to open in the program. As far as I know, you have to modify the actual path to use it with fopen or something like this. Like if you enter `C:\myfile.txt` then in `fopen`, you have to use `C:\\myfile.txt`. How would you do it? That's exactly what I'm trying to do. Thanks – muntasir2000 Jul 02 '13 at 12:15
  • @muntasir2000 See my post edit, this is tested on Windows 7 with cygwin, I was able to open successfully the file after passing it the correct path. No escaping necessary. Can you please try it and let me know what results you got? – Nobilis Jul 02 '13 at 12:32
  • @Nobilis It worked! Thanks a lot. I think the problem was, I was using string literals, not variables. So, the compiler was escaping the escape characters and gave me a lot of troubles. If I use variable, this would't occur. And that's what I want in my real program. So, the problem is solved. Thanks again. – muntasir2000 Jul 02 '13 at 12:43
  • @muntasir2000 You're very welcome, I'm glad this works for you :) – Nobilis Jul 02 '13 at 12:46