1

I am coding a program, that deletes all redundant / in the path of the file. In other words ///a/////b should become /a/b. I can delete all repeated /, but can't fully wrap my head about how to leave only one slash WITHOUT any standard function or indexation operation. Can someone fix my code, please?

#include <stdio.h>

//      ///a/////b
//      a/b/a
//      aa///b/a
void normalize_path(char *buf) {
    int k = 0, counter = 0;
    for (int i = 0; buf[i]; i++) {
        buf[i] = buf[i + k];

        if (buf[i] == '/') {
            ++counter;
            if (counter > 1) {
                --i;
                ++k;
            } else {
                ++k;
            }
        } else {
            counter = 0;
        }
    }
}



int main() {
    char path[100];
    scanf("%s", path);
    printf("String before the function: %s\n", path);
    normalize_path(path);
    printf("String after the function is used: %s\n", path);
    return 0;
}
EndOfTheGlory
  • 309
  • 3
  • 11
  • If on Linux, what about `/home/../etc/fstab` ? Should it be normalized to `/etc/fstab` ? Then read about [realpath(3)](https://man7.org/linux/man-pages/man3/realpath.3.html) and study the source of its implementation in [GNU libc](https://www.gnu.org/software/libc/) or in [musl libc](http://musl-libc.org/) – Basile Starynkevitch Jan 11 '21 at 09:18

4 Answers4

2

You can keep track if the previous character is slash, and add characters to the result if and only if at least either one of previous and current characters is not shash.

#include <stdio.h>

//      ///a/////b
//      a/b/a
//      aa///b/a
void normalize_path(char *buf) {
    char *in = buf, *out = buf;
    int prev_is_slash = 0;
    for (; *in != '\0'; in++) {
        if (!prev_is_slash || *in != '/') *(out++) = *in;
        prev_is_slash = *in == '/';
    }
    *out = '\0';
}

int main() {
    char path[100];
    scanf("%s", path);
    printf("String before the function: %s\n", path);
    normalize_path(path);
    printf("String after the function is used: %s\n", path);
    return 0;
}
MikeCAT
  • 73,922
  • 11
  • 45
  • 70
1

The logic is broken. In particular, index i should never decrease, as it corresponds to the read character.

Simpler and correct is to use two indices, one for reading i and one for writing k.


#include <stdio.h>

//      ///a/////b
//      a/b/a
//      aa///b/a
void normalize_path(char *buf) {
    int k = 0, counter = 0;
    if (buf[0] == '\0') return;
    for (int i = 0; buf[i]; i++) {
        if (buf[i] == '/') {
            ++counter;
            if (counter > 1) {
                continue;
            }
        } else {
            counter = 0;
        }
        buf[k] = buf[i];
        k++;
    }
    buf[k] = '\0';
}



int main() {
    char path[100];
    scanf("%s", path);
    printf("String before the function: %s\n", path);
    normalize_path(path);
    printf("String after the function is used: %s\n", path);
    return 0;
}
Damien
  • 4,809
  • 4
  • 15
  • 20
1

No standard functions and no indexing, use pointers:

char* normalize(char *s)
{
    char *src = s;
    char *dest = s;

    while ((*dest = *src)) {
        if (*dest == '/') {
            // skip repeated slashes
            while (*src=='/') {
                src++;
            }
            dest++;
        }
        else {
            src++;
            dest++;
        }
    }
    return s;
}
koder
  • 2,038
  • 7
  • 10
0

Use regular expressions (Regular expressions in C: examples?), a regex to remove double slashes is in remove duplicate forward slashes from the URL

In How to do regex string replacements in pure C? is a function like PHP str_replace

ralf htp
  • 9,149
  • 4
  • 22
  • 34
  • 1
    The reguration is "WITHOUT any standard function", so using non-standard external libraries is not banned! Nice idea! – MikeCAT Jan 11 '21 at 09:05