开发者

sizeof argv[1] not working

I'm really new to C and all I know is that the error is related to oldname and newname not be initialized

#include 开发者_开发技巧<stdio.h>

int main (int argc, char const *argv[])
{
    int result;
    int lengthOne;
    int lengthTwo;
    lengthOne = sizeof(argv[0]);
    lengthTwo= sizeof(argv[1]);

    char oldname[lengthOne] = argv[0];
    char newname[lengthOne] = argv[1];

    result = rename(oldname, newname);

    if (result == 0) {
        puts "File renamed";
    } else {
        perror "ERROR: Could not rename file";
    }

    return 0;
}

app.c: In function ‘main’:
app.c:11: error: variable-sized object may not be initialized
app.c:12: error: variable-sized object may not be initialized
app.c:17: error: expected ‘;’ before string constant
app.c:19: error: expected ‘;’ before string constant


lengthOne = sizeof(argv[0]);
lengthTwo= sizeof(argv[1]);

This gives you the size of a char*, not the length of the string. You meant strlen, not sizeof.

char oldname[lengthOne] = argv[0];
char newname[lengthOne] = argv[1];

You can't assign to arrays like that. You could strcpy them, but it's unnecessary here because you can just use pointers.

const char* oldname = argv[0];
const char* newname = argv[1]; // But verify that argc >= 2 first!

EDIT: Also, don't forget that argv[0] is the name of the program itself, and argv[1] is the first argument. If your intent was to write a mv-like program instead of a program that renames itself, you want argv[1] and argv[2].


You seem to not be understanding what pointers are in C. This is a very core concept that you need to understand to be able to use the language.

I would start with a tutorial on them. A guick google brings this up as the first result: http://pw1.netcom.com/~tjensen/ptr/pointers.htm


First, char x[length] = /* something */; only works for string literals (i.e. "string" or {'s', 't', 'r', 'i', 'n', 'g', '\0'} if you want to be masochistic).

Second, to call a function, use parenthesis. puts("Text"); and printf("Text\n");. They are not optional like they are in some languages.

Third, as a function parameter (even if it's a parameter to main()), an array type decays to a pointer. So your function signature is effectively int main(int argc, char **argv) (and I prefer to write it that way, personally, but it makes no difference). You can't take the sizeof an array that has decayed to a pointer because it's not an array anymore and has no associated information about it's size. To get the size, use strlen().

Fourth, use a size_t to store sizes. Using an int to store sizes is wrong - there's no guarantee that int is large enough to hold sizes, and you can't have a -5 sized object of any kind. size_t is an unsigned integral type included in the standard for precisely this purpose.

Lastly, if you need a object whose size depends on runtime conditions, you can't use an array. You have to use a pointer, and use malloc to create a block of memory of the correct size, and then use free to destroy it when you're done. EDIT: Or just assign argv[0] to the pointer. argv is guaranteed in the standard to be writable, so you can edit it (just try to avoid appending anything).


sizeof is a compile-time check... the sizeof any argv element will be the number of bytes in a pointer-to-char. It has nothing to do with the run-time length of the text that pointer may address: strlen() returns that. But, C doesn't let you create dynamically (i.e. runtime) sized arrays. And even then you can't copy a string into another string with =... it requires a call to strcpy(dest, src). To make it work, obviously the easiest thing is:

result = rename(argv[0], argv[1])

But, I appreciate you're trying to learn how to copy the values into your own buffer. To do so, you need to dynamically create a sufficiently large buffer (memory-allocate or malloc), string-copy it, use it then free it. Several of these requirements are satisfied by the strdup() function:

const char* p_old_name = strdup(argv[0]);
const char* p_new_name = strdup(argv[1]);
rename(p_old_name, p_new_name);
free(p_old_name);
free(p_new_name);

Alternatively, you can statically specify a maximum size for the two strings (dangerous if you get it wrong - strncpy() can provide a more safety but a mistake may still prevent your program working with some long-but-valid paths):

#include <linux/limit.h>   // or wherever you can find PATH_MAX or similar
...

char old_name[PATH_MAX];
char new_name[PATH_MAX];
strcpy(old_name, argv[0]);
strcpy(new_name, argv[1]);
rename(old_name, new_name);

Note: as argv[0] is the program name, this program changes it's own executable name to whatever the second argument is. If you want it to change another file's name, then you should use argv[0] and argv[1].


sizeof() returns the size of the type - ie the size of a pointer (probably 32bits) or a char (8bits)
To get the length of a string you need strlen()

Additionally in ansi C you can't create an array with a variable for the size. You can in the new C standard or for now you can use malloc() to create an array


argv is of the type char*[], i.e., an array of pointers to char. Thus, any first level element will simply be a char* and, as such, sizeof(argv[i]) will always return the native pointer size. You need to use strlen or some equivalent function to get the length of the string.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