从文件中读取数组没有给出正确的值?

Reading array from file not giving correct values?

本文关键字:文件 读取 数组      更新时间:2023-10-16

目前正在处理一个必须在太平洋标准时间本周四晚上完成的项目。为了快速总结,该程序必须基于菜单,并允许用户创建一个长双精度数组(用户设置的行/列数和所有数组值(并将其保存到文件(用户设置名称(。它还必须允许用户将文件读入长双精度数组并将其打印到程序中,然后允许用户选择要排序的列并将排序的数组保存到另一个文件中,最后允许用户在文件中搜索值(其中程序必须知道列是排序还是未排序并使用适当的搜索算法(。

由于CHOICE_2和CHOICE_3功能的问题,我没有完成菜单中的CHOICE_4。这是我整个项目的源代码:

#include <iostream>
#include <string>
#include <iomanip>
#include <cstdlib>
#include <fstream>
#include <vector>
using namespace std;
//Function prototypes required for project
void displayMenu(int &);                //Menu function
int unsortedFile(string, int, int);     //Function for menu choice 1
int printFile(string, int, int);        //Function for menu choice 2
int sortFile(string, int, int);     //Function for menu choice 3
int main()
{
int choice;             //Menu choice
do
{
displayMenu(choice);
} 
while (choice > 0 && choice <= 4);
return 0;
}
void displayMenu(int &c)
{
//Constants for menu choices
const int   CHOICE_1 = 1,
CHOICE_2 = 2,
CHOICE_3 = 3,
CHOICE_4 = 4,
QUIT_CHOICE = 0;
string  filenameU,      //unsorted
filenameP,      //printed
filenameS,      //to be sorted
filenameSOut;   //sorted data
int         SIZE1,      //Array dimensions
SIZE2;      //Array dimensions
cout << "-------------------------" << endl;
cout << "tMENU" << endl;
cout << "-------------------------" << endl;
cout << "1. Create a custom array file." << endl;
cout << "2. Print an array from a file." << endl;
cout << "3. Sort an array from a file." << endl;
cout << "4. Search an array from a file." << endl;
cout << "0. Exit program." << endl;
cout << "-------------------------" << endl;
cout << "Enter your choice from above: ";
cin >> c;
cout << endl;
switch(c)
{
case CHOICE_1:
cout << "Enter the name of the file you want to write: ";
cin.ignore(100, 'n');
getline(cin, filenameU, 'n');
do
{
cout << endl;
cout << "Enter the amount of rows you want in your array between 2 and 10: ";
cin >> SIZE1;
} while (SIZE1 < 2 || SIZE1 > 10);
do
{
cout << endl;
cout << "Enter the amount of columns you want in your array between 2 and 10: ";
cin >> SIZE2;
} while (SIZE2 < 2 || SIZE2 > 10);
unsortedFile(filenameU, SIZE1, SIZE2);
break;
case CHOICE_2:
cout << "Enter the name of the file you want to print: ";
cin.ignore(100, 'n');
getline(cin, filenameP, 'n');
printFile(filenameP, SIZE1, SIZE2);
break;
case CHOICE_3:
cout << "Enter the name of the file you want to sort: ";
cin.ignore(100, 'n');
getline(cin, filenameS, 'n');
sortFile(filenameS, SIZE1, SIZE2);
break;
case CHOICE_4:
break;
case QUIT_CHOICE:
cout << "Exiting program." << endl;
break;
default:
cout << "The valid entries are 1-4 or 0 to exit program.";
}
}
int unsortedFile(string filenameU, int SIZE1, int SIZE2)
{
long double arr[SIZE1][SIZE2];  //Array for user definition
ofstream outputFileU;
outputFileU.open(filenameU.c_str());
//Get data for file output
if (outputFileU)
{
//Get user input for array
cout << "Enter numbers into the array." << endl;
for (int i = 0; i < SIZE1; i++)
{
for (int j = 0; j < SIZE2; j++)
{
cout << "Enter element [" << i << "] [" << j << "]: ";
cin >> arr[i][j];
outputFileU << arr[i][j] << " ";
}
outputFileU << endl;
}
}
else
{
cout << "File could not be opened for writing..." << endl;
return 1;
}
//Close the file
outputFileU.close();
cout << "-------------------------" << endl;
cout << "File named: " << filenameU << " written." << endl;
cout << endl;
}
int printFile(string filenameP, int SIZE1, int SIZE2)
{
ifstream inputFileP;
inputFileP.open(filenameP.c_str());
if (inputFileP.is_open())
{
long double pArr[SIZE1][SIZE2];
inputFileP >> SIZE1 >> SIZE2;
while (inputFileP.good())
{
for (int i = 0; i < SIZE1; i++) //steps through rows
{
for (int j = 0; j < SIZE2; j++) //steps through columns
{
inputFileP >> pArr[i][j]; //reads data at position i, j
cout << pArr[i][j] << " "; //prints value at position i, j
}
cout << endl;
}
}
inputFileP.close();
cout << "-------------------------" << endl;
cout << "File named: " << filenameP << " printed." << endl;
cout << endl;
}
else
{
cout << "File could not be opened for printing..." << endl;
return 1;
}
}
int sortFile(string filenameS, int SIZE1, int SIZE2)
{
int key;
ifstream inputFileS;
inputFileS.open(filenameS.c_str());
if(inputFileS)
{
inputFileS >> SIZE1;
inputFileS >> SIZE2;
long double temp[SIZE1];
long double data[SIZE1][SIZE2];
for (int i = 0; i < SIZE1; i++)
{
for (int j = 0; j < SIZE2; j++)
{
inputFileS >> data[i][j];
}
}
cout << "Enter which column you want to sort: ";
cin >> key;
key--;
for (int i = 0; i < SIZE1; i++)
{
for (int j = 0; j < SIZE2; j++)
{
if (data[i][key] > data[j][key])
{
for (int t = 0; t < SIZE1; t++)
{
temp[t] = data[i][t];
}
for (int t = 0; t < SIZE1; t++)
{
data[i][t] = data[j][t];
}
for (int t = 0; t < SIZE1; t++)
{
data[j][t] = temp[t];
}
}
}
}
string filenameSOut;
cout << "nEnter file name to save sorted data: ";
cin.ignore(100, 'n');
getline(cin, filenameSOut, 'n');
ofstream outputFileS;
outputFileS.open(filenameSOut.c_str());
outputFileS << SIZE1 << " " << SIZE2 << endl;
for (int i = 0; i < SIZE1; i++)
{
for (int j = 0; j < SIZE2; j++)
{
outputFileS << data[i][j];
}
outputFileS << endl;
}
outputFileS.close();
cout << "-------------------------" << endl;
cout << "File named: " << filenameSOut << " sorted." << endl;
cout << endl;
}
else
{
cout << "File could not be opened for sorting...";
return 1;
}
}

我的输出目前读起来是这样的(使用一些示例输入(:

-------------------------
MENU
-------------------------
1. Create a custom array file.
2. Print an array from a file.
3. Sort an array from a file.
4. Search an array from a file.
0. Exit program.
-------------------------
Enter your choice from above: 1
Enter the name of the file you want to write: Yeetus
Enter the amount of rows you want in your array between 2 and 10: 3
Enter the amount of columns you want in your array between 2 and 10: 4
Enter numbers into the array.
Enter element [0] [0]: 5
Enter element [0] [1]: 3
Enter element [0] [2]: 8
Enter element [0] [3]: 9
Enter element [1] [0]: 2
Enter element [1] [1]: 1
Enter element [1] [2]: 0
Enter element [1] [3]: 3
Enter element [2] [0]: 5
Enter element [2] [1]: 7
Enter element [2] [2]: 4
Enter element [2] [3]: 4
-------------------------
File named: Yeetus written.
-------------------------
MENU
-------------------------
1. Create a custom array file.
2. Print an array from a file.
3. Sort an array from a file.
4. Search an array from a file.
0. Exit program.
-------------------------
Enter your choice from above: 2
Enter the name of the file you want to print: Yeetus
8 9 2
1 0 3
5 7 4
4 1.45808e-4950 1.45808e-4950
1.45808e-4950 1.74779e-4944 4.70418e+1991
-------------------------
File named: Yeetus printed.
-------------------------
MENU
-------------------------
1. Create a custom array file.
2. Print an array from a file.
3. Sort an array from a file.
4. Search an array from a file.
0. Exit program.
-------------------------
Enter your choice from above: 3
Enter the name of the file you want to sort: Yeetus
Enter which column you want to sort: 3
Enter file name to save sorted data: YeetusSorted
-------------------------
File named: YeetusSorted sorted.
-------------------------
MENU
-------------------------
1. Create a custom array file.
2. Print an array from a file.
3. Sort an array from a file.
4. Search an array from a file.
0. Exit program.
-------------------------
Enter your choice from above: 0
Exiting program.
--------------------------------
Process exited after 58.35 seconds with return value 0
Press any key to continue . . .

第一个函数unsortedFile完美地工作,减去它还必须在第一行中包含 UNSORTED,然后分别在第二行和第三行中包含 ROWS: 和 COLUMNS: 的要求。只有数字,它的打印方式如下:

5 3 8 9 
2 1 0 3 
5 7 4 4 

第二个功能似乎跳过文件中的前两个数字,打印其余的数字,然后打印一堆垃圾。

第三个函数给出了以下文件,其中包含我提供的示例数据:

5 3
894
103
572
4-2.71616e-11730
1.56264e-48671.68249e-2119-inf

不。。。完全确定为什么会发生这种情况。如果我能掌握从文件中正确读取数据以获得实数,我可以使用排序和搜索算法轻松完成此程序(希望如此(。现在,我被困住了。如果有人可以帮助我修复第二个和第三个函数来读取/打印和排序准确的数字,以及让我知道如何使文件看起来像这样而不会破坏其他函数:

UNSORTED
Rows: 3
Columns: 4
5 3 8 9 
2 1 0 3 
5 7 4 4 

供参考:这门课是C++的入门课程。我们只应该使用我今天在这里提供的内容。矢量和指针也是允许的,但我试图避免它们,因为我没有完全了解如何使用它们,也没有时间学习如何在这个项目中使用它们。

现在专注于printFile: 你的函数做的第一件事是

inputFileP >> SIZE1 >> SIZE2;

但是存在一些问题:

  • 您的unsortedFile函数不会写入此标头。您实际上是将第一行的前两个元素视为要读取的大小。
  • 它会覆盖作为参数传递的SIZE1SIZE2参数。如果您要直接从文件中读取它们,为什么还要传递这些内容?
  • 最后是杀手级问题:使用作为参数提供的SIZE1SIZE2分配数组后,您从文件中读取大小。

因此,您可以有效地为 3x4 数组分配内存,然后像 5x3 矩阵一样写入其中。这将产生烟花。

最后说明:您的顶级菜单假设用户始终通过选项 1 来设置SIZE1SIZE2。您应该从不使用它们的函数中删除这些参数,或者显式设置它们。从我在这里看到的情况来看,最好从选项 2-4 中的函数调用中删除这些参数。