如何输出vector数组中结构体的字符串?scanf输入结构体崩溃求助
解决你遇到的两个C++结构体相关技术问题
嘿,这俩问题都是C++里处理结构体和输入输出时很容易踩的坑,我给你一步步拆解解决:
问题2:scanf输入结构体时程序崩溃(根源问题,也是输出崩溃的原因)
你遇到的崩溃核心原因是**char* name是野指针,没有分配内存**!scanf("%s")会直接把输入的字符串写到指针指向的内存地址,但你的char* name只是声明了指针,却没给它分配实际的内存空间(比如堆上的内存或者栈上的数组),这就导致写入了非法内存,直接触发程序崩溃;就算侥幸没崩溃,把这个结构体存入vector后,输出时访问的还是野指针,照样会崩。
几种靠谱的解决方案:
方案1:用固定大小的char数组替代char(最简单安全)*
把结构体里的char* name改成char name[256];(大小可以根据需求调整,比如128、512),这样scanf可以直接写入栈上的数组,不用手动管理内存:struct citizen{ char name[256]; // 替换char*为固定数组 int year; int month; int day; // 你的bool成员... }; // 输入代码可以直接用原来的scanf格式(注意temp.name不用加&) scanf("%s %4d/%2d/%2d", temp.name, &temp.year, &temp.month, &temp.day);方案2:如果坚持用char,必须手动分配内存*
在调用scanf前,先给name分配足够的内存,还要注意结构体的拷贝/析构逻辑,避免浅拷贝导致的重复释放内存问题:struct citizen{ char* name; int year; int month; int day; // 手动写拷贝构造,避免浅拷贝 citizen(const citizen& other) { name = (char*)malloc(strlen(other.name)+1); strcpy(name, other.name); year = other.year; month = other.month; day = other.day; } // 析构函数释放内存 ~citizen() { if(name) free(name); } // 重载赋值运算符,避免赋值时的浅拷贝 citizen& operator=(const citizen& other) { if(this != &other) { free(name); name = (char*)malloc(strlen(other.name)+1); strcpy(name, other.name); year = other.year; month = other.month; day = other.day; } return *this; } }; // 输入前先分配内存 temp.name = (char*)malloc(256); // 分配足够的空间 scanf("%s %4d/%2d/%2d", temp.name, &temp.year, &temp.month, &temp.day);方案3:用string替代char,绕开scanf的限制*
scanf确实不能直接写std::string,但可以先把输入读到临时char数组里,再赋值给string,这也是C++里更推荐的做法:#include <string> // 记得打开这个头文件! struct citizen{ string name; int year; int month; int day; // 你的bool成员... }; // 输入代码 char temp_buf[256]; scanf("%s %4d/%2d/%2d", temp_buf, &temp.year, &temp.month, &temp.day); temp.name = temp_buf; // 把临时数组的内容赋值给string
问题1:输出vector数组中结构体的字符串
解决了输入的内存问题后,输出就非常简单了,只需要遍历vector,直接访问结构体的name成员即可:
几种遍历输出的方式:
方式1:范围for循环(C++11及以上最简洁)
vector<citizen> citizens; // 先把结构体存入citizens... for(const auto& c : citizens) { cout << "姓名:" << c.name << ",生日:" << c.year << "/" << c.month << "/" << c.day << endl; }方式2:迭代器遍历(兼容旧版C++)
vector<citizen>::const_iterator it; for(it = citizens.begin(); it != citizens.end(); ++it) { cout << it->name << endl; // 用->访问迭代器指向的结构体成员 }方式3:下标遍历
for(int i = 0; i < citizens.size(); ++i) { cout << citizens[i].name << endl; }
内容的提问来源于stack exchange,提问作者Stunning Thunder
相关产品推荐
相关产品推荐

