【问题标题】:C - scanf() and then getenv()C - scanf() 然后 getenv()
【发布时间】:2016-05-09 15:41:43
【问题描述】:

我在询问用户他想知道哪个环境变量,然后我用 scanf 扫描它。但这对我不起作用。这是我的代码:

    #include <unistd.h>
    #include <stdio.h>
    #include <stdlib.h>


    int main(int argc, char *argv[]){

        char *value;
        char input;

        printf("Which variable do you want?\n");
        scanf("%s", input);

        value = getenv(input);

        printf("%s", value);

    }

编译器说:

“不允许在类型“const char*”和“char”之间分配函数参数”

所以我尝试将输入变量更改为:char const *input

现在没有编译器错误,但是当我提交一个名称时,例如“USER”,我得到一个"Segmentation fault (core dumped)" 错误。

【问题讨论】:

  • char input; ... scanf("%s", input); --> input 不够大,无法存储用户文本输入。 (stackoverflow.com/q/37119782/2410359 的类似问题)
  • 在调用任何scanf() 系列函数时,1) 始终检查返回值(而不是参数值)以确保操作成功。 2) 使用“%s”输入转换说明符时,始终使用“最大长度”修饰符(比输入缓冲区的长度小一),这样用户就不会超出输入缓冲区(这将导致未定义的行为和可能导致段故障事件)。顺便说一句:当输入缓冲区只有 1 个字符长时,您希望如何读取字符串(NUL 终止的字符数组)?
  • 关于这一行:printf("%s", value); 输出将位于标准输出缓冲区中,直到程序退出,然后(并且只有那时)它才会实际显示在终端上。强烈建议使用:printf("%s\n", value);,因为 '\n'(换行符)会导致标准输出缓冲区立即显示在终端上。

标签: c environment-variables scanf getenv


【解决方案1】:

警告是因为这里

value = getenv(input);

您将char 传递给getenv(),它具有原型:

   char *getenv(const char *name);

input 定义为 char 数组,如:

    char input[256];

    printf("Which variable do you want?\n");
    scanf("%255s", input); //specify the width to avoid buffer overflow

或者,如果您认为 256 不足以满足您的目的,您可以使用动态内存分配(使用 malloc)。

【讨论】:

    【解决方案2】:

    当您定义 char *input; 时,您会满足编译器的要求,因为您的语法是有效的:调用 scanf("%s", input); 时,您是说您想要一个字符串,它应该放在 input 所在的任何位置。

    问题是input 还没有在任何地方(已初始化)...它指向的位置目前未定义;在使用任何指针之前,你必须让它指向一个有效的地方(并且大到足以容纳你打算放在那里的任何东西)。

    有几种方法可以解决这个问题,但也许最简单的方法是确定输入需要多大并声明一个字符数组,例如:char input[512];。请注意,这是有问题的,因为如果输入超出您的缓冲区,您将覆盖其他内存......但这应该让您现在继续前进。

    【讨论】:

      【解决方案3】:

      char 是单个char
      char *input 声明了一个变量,该变量包含一个指向字符的指针,但没有存储数据的内存。在 C 中,这是正确的行为。但是,sscanf 期望您实际上传递一个指向已分配内存的指针(请考虑该函数不返回任何指针,因此它没有机会为您分配内存)。

      所以在声明和使用之间,请使用malloc分配内存。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-06-04
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多