我的函数调用中未声明的标识符 (C++)

Undeclared Identifier in my function call (C++)

我是一名使用 C++ 的新程序员,我正在尝试制作一个程序,将信息从文件导入到输出文件,然后我将对数据执行搜索算法。我正在尝试使用数据结构并将其导入数组,然后在主程序中调用它。

出于某种原因,我无法让我的函数调用正常工作;我在主程序的函数调用中不断收到关于 inputFile 的未声明标识符错误。我意识到我可能做错了根本性的事情,所以我真的很感激能提供的任何帮助。

#include <iostream>
#include <iomanip>
#include <string>
#include <cstdlib>
#include <fstream>

using namespace std;

const int    MAX_LOG_SIZE = 7584;
const string LOGFILE ="crimes.dat"; 
const string OUTPUT_FILE ="crimesorted.log";

// Structure of strings based on info from crimes.dat
struct CrimeInfo
{
    string Crimedescr;
    string Date;
    string Time;
    string Address;
    string Grid;
    string Latitude;
    string Longitude;
};

CrimeInfo crimeList [MAX_LOG_SIZE];

void openInputFile(ifstream& inputFile, string inputFilename)
// here we open the input file crimes.dat
{
    inputFile.open(inputFilename.c_str());
    while (inputFile.fail())
    {
        cout << "Failed to open input file: " << inputFilename << ".\n";
        exit(1);
    }
};


void getLogEntry(ifstream &LOGFILE, CrimeInfo &entry)
{
    getline(LOGFILE, entry.Date);
    getline(LOGFILE, entry.Time);
    getline(LOGFILE, entry.Address);
    getline(LOGFILE, entry.Grid);
    getline(LOGFILE, entry.Crimedescr);
    getline(LOGFILE, entry.Latitude);
    getline(LOGFILE, entry.Longitude);
}

/* opens an output file */
void openOutputFile(ofstream& outputFile, string outputFilename)
{
    outputFile.open(outputFilename.c_str());
    if (outputFile.fail())
    {
        cout << "Failed to open output file: " << outputFilename << ".\n";
        exit(2);
    }
}

void outputLogFile(string outputFilename, CrimeInfo arr[], int size)
{
    // open output files
    ofstream outputLogFile;
    openOutputFile(outputLogFile, outputFilename);

    // output the crime file
    outputLogFile << "\nCrime log sort ^^:\n\n";
    for (int i = 0; i < size; i++) 
    {
        outputLogFile << arr[i].Date << "  ";
        outputLogFile << arr[i].Address << " (";
        outputLogFile << arr[i].Longitude << " ";
        outputLogFile << arr[i].Latitude << " ";
        outputLogFile << arr[i].Time << " ";
        outputLogFile << arr[i].Grid << " ";
        outputLogFile << arr[i].Crimedescr << "";
        outputLogFile << endl;
    }
    outputLogFile.close(); 
}

int main()
{
    outputLogFile(OUTPUT_FILE, crimeList, MAX_LOG_SIZE);
    for (int i =0; i < MAX_LOG_SIZE; i++)

    getLogEntry(inputFile, crimeList[i].Date);  
}

你的代码有很多问题。为了帮助您,我仔细阅读了您的代码并留下了很多我自己的评论来告诉您我的一些建议;为了方便起见,我删除了你的评论,这样就不会混淆你的评论和我的评论了。

以下是我在您的代码中注意到的一些事情:

  • using namespace std 通常被认为是一种非常糟糕的做法。相反,只需指定命名空间(例如 std::string 而不是 string)。
  • 您在程序的顶部将 LOGFILE 声明为字符串,但随后试图在函数 getLogEntry.
  • 中将其用作 ifstream&
  • 你的主要方法有问题。我假设您想将一些数据从一个文件加载到程序中,然后将该数据输出到另一个文件。您在 main 方法中使用它的方式是,首先,输出您还没有的信息,其次,导入信息但不要对其进行任何操作。
  • 您有 很多 的功能。作为一般的经验法则,不要为打开文件创建一个完整的函数,然后创建一个单独的函数来使用它,然后再创建一个单独的函数来关闭它。 不这样做的原因有很多。最大的原因是你的程序变得很难理解,其他人将无法使用你的代码。在实际应用中,你的代码只有 20% 给计算机,80% 给其他程序员。
  • 存在各种格式错误等。

