从链接列表数组中访问节点数据

时间:2017-05-20 19:45:43

标签: c++ arrays pointers linked-list

我正在进行一项相当冗长的任务,目前有一个致命的问题。我无法正确地实现节点访问存储在指针中的链表中存储的数据。

起初我收到了分段错误,但经过一些研究,例如thisthis,我能够清除它。现在我已经修复了分段错误,我的代码甚至都不会编译!

我已经“调试”调试到我知道问题存在于我的Cache.h文件中,特别是在我的addElement函数中,当我尝试设置新节点p时等于某个数组值的起始节点。试图明确评论。

因为我的数组是一个链表的数组,它本质上是一个指针数组。类型声明为node *。我觉得p应该是指向指针的指针,因为它不是任何列表的一部分,需要通过数组访问数据。我已经尝试了大约一百万个指针组合和指针指针,但是没有什么能让我再次编译。我已经完成了所有我知道如何做的调试,所以我转向你。

我将发布以下代码。 commands.in基本上包含我将使用的文件的名称。 A.data是我正在对其进行操作的数据的文件(min为ex)。 Process.cpp包含我的主要功能,以及基本操作,而Cache.h实际上只是存在这个指针。

由于问题肯定存在于Cache.h中,我将首先发布,其他一切都要遵循。同样,错误位置应该是显而易见的。希望我对指针的理解和一个​​简单的解决方案有些错误。

谢谢!

Cache.h`

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

using namespace std;

//CLASS TO STORE SIMPLE "CACHE"

class Cache
{


 private:

  struct node
  {
    double val;
    string cacheName;
    string cacheOp;
    node * next;
  };

  node * cacheArr[26];





 public:

    //CONSTRUCTOR, SET VALUES OF cacheArr TO NULL
    Cache()
      {
        for (int i = 0; i < 26; i++)
          {
            cacheArr[i] = new node;
          }
      }



    //ADD AN ELEMENT TO CACHE
    void addElement (string file, string op, double value)
    {
      node** p;
      char ch = file[0];
      //convert
      int alphaNum  = (int)(ch - 'A');

      cout << "\nALPHA NUM = " << alphaNum << " -- ch = " << ch << endl;

      cout << "TEST PRE";
      /*

        HERE LIES THE PROBLEM
        vvvvvvvvvvvvvvvvvvvvv

      */
      p* = cacheArr[alphaNum];
 cout << "\nTEST";

      if (p == NULL)
        {
          //no values starting with 'ch' have been used
          //create new node

          p->cacheName = file;
          p->cacheOp = op;
          p->val = value;
          p->next = NULL;
          return;
        }
      else if (p->next == NULL)
        {
          //list has  one value, add to list if so
              p = p->next;
              p->cacheName = file;
              p->cacheOp = op;
              p->val = value;
              p->next = NULL;
              return;
        }

      //list has 2+ elements
      //bring p to last element
      while(p!=NULL)
            {
              p = p->next;
            }
`          //p is at end of list

          p->cacheName = file;
          p->cacheOp = op;
          p->val = value;
          p->next = NULL;


          return;
    }


    //checks to see if file already in cache
    bool checkCache(string file, string op)
    {
      char ch = file[0];
      int numAlpha = (int)(ch - 'A' + 1);
      node* p = cacheArr[numAlpha];
      if(p == NULL)
        {
          return false;
        }
      while(p!=NULL)
        {
          if(p->cacheName == file && p->cacheOp == op)
            {
              return true;
            }
          p = p->next;
        }
      return false;
    }



    //RETURNS VALUE OF CACHE
    double getVal(string file, string op)
    {
      char ch = file[0];
      int numAlpha = (int)(ch - 'A' + 1);
      node * p = cacheArr[numAlpha];
      while (p!=NULL)
        {
          if(p->cacheName == file && p->cacheOp == op)
            {
              return p->val;
            }
          p = p->next;
        }
      return 0;
    }




};

    //END OF CLASS

Process.cpp:

#include <iostream>
#include <fstream>
#include <vector>
#include <string>
#include <ctime>
#include "Cache.h"

using namespace std;



//PROTOTYPE
double Avg(string fileName);
int Min(string fileName);
int Max(string filename);
double  Med(string filename);




