【问题标题】:Confused about char and char * and scanning in words对 char 和 char * 感到困惑并用单词扫描
【发布时间】:2018-11-25 21:27:49
【问题描述】:

我编写了这个简单的代码,它可以扫描一些数字和单词。但是,我很困惑,因为 char 总是给我一个错误。它有什么问题?

int main(int argc, char *argv[]) {
    int val_pos, incr_val, max_val;
    char *file_name;
    char *new_name;

    if (argc == 6) {

        val_pos = atoi(argv[1]);
        incr_val = atoi(argv[2]);
        max_val = atoi(argv[3]);
        file_name = argv[4];
        new_name = argv[5];

    } else {

        printf("Command usage: %s <val_pos> <increment val> <max val> <file_name> <new name>\n", argv[0]);

        printf("What is the position you want to change? Enter your number\n");
        printf("X = 0 | Y = 1 | Z = 2\n");
        scanf("%d", &val_pos);

        printf("What is the increment value?\n");
        scanf("%d", &incr_val);

        printf("What is the max value/value we should terminate at?\n");
        scanf("%d", &max_val);

        printf("What is the pose file called?\n");
        scanf("%s", &file_name);

        printf("What should we call the newly generated files?\n");
        scanf("%s", &new_name);
    }
}

【问题讨论】:

  • “字符总是给你一个错误”是什么意思?
  • file_namenew_name 最初是 未初始化的指针,用于分配 argv[4]argv[5] 的地址。当您尝试scanf("%s", &amp;file_name); 时,您正在回信给argv[4]。虽然 C 标准要求 argv 值是可修改的——但您不能超出原始值的范围进行写入。因此,如果您输入的名称比原始名称长 - 您可能会调用 Undefined Behavior 覆盖原始 nul-terminating 字符并在原始分配范围之外写入争论。 &amp; 也是错误的。
  • @DavidC.Rankin 那么如何扫描文件名?
  • 声明char file_name[512] = "";为你的新名字创建自动存储,然后scanf("%s", file_name);(不是'&amp;'file_name已经是一个指针)根据需要调整大小。
  • @ZoeyMalkov:也许从阅读scanf()'s documentation开始?

标签: c if-statement char int scanf


【解决方案1】:

这里

char *file_name;
char *new_name;

file_namenew_name 是 char 指针,它们没有被初始化,所以它们不指向任何有效的内存位置;如果你喜欢

scanf("%s", &file_name);
scanf("%s", &new_name);

这会导致分段错误,因为您没有为 file_namenew_name 分配任何内存。

正确的做法是先为file_namenew_name分配内存,然后扫描数据

char *file_name = malloc(F_SIZE); /* define F_SIZE */
char *new_name = malloc(N_SIZE); /* define the N_SIZE as how much size you want */

现在像这样扫描数据

scanf("%s",file_name); /* & is not required */
scanf("%s",new_name);

一旦完成file_namenew_name,不要忘记通过调用free() 来释放动态内存以避免内存泄漏,例如

free(file_name);
free(new_name);

旁注:你的编译器可能会警告你

scanf("%s", &file_name); /* & is not needed */

喜欢

格式“%s”需要“char *”类型的参数,但参数 2 有 输入‘char **’

还有关于

char *file_name; /* uninitialized */

‘file_name’可以在这个函数中使用未初始化的

如果您使用正确的标志编译代码。我建议你用

编译任何基本的 C 代码
gcc -Wall -Wstrict-prototypes -Werror test.c

它对你有很大帮助,因为有时人们习惯于从字面上接受警告,但以后会花费更多。所以最好通过使用-Werror 编译将警告转换为错误并继续。

【讨论】:

  • free(file_name);free(new_name); 给我错误。 runtime error - illegal array, pointer or other operation
  • 如果argc==6 表示命令行输入并且在file_name = argv[4]; 之后,此file_name 不保留您之前分配的动态内存,并且此free(filke_name) 尝试free 无效内存,导致运行-时间错误。将file_name = argv[4]; 替换为strcpy(file_name, argv[4]);
  • 类似new_name = argv[5]; --> strcpy(new_name, argv[5]);
  • 查看我对这个问题的评论,关于使用%s 输入格式说明符调用scanf()
【解决方案2】:

对于这些值:

printf("What is the pose file called?\n");
scanf("%s", &file_name);

printf("What should we call the newly generated files?\n");
scanf("%s", &new_name);

你已经声明了指针

char *file_name;
char *new_name;

所以,首先,变量已经是指针,所以不需要使用&amp;操作符的地址:

printf("What is the pose file called?\n");
scanf("%s", file_name);

printf("What should we call the newly generated files?\n");
scanf("%s", new_name);

其次,你没有分配任何内存来保存你的字符串,例如:

file_name = malloc(50);      // choose appropriate sizes
// check for NULL
new_name = malloc(50);
// check for NULL

【讨论】:

    【解决方案3】:

    改变

    scanf("%s", &file_name);
    
    scanf("%s", &new_name);
    

    scanf("%s", file_name);
    
    scanf("%s", new_name);
    

    您必须在向 file_namenew_name 写入数据之前为其分配内存。

    而且你最好在每个 scanf() 之后附加 getchar() 以获取由 ENTER 键生成的 '\n'。

    【讨论】:

      猜你喜欢
      • 2021-12-15
      • 1970-01-01
      • 2011-10-17
      • 2021-01-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-10-18
      • 2010-10-17
      相关资源
      最近更新 更多