将argv[]中的字符串赋值给char数组

5

我有以下代码,它从命令行读取文件名并打开此文件:

#include <stdio.h>
#include <stdlib.h>
int main(int argc, char **argv){
    FILE *datei;
    char filename[255];

    //filename = argv[1];
    //datei=fopen(filename, "r");
    datei=fopen(argv[1], "r");
    if(datei != NULL)
        printf("File opened");
    else{
        printf("Fehler beim öffnen von %s\n", filename);
        return EXIT_FAILURE;
    }
    return EXIT_SUCCESS;
}

这个例子能够工作,但是我想从命令行写入字符串到字符数组,并将该字符数组传递给fopen(),但我得到了编译器错误Error: assignment to expression with array type filename = argv[1];。这个错误意味着什么?我该如何解决这个问题?

使用 strcpy(filename, argv[1]); - R Sahu
可能是重复的问题:无法将数组分配给另一个数组 - R Sahu
在“文件已打开”消息的末尾添加一个 \n。使用大括号将此指令括起来,以保持与 else 子句的一致性。 - chqrlie
3
使用strncpy(filename, argv[1], sizeof filename);argv[1]的内容复制到filename中,复制长度不超过filename的大小。 - harper
1个回答

11

你必须将字符串复制到字符数组中,这不能通过简单的赋值完成。

简单的答案是strcpy(filename, argv[1]);

但是这种方法存在一个很大的问题:命令行参数可能比filename数组更长,导致缓冲区溢出。

因此,正确的答案是:

if (argc < 2) {
    printf("missing filename\n");
    exit(1);
}
if (strlen(argv[1]) >= sizeof(filename)) {
    printf("filename too long: %s\n", argv[1]);
    exit(1);
}
strcpy(filename, argv[1]);
...

您可能希望将错误消息输出到stderr。 另外,您可能希望选择英语或德语,但不要同时使用它们;-)

甚至更简单的解决方案是在char *filename中仅保留指针argv [1]的副本。除非您自己修改它(这是一个非常糟糕的想法),否则其内容在程序执行期间不会改变。

这是一个修改后的版本:

#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(int argc, char *argv[]) {
    FILE *datei;
    char *filename;

    if (argc < 2) {
        fprintf(stderr, "Fehlendes Dateiname-Befehlszeilenargument\n");
        return EXIT_FAILURE;
    }
    filename = argv[1];
    datei = fopen(filename, "r");
    if (datei != NULL) {
        printf("Datei erfolgreich geöffnet\n");
    } else {
        fprintf(stderr, "Fehler beim öffnen von %s: %s\n",
                filename, strerror(errno));
        return EXIT_FAILURE;
    }
    // ...
    fclose(datei);
    return EXIT_SUCCESS;
}

1
一个更简单的解决方案是只需在 char *filename 中保留指针 argv[1] 的副本。除非你自己修改它,这是非常糟糕的想法,否则它的内容在程序执行期间不会改变。 - chqrlie
只是对@chqrlie的优秀建议进行澄清 - 代码应该如下所示:const char *filename = argv[1]; - S3DEV

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接