int main(){


  //VARIABLES
  int numFile;
  string fileName;
  string opName;
  fstream fileObj;
  double result;
  ofstream resultFile;
  Cache cacheObj;
  bool inCache;
  double elapsed_secs;
  //OPEN FILES. READ FROM fileObj, WRITE TO resultFile
  resultFile.open("results.out");
  cout << "\n\n\n\n\n\n" << endl;
  fileObj.open("commands.in");
  fileObj >> numFile;


  //ITERATE THROUGH FILES IN commands.in
  for (int i = 0; i < numFile; i++){
  fileObj >> fileName;
  fileObj >> opName;


  //CHECK IF IN CACHE
  inCache = cacheObj.checkCache(fileName, opName);

  if (inCache==false)
    {



  //DO AVG OP
    if (opName == "Avg")
      {
        cout << "\n\nAvg file found. Filename  = " << fileName<<endl;
        clock_t begin = clock();
        result = Avg(fileName);
        cout << "test";
        clock_t end = clock();
        cacheObj.addElement(fileName, opName, result);
        elapsed_secs = double(end - begin) / CLOCKS_PER_SEC;
        cout << "Time for OP : " << elapsed_secs << endl;
        cout << "result = " <<  result;
        resultFile << fileName << " " << opName << ": " << result << " in " << elapsed_secs << " seconds" << endl;

      }

    //DO MIN OP
    if (opName == "Min")
      {
        cout <<"\n\nMin file found. Filename = " << fileName << endl;
        clock_t begin = clock();
        result = Min(fileName);
        clock_t end = clock();
        cacheObj.addElement(fileName, opName, result);
        elapsed_secs = double(end - begin) / CLOCKS_PER_SEC;
        cout << "Time for OP : " << elapsed_secs << endl;
        cout << "result = " << result;
        resultFile << fileName << " " << opName << ": " << result << " in " << elapsed_secs << " seconds" << endl;

      }

    //DO MAX OP
    if (opName == "Max")
      {
        cout <<"\n\nMax file found. Filename = " << fileName << endl;
        clock_t begin = clock();
        result = Max(fileName);
        clock_t end = clock();
        cacheObj.addElement(fileName, opName, result);
        elapsed_secs = double(end - begin) / CLOCKS_PER_SEC;
        cout << "Time for OP : " << elapsed_secs << endl;

        cout << "result = " << result;
        resultFile << fileName << " " << opName << ": " << result << " in " << elapsed_secs << " seconds" << endl;

      }

    //DO MED OP
    if (opName == "Med")
      {
        cout << "\n\nMed file found. Filename = " << fileName << endl;
        clock_t begin = clock();
        result = Med(fileName);
        clock_t end = clock();
        cacheObj.addElement(fileName, opName, result);
        elapsed_secs = double(end - begin) / CLOCKS_PER_SEC;
        cout << "Time for OP : " << elapsed_secs << endl;

        cout << "result = " << result;
        resultFile << fileName << " " << opName << ": " << result << " in " << elapsed_secs << " seconds" << endl;

      }

    }else if(inCache == true)
    {
 clock_t begin = clock();
      result =  cacheObj.getVal(fileName, opName);
      clock_t end = clock();
      elapsed_secs = double(end-begin) / CLOCKS_PER_SEC;
      cout << "Time for OP: " << elapsed_secs << endl;
      resultFile << fileName << " " << opName << ": " << result << " in " << elapsed_secs << " seconds " << endl;
    }

    //END OF FOR LOOP
  }

  //END OF MAIN
  return 0;
}

//COMPUTE AVG AS DOUBLE, RETURN
  double Avg(string filename)
  {
  fstream file;
  string name = filename + ".data";
  file.open(name.c_str());
  if (file.fail())
    {
  cout << "The file was not found" << endl;
  return 0;
}
  int count = 0;
  double allNum = 0;
  double current;
  double result;
  while(file)
    {

      file >> current;
      allNum += current;
      count++;
    }


  //WHY IS IT ADDING THE FINAL NUMBER TWICE?!
  //THIS PART OF THE CODE IS BROKEN
  result = allNum / count-1;

  return result;
  }




//COMPUTE THE MIN AS INT
  int Min(string filename)
  {
    fstream file;
    string name = filename + ".data";
    file.open(name.c_str());
        if (file.fail())
      {
       cout << "The file was not found" << endl;
        return 0;
      }

        int min;
        int test;
        file >> min;
        while (file)
          {
            file >> test;
            if (test < min)
              min = test;
          }

        return min;
  }



//COMPUTE MAX AS INT
int Max(string filename)
{
  fstream file;
  string name = filename + ".data";
  file.open(name.c_str());
  if (file.fail())
    {
      cout << "The file was not found" << endl;
      return 0;
    }
  int max = 0;
  int test;
  file >> max;
  while (file)
    {
      file >> test;
      if (test >  max)
        max = test;
    }

  return max;
}




