You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C语言中字符串字面量赋值给char*报错E0513问题求助

字符串字面量赋值给char*的编译差异问题及解决

可正常运行的代码

#include <stdio.h>

struct student
{
    char* name;
};

struct student s[2];

void main()
{
    s[0].name = "jason";
    s[1] = s[0];

    printf("%s%s", s[0].name, s[1].name);

    s[1].name = "fedin";

    printf("%s%s", s[0].name, s[1].name);
}

编译报错的代码

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

struct item {
  char* itemName;
  int quantity;
  float price;
  float amount;
};

void readItem(item* const p) {
  printf("Please enter item name. \n");
  fgets(p->itemName, 50, stdin);
  for (int i = 0; i < strlen(p->itemName); i++)
  {
    if (p->itemName[i] == '\n') {
      p->itemName[i] = NULL;
    }
  }

  printf("Please enter the quantity. \n");
  scanf_s("%d", &p->quantity);

  printf("Please enter the price. \n");
  scanf_s("%f", &p->price);
}

void print(item* const p) {
  printf("Item Name: %s \n", p->itemName);
  printf("Quantity: %i \n", p->quantity);
  printf("Price: %.4f \n", p->price);

  p->amount = (p->quantity) * (p->price);
  printf("Amount: %.4f \n", p->amount);
}

int main(void) {
  struct item item1;

  item1.itemName = "SDfsd";

  item1.quantity = 0;
  item1.price = 0.0;
  item1.amount = 0.0;

  struct item* itemP = &item1;

  readItem(itemP);
  print(itemP);

  free(itemP->itemName);
  itemP->itemName = NULL;

  return 0;

}

编译错误信息

Error (active) E0513 a value of type "const char *" cannot be assigned to an entity of type "char *" Structure Pointers and Functions F:\Mohamed Taha\Codes\C Programming\C Programming For Beginners\vs\Structure Pointers and Functions\Structure Pointers and Functions\mian.cpp 41

原因分析

  1. 字符串字面量的本质:C标准规定,字符串字面量(如"jason")的类型为const char[],存储在程序的只读数据段,不允许被修改。
  2. 两段代码的编译差异:
    • 第一段代码仅对指针做赋值和读取操作,从未尝试修改字符串字面量的内容。旧版C标准(C89)允许const char*隐式转换为char*,多数编译器为兼容旧代码,在未开启严格编译选项时不会报错。
    • 第二段代码中,readItem函数试图通过fgets修改itemName指向的内存,后续还调用free释放该指针——这两个操作均属非法:只读内存不可写入,且字符串字面量并非堆内存分配,不能用free释放。编译器的严格检查(如VS默认编译选项)捕捉到风险,抛出类型不兼容错误,阻止非法操作的发生。

解决方案

方案一:使用栈数组

修改结构体定义,将char* itemName替换为固定大小的栈数组,无需手动管理内存,直接支持写入:

struct item {
  char itemName[50];
  int quantity;
  float price;
  float amount;
};

注意:栈数组无需调用free,作用域结束后自动释放。

方案二:动态分配堆内存

若需灵活的内存大小,在main中为itemName分配堆内存,使用完毕后释放:

int main(void) {
  struct item item1;

  // 分配可写入的堆内存,大小按需调整
  item1.itemName = (char*)malloc(50 * sizeof(char));
  if (item1.itemName == NULL) {
    printf("Memory allocation failed\n");
    return 1;
  }
  // 初始化字符串
  strcpy(item1.itemName, "SDfsd");

  item1.quantity = 0;
  item1.price = 0.0;
  item1.amount = 0.0;

  struct item* itemP = &item1;

  readItem(itemP);
  print(itemP);

  // 安全释放堆内存
  free(itemP->itemName);
  itemP->itemName = NULL;

  return 0;
}

注意:动态分配后需检查malloc是否成功,避免空指针操作。

额外修正:换行符处理逻辑

原代码中用NULL替换换行符错误,NULL是指针类型,应使用字符'\0',且可优化循环逻辑:

if (p->itemName[i] == '\n') {
  p->itemName[i] = '\0';
  break; // 找到换行符后直接退出循环
}

更简洁的写法:

p->itemName[strcspn(p->itemName, "\n")] = '\0';

内容的提问来源于stack exchange,提问作者Mohamed Taha

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.11 02:59:54