1

I did this code to check if a given filename is ".jpg" and if yes, change it to ".png":

#include <errno.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <dirent.h>
#include <stdio.h>


char newname[2000];

customRename(char *name) {
    int i = strlen(name), 
    answer;

    memset(newname, '\0', sizeof(newname));
    strcpy(newname, name);

    if ((name[i-1] == 'g') && (name[i-2] == 'p') && (name[i-3] == 'j') && (name[i-4] == '.')) {
        newname[i-2] = 'n';
        newname[i-3] = 'p';
        answer = rename(name, newname);
        if (answer == -1) { 
            fprintf(stderr, "%s -> %s: %s\n", name, newname, strerror(errno)); 
        } else {
            printf("%i: ", answer);
            puts(newname);
        }
    }
}

void listdir(const char *name, int level)
{
    DIR *dir;
    struct dirent *entry;

    struct stat s;

    if (!(dir = opendir(name)))
        return;
    if (!(entry = readdir(dir)))
        return;

    do {
        if (S_ISDIR(s.st_mode)) {
            char path[1024];
            int len = snprintf(path, sizeof(path)-1, "%s/%s", name, entry->d_name);
            path[len] = 0;
            if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0) {
                continue;
            }
            //printf("%*s[%s]\n", level*2, "", entry->d_name);
            listdir(path, level + 1);
        }
        else {
            //printf("%*s- %s\n", level*2, "", entry->d_name);
            customRename(entry->d_name);
        }
    } while (entry = readdir(dir));
    closedir(dir);
}




int main() {

    printf("Root path:\n");

    char rootpath[2000];
    gets(rootpath);
    listdir(rootpath, 0);

    return 0;
}

But, for some unknown reason it prints:

-1: LF1603300450121ARG.png

The -1 means something was wrong... but what is wrong?

Thanks in advance.

Washington Guedes
  • 4,254
  • 3
  • 30
  • 56
  • do you have permission to rename files in that directory? check `errno` to get the actual reason for failure. and note that this does NOT turn that file from a jpg into a png. it just changes the name, and can make the picture appear "corrupt" to anything expecting an actual .png picture when loading the file. – Marc B Jun 07 '16 at 19:32
  • That function fails horribly if you pass it a name shorter than 4 characters or longer than `INT_MAX`. – melpomene Jun 07 '16 at 19:35
  • 2
    As @MarcB said, `if (answer == -1) { fprintf(stderr, "%s -> %s: %s\n", name, newname, strerror(errno)); }` – melpomene Jun 07 '16 at 19:36
  • I tried manually renaming and it worked, then I think permission is not the cause. – Washington Guedes Jun 07 '16 at 19:38
  • I tried that code, but in Dev-C++ it shows: `[Error] 'errno' undeclared (first use in this function)`. How can I declare it? Or is it from some include library? – Washington Guedes Jun 07 '16 at 19:40
  • 2
    `#include ` – user3386109 Jun 07 '16 at 19:44
  • 1
    In that case please post the [Minimal, Complete, and Verifiable example](http://stackoverflow.com/help/mcve) which shows what you have tried (including the error test suggested) that can be copy/paste and replicated. But even then, unless the file was saved with the wrong `.suffix` in the first place you'll render the file unreadable. – Weather Vane Jun 07 '16 at 19:45
  • Strange, it shows `No such file or directory`. I will double check – Washington Guedes Jun 07 '16 at 19:48
  • @WeatherVane. I just posted the relevant part, but I updated with the full code – Washington Guedes Jun 07 '16 at 19:49
  • 3
    I'm going to guess the file you are trying to rename is in a subdirectory, and since you only pass the filename you're looking for it in the working directory and not where it actually is. – Retired Ninja Jun 07 '16 at 19:52
  • 1
    `s` is uninitialized. – melpomene Jun 07 '16 at 19:53
  • 1
    Does `name` include the full path name? If it is `No such file or directory` your recursion may not be the "current directory" – Weather Vane Jun 07 '16 at 19:58
  • @melpomene. I took `listdir` from another post. And initially it was `if (entry->d_type == DT_DIR) {` ... but it didn't work for me, then I put `s` there.... anyways, how can it be a problem? – Washington Guedes Jun 07 '16 at 19:58
  • This may help you: http://stackoverflow.com/questions/1542763/what-is-the-correct-way-to-use-the-stat-function-to-test-if-a-dirent-is-a-dire/1542780#1542780 – Retired Ninja Jun 07 '16 at 19:59

1 Answers1

0
int n = strlen(name);
if ( n > 4 ) {
   if ( strcmp(&name[n-4], ".jpg") == 0 ) {
      strcpy( &name[n-3], "png";
   }
}
FredK
  • 4,094
  • 1
  • 9
  • 11
  • While this code snippet may solve the question, [including an explanation](https://meta.stackexchange.com/questions/114762/explaining-entirely-code-based-answers) really helps to improve the quality of your post. Remember that you are answering the question for readers in the future, and those people might not know the reasons for your code suggestion. Please also try not to crowd your code with explanatory comments, this reduces the readability of both the code and the explanations! – Box Box Box Box Jun 08 '16 at 03:43