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

C++中无法将string变量赋值给结构体char数组成员的问题求助

问题修复方案

核心问题拆解与修复

  • 函数名不匹配:声明的modifyRecord和定义的modifyingRecord不一致,直接导致编译失败,把定义的函数名改成modifyRecord即可。
  • getline输入吞空问题:用cin >>读取数字后,输入缓冲区会残留换行符,后续getline会直接读取这个空行。需要把cin.ignore()放在getline之前,清空缓冲区的换行符。
  • strcpy参数错误:strcpy的第二个参数需要const char*类型,不能直接传std::string对象,得用str.c_str()获取C风格字符串指针。
  • 文件定位错误:直接用tempNum作为seekg的偏移量完全错误,每个Product记录占sizeof(Product)字节,要定位到第N条记录,偏移量应该是tempNum * sizeof(Product)(注意如果记录编号从1开始,要减1,比如输入1对应第0个偏移)。

修正后的完整代码

#include<iostream>
#include<fstream>
#include<string>
#include<cstring>
#include<limits>

#pragma warning(disable : 4996)

using namespace std;

const int NAME_SIZE = 40;

struct Product
{
    long number;
    char name[NAME_SIZE];
    double price;
    int quantity;
};

void modifyRecord(fstream&);
void createFile(fstream&); // 补充函数声明,避免编译报错

int main() {

    fstream inventoryFile;
    // 调整open参数:二进制读写模式,文件不存在则创建
    inventoryFile.open("inventory.dat", ios::binary | ios::in | ios::out);

    if (inventoryFile) {
        // 判断文件是否为空,避免重复写入初始数据
        inventoryFile.seekg(0, ios::end);
        if (inventoryFile.tellg() == 0) {
            createFile(inventoryFile);
            cout << "Inventory File created.\n";
        } else {
            cout << "Inventory File opened.\n";
        }
        // 重置文件指针到开头
        inventoryFile.seekg(0);
    }
    else {
        cout << "Error: Cannot open file." << endl;
        return 1;
    }
    
    modifyRecord(inventoryFile);

    inventoryFile.close();

    return 0;
}

void createFile(fstream& inventoryFile) {
    
    Product milk;
    milk.number = 15478;
    strcpy(milk.name, "Whole Milk");
    milk.price = 2.99;
    milk.quantity = 30;
    inventoryFile.write(reinterpret_cast<char*>(&milk), sizeof(milk));
}

void modifyRecord(fstream& inventoryFile) {

    string str;
    int tempNum = 0;
    Product prod;

    cout << "\nEnter Record Index (start from 0): ";
    cin >> tempNum;

    // 定位到对应记录的起始位置
    inventoryFile.seekg(tempNum * sizeof(Product), ios::beg);
    // 先读取原有记录,保留未修改的字段值
    inventoryFile.read(reinterpret_cast<char*>(&prod), sizeof(Product));

    cout << "\nEnter New Product Number: \n";
    cin >> prod.number;

    cout << "\nEnter New Product Name: \n";
    // 先忽略之前cin留下的所有换行符
    cin.ignore(numeric_limits<streamsize>::max(), '\n');
    getline(cin, str);
    // 用strncpy替代strcpy,避免数组溢出,手动补结束符
    strncpy(prod.name, str.c_str(), NAME_SIZE - 1);
    prod.name[NAME_SIZE - 1] = '\0';

    cout << "\nEnter New Price: \n";
    cin >> prod.price;
    cout << "\nEnter New Quantity: ";
    cin >> prod.quantity;

    // 回到记录起始位置,覆盖写入更新后的数据
    inventoryFile.seekp(tempNum * sizeof(Product), ios::beg);
    inventoryFile.write(reinterpret_cast<char*>(&prod), sizeof(Product));
    cout << "Record updated successfully.\n";
}

额外优化说明

  • 用strncpy替代strcpy,避免输入的产品名称过长导致数组溢出,提升安全性。
  • 添加了文件是否为空的判断,避免每次打开文件都覆盖初始记录。
  • 读取原有记录后再修改,确保未修改的字段保留原有值(原代码新建prod变量时,未赋值的字段会是随机值,写入后会破坏原有数据)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.14 22:40:40