【问题标题】:gcc error when writing string to char array将字符串写入char数组时出现gcc错误
【发布时间】:2016-10-09 19:45:25
【问题描述】:

当尝试将字符串分配给先前定义的char flightNumber[MAX] 时,我遇到了 error: assignment makes integer from pointer without a cast [-Werror] 这对我来说很奇怪,因为我没有使用指针,而且我相信我使用的是正确的强制转换类型,即char 而不是int。问题是,分配给flightNumber[MAX] 的字符串需要根据用户输入的内容进行更改。

main()的相关代码粘贴在下面

flightMenu();
scanf( "%d", &choice );
    while ( choice < 1 || choice > 3 ) {
        printf( "That is not a valid flight option!" );
        flightMenu();
        scanf( "%d", &choice );
    }

char name[MAX];
char flightNumber[MAX];

printf( "Enter your first name: ");
scanf( "%s", &name[MAX] );

if ( choice == 1 ) {
    flightNumber[MAX] = "MIA1050";
    seatReservation( flight1 );
}

else if ( choice == 2 ) {
    flightNumber[MAX] = "BNA1050";
    seatReservation( flight2 );
}
else if ( choice == 3 ) {
    flightNumber[MAX] = "LAS1050";
    seatReservation( flight3 );
}

看起来其他人也有类似的问题,但我不知道如何使用 strcpy 或指针之类的东西。为菜鸟问题和糟糕的格式道歉,但我似乎没有解决这个错误,我猜我忽略了一个非常简单的问题......

【问题讨论】:

  • 您需要使用strcpystrncpy。像你正在做的赋值(使用 =)不会在 C 中复制字符串。
  • 除了strcpy,还有其他方法吗?不幸的是,对于这个作业,我们只被允许使用 stdio.hstdlib.htime.h C 库。
  • 分配给flightNumber[MAX] 完全超出了数组的范围。也是char;您不能将字符串分配给char。您使用strcpy() 来“分配”字符串,并且从目标数组的开头而不是结尾开始。
  • 如果你真的必须复制这些字符串文字(我不确定),那么你可以滚动你自己的 strcpy 版本,它只是一个简单的循环

标签: c arrays gcc


【解决方案1】:

要复制字符串,您应该使用特殊功能,例如:

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

int main()
{
   char source[1000], destination[1000];

   printf("Input a string\n");
   gets(source);

   strcpy(destination, source);

   printf("Source string:      \"%s\"\n", source);
   printf("Destination string: \"%s\"\n", destination);

   return 0;
}

http://www.programmingsimplified.com/c/source-code/c-program-copy-strings

【讨论】:

  • 现在这是一个可以由用户触发的缓冲区溢出的好例子,千万不要在实际程序中编写这样的代码
【解决方案2】:

C 库函数

char *strcpy(char *dest, const char *src) 

将src指向的字符串复制到dest。

所以用它代替 flightNumber[MAX] = "anything";

更详细一点:strcpy() 函数在 string.h 头文件中定义。

【讨论】:

    【解决方案3】:

    其他答案为您提供了如何复制字符串的不错选择,但要回答有关为什么会收到错误error: assignment makes integer from pointer without a cast [-Werror] 的问题:

    char flightNumber[MAX]; 是 char 数组的声明,但声明 flightNumber[MAX] = "MIA1050"; 的意思是“将 "MIA1050" 分配给 flightnumber 中索引 MAX 处的元素”。

    这是错误的,有两个不同的原因:

    1. 您正在尝试将字符串文字分配给字符变量(flightNumber 的元素是 chars。这是编译器抱怨的类型不匹配:字符串文字的类型是 const char*,并且您将其分配给 char 类型的变量,因此隐式地将指针转换为整数类型 (char)。
    2. 超出范围:flightNumber 中的最大索引是 MAX-1,因为 C 数组的索引从零开始。

    要使用数组,只需使用其名称(即flightNumber),而不是声明中的名称+大小(即flightNumber[MAX])。 现在,正如其他答案指出的那样,分配 flightNumber = "MIA1050" 不会做你想做的事,所以你需要使用例如 strncpy

    顺便说一句,请首选strncpy(它带有一个长度参数)而不是不太安全的strcpy作为默认值,以减少缓冲区溢出的风险。

    【讨论】:

    • 感谢关于 C 数组索引的提醒,我自己应该已经明白了。我会研究strncpy,但出于好奇,它是否适用于用户定义的字符串输入,例如char name[MAX]
    • @Likasumboode,是的,strcpy(char* dest, const char *src) 只是将一个以 src 开头的空终止字符串复制到 dest 指向的内存中。只要dest 指向的数组足够大(而不是const),它就适用于任何char[]。至于strncpy,它的工作原理相同,但最多复制n 个字符。您需要注意的一件事是,如果strlen(src) &gt; ndest 指向的字符串将不会以空值结尾。要检查src 的字符串长度,您可以使用strnlen()
    【解决方案4】:

    赋值flightnumber[MAX] = "MIA1050";为例,尝试将文本字符串"MIA1050"的内存地址(而不是字符串本身的字符)赋值给MAX-flightnumber中的第一个元素位置数组(因为数组编号从 0 开始,这也将超过数组的末尾,因为数组中的最后一个元素位于索引 MAX-1)。由于数组是 chars,它是一个整数类型(不要与 int 混淆,它也是一个整数类型,尽管通常具有不同的大小),这也是尝试将内存地址分配给标记为包含整数类型的位置,编译器会将其视为您看到的错误。

    要解决错误并实现将字符串“分配”到存储位置的功能,两种主要方法是将实际字符串字符复制到缓冲区或传递字符串文字的地址(这两种方法都是以上对您的问题的回答已经记下)。对于前者,诸如strcpy 之类的标准库工具通常是将字符串从一个位置(例如字符串文字的位置)复制到另一个位置(例如您的示例中的flightnumber 之类的缓冲区)的有效解决方案。对于后一种方法,您可以创建 char * 类型的变量而不是 char 数组,在这种情况下,您可以将字符串文字分配给该变量,因为尝试分配字符的地址是正确的因为变量将是正确的类型(指向-char)。

    哪种方法更可取取决于特定的应用程序以及字符串文字的处理方式。但是,如果对字符串所做的唯一事情是打印出结果值或类似的内容,则第二种方法(存储指向文字的地址而不是复制实际字符的方法)可能比分配单个方法更可取address 通常在性能和内存存储方面比创建缓冲区和执行内存区域的副本更便宜(除非程序多次执行相同的任务,否则差异不会真正显着) .

    我也赞同这样的建议,即在深入了解 C 中的指针管理的基础知识之前,您至少应该将重点放在理解上,因为这对于有效使用该语言非常重要。注意 C 风格字符串的布局也可能是个好主意。

    【讨论】:

      【解决方案5】:

      flightNumber[MAX] 是一个字符数组。 (堆栈上大小为 MAX 的本地缓冲区),而您尝试分配的三个航班号是字符串文字。

      一个字符串字面量计算为一个 char 指针以便分配它。 (字符*)

      因此,你必须使用 char 指针而不是这个数组来分配字面量。

      但是,如果您真的想将字符串文字复制到可变缓冲区,则可以使用 strncpy()。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-11-01
        • 2020-09-14
        • 2013-08-31
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多