所以,这是你的原始代码和我的评论...

#include <iostream>
#include <iomanip>
#include <string>
#include <cstdlib>  // Unneeded since other headers here already include this
#include <fstream>

using namespace std; // NEVER globally use the entire standard namespace!

const int    MAX_LOG_SIZE = 7584;  // Can be declared 'constexpr'
const string LOGFILE ="crimes.dat"; 
const string OUTPUT_FILE ="crimesorted.log";

/*
 NOTE:
   > It often looks a lot cleaner to have a header part of your code
     and then define your functions seperately. This is good practice
     for when you need to start using header files with big projects
*/

struct CrimeInfo
{ // Can declare all variables by only listing type once if they're all the same type
    string Crimedescr;
    string Date;
    string Time;
    string Address;
    string Grid;
    string Latitude;
    string Longitude;
};

CrimeInfo crimeList [MAX_LOG_SIZE];  // This should be in 'main()'

/* 
 This should not be its own function.
 Making too many function can make things look a bit confusing.
 Here, this is only 4 lines of code, so you shouldn't be making
 an entire function for it. 
*/
void openInputFile(ifstream& inputFile, string inputFilename)
{
    inputFile.open(inputFilename.c_str());
    while (inputFile.fail())
    {
        cout << "Failed to open input file: " << inputFilename << ".\n";
        exit(1);
    }
};

/*
 This should also just be written out where its used. There's
 no need to make a whole function for a task like this.

 ERROR HERE:
   > LOGFILE is NOT an std::ifstream! It is a std::string!
*/
void getLogEntry(ifstream &LOGFILE, CrimeInfo &entry)
{
    getline(LOGFILE, entry.Date);
    getline(LOGFILE, entry.Time);
    getline(LOGFILE, entry.Address);
    getline(LOGFILE, entry.Grid);
    getline(LOGFILE, entry.Crimedescr);
    getline(LOGFILE, entry.Latitude);
    getline(LOGFILE, entry.Longitude);
}

/* 
 This should not be its own function.
 Making too many function can make things look a bit confusing.
 Here, this is only 4 lines of code, so you shouldn't be making
 an entire function for it. 
*/
void openOutputFile(ofstream& outputFile, string outputFilename)
{
    outputFile.open(outputFilename.c_str());
    if (outputFile.fail())
    {
        cout << "Failed to open output file: " << outputFilename << ".\n";
        exit(2);
    }
}

// It's a good idea to use some sort of documentation style for functions
void outputLogFile( 
    // Declare variables const when they aren't modified
    /* (const) */ string outputFilename, 
    /* (const) */ CrimeInfo arr[], 
    /* (const) */ int size)
{
    ofstream outputLogFile;
    openOutputFile(outputLogFile, outputFilename);  // Just write out the code

    outputLogFile << "\nCrime log sort ^^:\n\n";
    for (int i = 0; i < size; i++) 
    {
        /* 
         You only need to declare the name of the stream one time

         e.g.
            outputLogFile << thing1 << thing2
                << thing3 << thing4 << thing5
                << thing6
                << endl;
        */
        outputLogFile << arr[i].Date << "  ";
        outputLogFile << arr[i].Address << " (";
        outputLogFile << arr[i].Longitude << " ";
        outputLogFile << arr[i].Latitude << " ";
        outputLogFile << arr[i].Time << " ";
        outputLogFile << arr[i].Grid << " ";
        outputLogFile << arr[i].Crimedescr << ""; // Empty quotes not needed here
        outputLogFile << endl;
    }
    outputLogFile.close(); 
}

int main()
{
    // What data are you outputting?
    outputLogFile(OUTPUT_FILE, crimeList, MAX_LOG_SIZE);

    // Are you trying to load the data you just outputted?
    for (int i =0; i < MAX_LOG_SIZE; i++)
    { // I added these braces, but it's a good idea to always have braces

        // You have not declared 'inputFile' anywhere
        getLogEntry(inputFile, crimeList[i].Date);
    }
}

