int config_set_value(Config *config, const char *section_name, const char *bss_name, const char *key, const char *new_value) { ConfigSection *sec = find_section(config, section_name); if (!sec) return -1; if (sec->is_bss_section) { // 处理 BSS 节 BssModule *bss = find_bss(sec, bss_name); if (!bss) return -1; printf("🔧 开始设置 key: %s = %s 在 bss: %s\n", key, new_value, bss_name); for (ConfigLine *line = bss->lines; line; line = line->next) { printf("遍历行: %s\n", line->line); char k[128], v[128]; if (sscanf(line->line, "%127[^=]=%127[^\n]", k, v) != 2) { printf("❌ 解析失败: %s\n", line->line); continue; } printf("解析到 key: %s\n", k); if (strcmp(k, "bss") == 0) { printf("跳过 bss=xxx 行\n"); continue; } if (strcmp(k, key) == 0) { // 修改已有行的 value size_t new_len = strlen(k) + strlen(new_value) + 2; char *new_line_str = realloc(line->line, new_len); if (!new_line_str) return -1; line->line = new_line_str; snprintf(line->line, new_len, "%s=%s", k, new_value); return 0; } } } else { // 处理普通节(General 或 Interface) printf("🔧 开始设置 key: %s = %s 在普通节: %s\n", key, new_value, section_name); for (ConfigLine *line = sec->lines; line; line = line->next) { printf("遍历行: %s\n", line->line); char k[128], v[128]; if (sscanf(line->line, "%127[^=]=%127[^\n]", k, v) != 2) { printf("❌ 解析失败: %s\n", line->line); continue; } printf("解析到 key: %s\n", k); if (strcmp(k, key) == 0) { // 修改已有行的 value size_t new_len = strlen(k) + strlen(new_value) + 2; char *new_line_str = realloc(line->line, new_len); if (!new_line_str) return -1; line->line = new_line_str; snprintf(line->line, new_len, "%s=%s", k, new_value); return 0; } } } return -1; // key 不存在 } 这里报错line->line = new_line_str;必须是可修改的左值,同时我不想修改结构体
时间: 2025-09-07 11:51:32 AIGC 浏览: 4
你遇到的错误是:
```
error: expression must be a modifiable lvalue
```
出现在这一行:
```c
line->line = new_line_str;
```
---
## ❌ 错误原因
你使用了 `realloc` 来重新分配内存:
```c
char *new_line_str = realloc(line->line, new_len);
```
然后试图将新地址赋给 `line->line`:
```c
line->line = new_line_str;
```
但是你的结构体定义是:
```c
typedef struct ConfigLine {
char line[256]; // 固定大小的数组
struct ConfigLine *next;
} ConfigLine;
```
`line->line` 是一个 **固定大小的字符数组(char[256])**,**不是指针**,所以你 **不能将它重新赋值为另一个地址**。
---
## ✅ 你想要的:**不修改结构体的前提下安全地修改 `line->line` 的内容**
### ✅ 替代方案:使用 `strncpy` + `snprintf`
由于你不能使用 `realloc`,也不能赋值 `line->line = ...`,你需要:
- 使用 `snprintf` 构造新字符串;
- 使用 `strncpy` 将其复制进 `line->line`;
- 确保字符串结尾有 `\0`。
---
## ✅ 修改后的函数(不修改结构体)
```c
int config_set_value(Config *config, const char *section_name, const char *bss_name, const char *key, const char *new_value) {
ConfigSection *sec = find_section(config, section_name);
if (!sec) return -1;
if (sec->is_bss_section) {
// 处理 BSS 节
BssModule *bss = find_bss(sec, bss_name);
if (!bss) return -1;
printf("🔧 开始设置 key: %s = %s 在 bss: %s\n", key, new_value, bss_name);
for (ConfigLine *line = bss->lines; line; line = line->next) {
printf("遍历行: %s\n", line->line);
char k[128], v[128];
if (sscanf(line->line, "%127[^=]=%127[^\n]", k, v) != 2) {
printf("❌ 解析失败: %s\n", line->line);
continue;
}
printf("解析到 key: %s\n", k);
if (strcmp(k, "bss") == 0) {
printf("跳过 bss=xxx 行\n");
continue;
}
if (strcmp(k, key) == 0) {
// 构造新行
char new_line[256];
snprintf(new_line, sizeof(new_line), "%s=%s", k, new_value);
// 使用 strncpy 安全地复制
strncpy(line->line, new_line, sizeof(line->line) - 1);
line->line[sizeof(line->line) - 1] = '\0'; // 确保结尾
return 0;
}
}
} else {
// 处理普通节(General 或 Interface)
printf("🔧 开始设置 key: %s = %s 在普通节: %s\n", key, new_value, section_name);
for (ConfigLine *line = sec->lines; line; line = line->next) {
printf("遍历行: %s\n", line->line);
char k[128], v[128];
if (sscanf(line->line, "%127[^=]=%127[^\n]", k, v) != 2) {
printf("❌ 解析失败: %s\n", line->line);
continue;
}
printf("解析到 key: %s\n", k);
if (strcmp(k, key) == 0) {
char new_line[256];
snprintf(new_line, sizeof(new_line), "%s=%s", k, new_value);
strncpy(line->line, new_line, sizeof(line->line) - 1);
line->line[sizeof(line->line) - 1] = '\0';
return 0;
}
}
}
return -1; // key 不存在
}
```
---
## ✅ 关键修改点
| 原代码 | 修改后 |
|--------|--------|
| `char *new_line_str = realloc(...)` | 删除 `realloc` |
| `line->line = new_line_str;` | 删除赋值 |
| `snprintf(line->line, new_len, ...)` | 使用 `snprintf` 构造临时字符串 |
| `strncpy(line->line, new_line, ...)` | 使用 `strncpy` 安全复制进固定数组 |
---
## ⚠️ 注意事项
| 项目 | 说明 |
|------|------|
| 是否修改结构体 | ❌ 不修改 |
| 是否支持任意长度字符串 | ❌ 最多 255 字符 |
| 是否会截断 | ✅ 如果新字符串太长会被截断 |
| 是否需要动态内存管理 | ❌ 不需要 `malloc` / `realloc` |
| 是否安全 | ✅ 使用 `strncpy` + `\0` 保护 |
---
## ✅ 示例
假设原字符串是:
```
ifname=wl0.1
```
调用:
```c
config_set_value(config, "BSS configurations", "radio0", "ifname", "wl0.3");
```
结果会变成:
```
ifname=wl0.3
```
只要长度不超过 255 字符即可。
---
### ❓相关问题:
阅读全文
相关推荐



















