如何修复c+上的分段故障(堆芯转储)错误+;在读取文件时? 当我试图在C++ 17上运行这个代码时,它工作了,但是C++上没有。第一次运行时,它只给出最后输入元素的字符串值,但第二次运行时,它显示分段错误(核心转储)错误。有人能帮我吗
这是我的密码:如何修复c+上的分段故障(堆芯转储)错误+;在读取文件时? 当我试图在C++ 17上运行这个代码时,它工作了,但是C++上没有。第一次运行时,它只给出最后输入元素的字符串值,但第二次运行时,它显示分段错误(核心转储)错误。有人能帮我吗,c++,C++,这是我的密码: #include<iostream> #include<string> #include<fstream> #include<vector> #include<iomanip> #include <stdlib.h> using namespace std; void show1(string name,string type,string price,string quantity){ cout<
#include<iostream>
#include<string>
#include<fstream>
#include<vector>
#include<iomanip>
#include <stdlib.h>
using namespace std;
void show1(string name,string type,string price,string quantity){
cout<<"=======================================\n";
cout<<setw(5)<<name<<setw(15)<<type<<setw(10)<<price<<setw(15)<<quantity<<"\n";
cout<<"========================================\n";
}
template<class T>
void Readfile(T &obj,string fname,string name,string type,string price,string quantity){
int i=1;
ifstream f;
f.open(fname,ios::in);
f.seekg(0);
Display(name,type,price,quantity);
while(!f.eof()){
f.read((char*)&obj, sizeof(obj));
if(!f.eof()) {
if(f.tellg()<0)
{ i=0; break;}
obj.putdata();
}
}
f.close();
}
class Items{
string name;
double price;
int quantity;
public:
string itemObj;
void getdata(string obj){
cout<<"Enter name, price and quantity: \n";
cin>>name>>price>>quantity;
itemObj=obj;
}
void putdata(){
cout<<setw(5)<<name<<setw(10)<<itemObj<<setw(12)<<price<<setw(10)<<quantity<<"\n";
}
void writeToFile(int n,string obj);
void ReadFile_item();
int check(string temp_name);
void refill_Item(int qty);
double checkout_price(int qty);
}item;
class CD:public Items{
public:
void Add_CD();
}cd;
double Items::checkout_price(int qty){
if(quantity>=qty){
quantity-=qty;
cout<<"File Updated";
return price*qty;
}
else{
cout<<"\nNot enough stock";
return 0;
}
}
void Items::writeToFile(int n,string obj){
ofstream f;
f.open("stock.txt",ios::out|ios::app);
for(int i=0;i<n;i++){
item.getdata(obj);
f.write((char*)&item, sizeof(item));
cout<<"File Updated\n";
}
f.close();
}
void Items:: ReadFile_item(){
Readfile(item,"stock.txt","Name","Item type"," Price ","Available stock");
}
void Add_item_obj(string obj){
int n;
cout<<"Enter no. of "<<obj<<"'s to add: \n";
cin>>n;
item.writeToFile(n,obj);
}
void CD::Add_CD(){
Add_item_obj("CD");
}
void main_menu(){
int i=0;
do{
cout<<"============================\n";
cout<<"-------MAIN MENU------------\n";
cout<<"============================\n";
cout<<"1. Sell Items\n";
cout<<"2. Add Items\n";
cout<<"4. View stock file\n";
cout<<"5. Exit \n";
cout<<"Enter your choice: ";
cin>>i;
switch(i){
case 1: sell_items();
break;
case 2: writetoFile(1,"CD");
break;
case 3: item.ReadFile_item();
break;
default: cout<<"Exiting... \n";
exit(0);
}
}while(i!=0);
}
int main(){
main_menu();
return 0;
}
#包括
#包括
#包括
#包括
#包括
#包括
使用名称空间std;
void show1(字符串名称、字符串类型、字符串价格、字符串数量){
库特
这个演员阵容毫无意义。有两种方法可以解释为什么这不可能奏效:
假设obj
是std::string
。此代码必须读取固定数量的字节(否则,它将传递给read
?)。但是,对于字符串的任何可能内容,多少字节是足够的?显然,这是不可能的。无论传递给read
的大小如何,字符串的逻辑大小都可能大于此值
内存内容可能只包含在当前进程上下文中有意义的信息。例如const char*foo=“hello”
使foo
保持字符串常量的地址“hello”
。将该地址写入文件的目的是什么?任何后续进程的后续执行如何在该进程运行时不存储在该特定地址的内容
您的代码在文件中读取和写入对象的物理内容。您需要读取和写入对象的逻辑内容,而不是在执行此过程期间这些内容在内存中的编码方式
打个比方,我可能会记得某家餐厅是“我20岁生日吃东西的地方”。但如果我与其他人交流该餐厅,告诉他们我对该餐厅的记忆是没有帮助的。我必须以我知道他们会理解的方式对其进行编码。这就是文件格式的作用
要将数据写入文件,您必须确定文件格式,并实现与该格式的转换代码。对于字符串等内容,您必须确定支持的最大大小,并始终读取和写入该字节数,或者使用允许可变大小的格式
看看现有库中的著名文件格式。文本是最简单的,但也有XML和JSON之类的东西
这个演员阵容毫无意义。有两种方法可以解释为什么这不可能奏效:
假设obj
是std::string
。此代码必须读取固定数量的字节(否则,它将传递给read
?)。但是,对于字符串的任何可能内容,多少字节是足够的?显然,这是不可能的。无论传递给read
的大小如何,字符串的逻辑大小都可能大于此值
内存内容可能只包含在当前进程上下文中有意义的信息。例如const char*foo=“hello”
使foo
保持字符串常量的地址“hello”
。将该地址写入文件的目的是什么?任何后续进程的后续执行如何在该进程运行时不存储在该特定地址的内容
您的代码在文件中读取和写入对象的物理内容。您需要读取和写入对象的逻辑内容,而不是在执行此过程期间这些内容在内存中的编码方式
打个比方,我可能会记得某家餐厅是“我20岁生日吃东西的地方”。但如果我与其他人交流该餐厅,告诉他们我对该餐厅的记忆是没有帮助的。我必须以我知道他们会理解的方式对其进行编码。这就是文件格式的作用
要将数据写入文件,您必须确定文件格式,并实现与该格式的转换代码。对于字符串等内容,您必须确定支持的最大大小,并始终读取和写入该字节数,或者使用允许可变大小的格式
看看现有库中的著名文件格式。文本是最简单的,但也有XML和JSON之类的东西。我还没有读过你的代码,但建议你尝试使用地址消毒器来编译它。如果你使用gcc或clang,只需将-fsanize=地址添加到编译器和链接器中。如果你使用MSVC,就有一个经验Visual Studio中的ntal功能。地址消除器将为您提供有关出现SEGFAULT的原因的一些额外信息。您能否提供stock.txt
和sales.txt
的示例?我认为Items::name
成员的处理不正确,或者不一定正确。如果字符串足够长,则实际字符串存储在堆和指向该内存的唯一指针存储在字符串中。当您读取对象时,您可能会读取指针值,而实际上该内存位置没有字符串。请参阅此处有关堆的详细信息:@DhirajWishal sales.txt仅在我们出售某些物品时才会打开,并且信息取自stock.txt文件。不过,下面是一个示例stock.txt的名称为:HarryPotter 1020@DhirajWishal谢谢我还没有读过你的代码,但是我建议你试着用地址消毒器编译它。如果你使用gcc或clang,只需将-fsanize=address添加到编译器和链接器中。如果你使用MSVC,Visual Studio中有一个实验性的功能。地址消毒器将为你提供关于segfaults出现原因的一些额外信息能否提供stock.txt
和sales.txt
的示例?我认为Items::name
成员的处理不正确,或者不一定正确。如果字符串足够长,则实际字符串存储在堆中并
f.read((char*)&obj, sizeof(obj));