刚学习文件操作,我把数组元素放到文件后,在放回代码,数据全部在新建数组的第一个元素,我该怎么让他放回各自的位置
看看你的程序。你怎么写入文件,读出来的时候也应相应的拆分,放到数组中
1.友元函数写在类中
template <typename T>
class Complex
{
friend ostream& operator << (ostream& out, Complex &c)
{
out << c.a << "+" << c.b << "i" << endl;
return out;
}
};
2.按照一般改写,如下:
template <typename T>
class Complex
{
friend ostream& operator << (ostream& out, Complex &c);
};
template <typename T>
ostream& operator << (ostream& out, Complex<T> &c)
{
out << c.a << "+" << c.b << "i" << endl;
return out;
}
错误 1 error LNK2019: 无法解析的外部符号 "class std::basic_ostream<char,struct std::char_traits<char> > & __cdecl operator<<(class std::basic_ostream<char,struct std::char_traits<char> > &,class Complex<int> &)" (??6@YAAAV?$basic_ostream@DU?$char_traits@D@std@@@std@@AAV01@AAV?$Complex@H@@@Z),该符号在函数 _main 中被引用 D:\C++study\eight\Complex\Complex\dm02.obj Complex
3.解决办法:由友元函数类中改成成类外,但是在同一个文件中
template <typename T>
class Complex
{
friend ostream& operator << <T>(ostream& out, Complex &c);
};
template <typename T>
ostream& operator << (ostream& out, Complex<T> &c)
{
out << c.a << "+" << c.b << "i" << endl;
return out;
}
只要在类中声明过程中添加<T>
4.原因:
模板的机制:模板会有二次编译,第一次编译检查类模板或函数模板是否有词法语法等错误,在使用模板函数,编译器会根据实际类型不同生成不同的函数,然后就能找到相应类型的函数体。在实际运用中,模板函数可以利用编译器自动推断类型,可以显式或隐式使用函数模板,类模板必须显式使用,告诉编译器模板类的类型。
原因:第一次编译的函数头和第二次编译的函数头不同,
friend ostream& operator << (ostream& out, Complex &c);
ostream& operator << (ostream& out, Complex<T> &c)
导致找不到函数体,出现错误。
二、写在不同的文件中(.cpp和.h)
main.cpp引用时,#include"complex.cpp" 而不是#include"complex.h"
实例:
complex.h
#pragma once
#include <iostream>
using namespace std;
template <typename T>
class Complex
{
friend ostream& operator << <T>(ostream& out, Complex &c);
/*
friend Complex Sub(Complex &c1, Complex &c2)
{
Complex tmp(c1.a - c2.a, c1.b - c2.b);
return tmp;
}
*/
private:
T a;
T b;
public:
Complex(T a, T b);
void print();
Complex operator + (Complex &c2);
Complex operator - (Complex &c2);
};
complex.cpp
#include "complex.h"
template <typename T>
Complex<T>::Complex(T a, T b)
{
this->a = a;
this->b = b;
}
template <typename T>
void Complex<T>::print()
{
cout << a << "+" << b << "i" << endl;
}
template <typename T>
Complex<T> Complex<T>::operator - (Complex<T> &c2)
{
Complex tmp(a - c2.a, b - c2.b);
return tmp;
}
template <typename T>
ostream& operator << (ostream& out, Complex<T> &c)
{
out << c.a << "+" << c.b << "i" << endl;
return out;
}
template<typename T>
Complex<T> Complex<T>::operator + (Complex<T> &c2)
{
Complex<T> c1(0, 0);
c1.a = this->a + c2.a;
c1.b = this->b + c2.b;
return c1;
}
main.cpp
#include <iostream>
using namespace std;
#include "complex.cpp"
int main()
{
Complex<int> c1(1, 2);
Complex<int> c2(3, 4);
Complex<int> c3(5, 6);
Complex<int> c4 = c1 + c2 + c3;
cout << c4 << endl;
//滥用友元
// Complex<int> c5 = Sub(c1, c2);
// cout << c5 << endl; //这种是无法解决的
Complex<int> c6 = c1 - c2;
cout << c6 << endl;
system("pause");
}
针对问题:如何解决文件操作后数组数据只集中在第一个元素的问题?
首先,需要了解是通过什么方式将数组输入到文件中的,是否在代码中实现还是通过其他工具?
其次,需要检查读取文件时是否按照正确的方法读取,读取的文件是否和之前存储的文件是一致的,文件读写模式是否正确。
最后,建议使用循环遍历读取文件中的数据,并逐个把数据保存到目标数组中对应的位置上。
以下是一个示例代码(假设数据是按照逗号分隔的字符串):
#define MAX_LEN 1000
// 将一个数组的数据存储到文件中,假设数据都是文本
void saveDataToFile(char* fileName, int* array, int length) {
FILE* file = fopen(fileName, "w"); // 以写入模式打开文件
if (file != NULL) {
for (int i = 0; i < length; i++) {
fprintf(file, "%d", array[i]); // 将数据写入文件
if (i != length - 1) {
fprintf(file, ","); // 每个数据之间加上逗号分隔
}
}
fclose(file); // 关闭文件
}
}
// 从文件中读取一个数组的数据,返回实际读取到的元素个数
int readDataFromFile(char* fileName, int* array, int maxLen) {
FILE* file = fopen(fileName, "r"); // 以读取模式打开文件
if (file != NULL) {
char dataStr[MAX_LEN];
fgets(dataStr, MAX_LEN, file); // 读取一整行字符串
fclose(file); // 关闭文件
int length = 0;
char* itemStr = strtok(dataStr, ","); // 使用逗号分隔符分割字符串
while (itemStr != NULL && length < maxLen) {
array[length] = atoi(itemStr); // 将字符串转成整数并存储到数组中
length++;
itemStr = strtok(NULL, ",");
}
return length;
} else {
return -1; // 文件不存在或无法打开
}
}
// 示例代码中的用法
int main() {
int testArray[] = {10, 20, 30, 40, 50};
int arrayLen = sizeof(testArray) / sizeof(int);
saveDataToFile("test.txt", testArray, arrayLen);
int resultArray[MAX_LEN];
int resultLen = readDataFromFile("test.txt", resultArray, MAX_LEN);
for (int i = 0; i < resultLen; i++) {
printf("%d ", resultArray[i]);
}
return 0;
}
在示例代码中,saveDataToFile
函数将一个整数数组中的数据存储到文件中(以逗号分隔),readDataFromFile
函数从文件中读取数据并返回读取到的元素个数,最后再通过循环将读取到的数据逐个存储到目标数组中。需要注意的是,如果存储和读取的数据长度不超过1000,可以直接把数组的长度作为readDataFromFile
函数的第三个参数传入,否则需要另外处理。