我没有让您不得不自己解决所有问题(我知道这会多么令人沮丧),而是继续编写了您的程序。我试图在很多地方添加评论,以便于跟进。如果您对此有任何疑问,请随时问我。

#include <fstream>
#include <iomanip>
#include <iostream>
#include <string>

/*
 If you're using C++17, the lines below can just become one line:

 using std::cin, std::cout, std::endl, std::ifstream, 
    std::ofstream, std::string, std::getline;
*/
using std::cin;
using std::cout;
using std::endl;
using std::ifstream;
using std::ofstream;
using std::string;

constexpr int MAX_LOG_SIZE     = 7584;
const string  LOGFILE_NAME     = "crimes.dat";
// I'm assuming:       inputFile  ^^^
//                     outputFile vvv
const string  OUTPUT_FILE_NAME = "crimesorted.log";
/*
 NOTE: If you're trying to export data to "crimesorted.log"
       and then load it back into the program through "crimes.dat",
       that will be a problem. I say this because the main method
       in your original code, this is the order you had it in.
*/


// [BEGIN] Function Prototypes

// Structure of strings based on info from crimes.dat
struct CrimeInfo
{
    string Crimedescr, Date, Time, Address,
        Grid, Latitude, Longitude;
};

/** (This is JavaDoc-style documentation)
 [Purpose of function here]

 @param outputFile  [Describe paramater here]
 @param arr[]       [Describe parameter here]
 @param size_of_arr Size of 'arr[]'
*/
void outputLogFile(
    ofstream& outputFile, // Changed to 'std::ofstream&' because I declare this in 'main()'
    const CrimeInfo arr[], 
    const int size_of_arr);

// [END] Function Prototypes


int main()
{
    // Create std::ifstream and open a file
    ifstream file_to_load;
    file_to_load.open(LOGFILE_NAME);

    // Constructing and using 'crimeList' here allows the size to be known in 
    // this scope. However, if it's passed to a function, it's passed as a pointer
    CrimeInfo crimeList[MAX_LOG_SIZE];

    // Check if file was open and do stuff with it
    if (file_to_load.is_open())
    { // File was opened

        for (int i = 0; i < MAX_LOG_SIZE; i++)
        {
            getline(file_to_load, crimeList[i].Date);
            getline(file_to_load, crimeList[i].Time);
            getline(file_to_load, crimeList[i].Address);
            getline(file_to_load, crimeList[i].Grid);
            getline(file_to_load, crimeList[i].Crimedescr);
            getline(file_to_load, crimeList[i].Latitude);
            getline(file_to_load, crimeList[i].Longitude);
        }

        file_to_load.close();  // Close file
    }
    else
    { // File could not be
        cout << "Could not open file: " << LOGFILE_NAME << endl;
        return 1;
    }

    // Create std::ofstream and output the log
    ofstream outputFile;
    outputFile.open(OUTPUT_FILE_NAME);

    // Check if 'outputFile' opened OUTPUT_FILE_NAME successfully
    if(outputFile.is_open())
    { // File was opened
        outputLogFile(outputFile, crimeList, MAX_LOG_SIZE);
        outputFile.close();
    }
    else
    { // File could not be opened
        cout << "Could not open file: " << OUTPUT_FILE_NAME << endl;
        return 1;
    }
}


// Function definition for outputLogFile()
void outputLogFile(
    ofstream &outputFile,
    const CrimeInfo arr[],
    const int size_of_arr)
{
    outputFile << "\nCrime log sort ^^:\n\n";
    for (int i = 0; i < size_of_arr; i++)
    {
        outputFile 
            << arr[i].Date << '\n' // Newlines may look better than spaces here
            << arr[i].Address << " ("
            << arr[i].Longitude << ", "
            << arr[i].Latitude << ")\n"
            << arr[i].Time << '\n'
            << arr[i].Grid << '\n'
            << arr[i].Crimedescr
            << endl;
    }
}