//COMPUTE THE MED
double Med(string filename){
  fstream file;
  string name = filename + ".data";
  file.open(name.c_str());
  if (file.fail())
    {
      cout << "The file was not found" << endl;
      return 0;
    }
  double val;
  vector<double> medVect;
  int count = 0;
  //store file in vector
  while(file)
    {
      file >> val;
      medVect.push_back(val);
      count++;
    }
  //sort the vector
  double temp;
  int vSize = medVect.size();
  for (int i = 0; i < vSize; i++)
    {
      for (int j = 0; j < vSize; j++)
        {
          if (medVect.at(i) > medVect.at(j))
            {
              temp =  medVect.at(i);
              medVect.at(i) = medVect.at(j);
              medVect.at(j) = temp;
            }
        }
    }

  //find the median for:

  //odd values
  if (vSize %2 == 1)
    {
      int mid = vSize / 2;
      return medVect.at(mid+1);
    }
      int mid = vSize / 2;
      double mid1 = medVect.at(mid);
      double mid2 = medVect.at(mid+1);
      double result = (mid1 + mid2) / 2;
      return result;

      //SAME THING, CODE READS LAST LINE OF FILE TWICE...NEED TO FIX
}

Commands.in

6
A Min
B Max
C Avg
A2 Max
B Max
ABC Med

A.Data`

20
20
30
30
40
40

`

忘了,我得到的错误代码。

[dilleyj@cs1 HW6]$ g++ -Wall -o process Process.cpp
In file included from Process.cpp:6:0:
Cache.h: In member function ‘void Cache::addElement(std::string, std::string, double)’:
Cache.h:59:7: error: expected primary-expression before ‘=’ token
    p* = cacheArr[alphaNum];
       ^
Cache.h:67:8: error: request for member ‘cacheName’ in ‘* p’, which is of pointer type ‘Cache::node*’ (maybe you meant to use ‘->’ ?)
     p->cacheName = file;
        ^
Cache.h:68:8: error: request for member ‘cacheOp’ in ‘* p’, which is of pointer type ‘Cache::node*’ (maybe you meant to use ‘->’ ?)
     p->cacheOp = op;
        ^
Cache.h:69:8: error: request for member ‘val’ in ‘* p’, which is of pointer type ‘Cache::node*’ (maybe you meant to use ‘->’ ?)
     p->val = value;
        ^
Cache.h:70:8: error: request for member ‘next’ in ‘* p’, which is of pointer type ‘Cache::node*’ (maybe you meant to use ‘->’ ?)
     p->next = NULL;
        ^
Cache.h:73:16: error: request for member ‘next’ in ‘* p’, which is of pointer type ‘Cache::node*’ (maybe you meant to use ‘->’ ?)
    else if (p->next == NULL)
                ^
Cache.h:76:14: error: request for member ‘next’ in ‘* p’, which is of pointer type ‘Cache::node*’ (maybe you meant to use ‘->’ ?)
       p = p->next;
              ^
Cache.h:77:9: error: request for member ‘cacheName’ in ‘* p’, which is of pointer type ‘Cache::node*’ (maybe you meant to use ‘->’ ?)
      p->cacheName = file;
         ^
Cache.h:78:9: error: request for member ‘cacheOp’ in ‘* p’, which is of pointer type ‘Cache::node*’ (maybe you meant to use ‘->’ ?)
      p->cacheOp = op;
         ^
Cache.h:79:9: error: request for member ‘val’ in ‘* p’, which is of pointer type ‘Cache::node*’ (maybe you meant to use ‘->’ ?)
      p->val = value;
         ^
Cache.h:80:9: error: request for member ‘next’ in ‘* p’, which is of pointer type ‘Cache::node*’ (maybe you meant to use ‘->’ ?)
      p->next = NULL;
         ^
Cache.h:88:13: error: request for member ‘next’ in ‘* p’, which is of pointer type ‘Cache::node*’ (maybe you meant to use ‘->’ ?)
      p = p->next;
             ^
Cache.h:93:8: error: request for member ‘cacheName’ in ‘* p’, which is of pointer type ‘Cache::node*’ (maybe you meant to use ‘->’ ?)
     p->cacheName = file;
        ^
Cache.h:94:8: error: request for member ‘cacheOp’ in ‘* p’, which is of pointer type ‘Cache::node*’ (maybe you meant to use ‘->’ ?)
     p->cacheOp = op;
        ^
Cache.h:95:8: error: request for member ‘val’ in ‘* p’, which is of pointer type ‘Cache::node*’ (maybe you meant to use ‘->’ ?)
     p->val = value;
        ^
`

1 个答案:

答案 0 :(得分:1)

至少有两个问题。

p* = cacheArr[alphaNum];应为*p = cacheArr[alphaNum];

然后,在同一个函数中,p->应为(*p)->,因为p是指向指针的指针。