Как получить доступ к определенному значению в текстовом файле, используя C ++ - PullRequest
1 голос
/ 01 сентября 2011

мой текстовый файл имеет такую ​​структуру, и это значения

15.32 15.00 14.58 14.36 17.85 01.95 15.36 
14.58 21.63 25.00 47.11 48.95 45.63 12.00
74.58 52.66 45.55 47.65 15.55 00.23 78.69

каждый столбец - это другой тип данных, первый столбец - взвешивание, второй - размер и т. Д.пользователь запрашивает, например, вес, который будет первым столбцом

15.32
14.58
74.58

, и мне нужно напечатать

reg 1 reg 2 reg 3
15.32 14.58 74.58

, также пользователь может запросить другой столбец, который я не знаюКак я могу это сделать, я могу печатать только первую строку

15.32 15.00 14.58 14.36 17.85 01.95 15.36 

, используя этот код, но только если я использую целочисленные файлы, если они двойные, приведенный ниже код ничего не делает

string nextToken;
while (myfile>> nextToken) {
    cout << "Token: " << nextToken << endl;
}

но я не знаю, как перемещаться между столбцами и строками

Я использую эту структуру

struct measures{
    string date;
    double weight;
    double size;
    double fat;
    double imc;
    double chest;
    double waist;
} dataclient;

Я читаю такие значения

ofstream file;
file.open (dataclient.id, ios::out | ios::app);
if (file.is_open())
{
    cout<<"   ENTER THE WEIGH"<<endl;
    cin>>dataclient.weigh;
    file<<dataclient.weigh<<" ";

    cout<<"   ENTER THE SIZE"<<endl;
    cin>>dataclient.size;
    file<<dataclient.size<<" ";

    cout<<"  ENTER  % FAT"<<endl;
    cin>>dataclient.fat;
    file<<dataclient.fat<<" ";

это может быть сделано несколько раз для пользователя, а затем закрывается файл

, после чего пользователь запрашивает любое значение

Ответы [ 4 ]

2 голосов
/ 01 сентября 2011

Простой способ сделать такие вещи - создать структуру или класс для инкапсуляции данных, которые появляются в «записи». (Запись является строкой) Прочитайте каждую строку в новом экземпляре этого класса, а затем просто извлеките данные из соответствующих переменных-членов, которые вам нужны.

РЕДАКТИРОВАТЬ: Кроме того, я хотел бы добавить, что этот ответ дал мне 1337 повторений:)

0 голосов
/ 01 сентября 2011

Взгляните на эту тему MSDN Forum, Visual C ++ General Существует решение для файла с двумя столбцами, но это может быть любое количество столбцов. Вы читаете текст в std :: string, затем пишете его в std :: vector и затем работаете с его элементами.

0 голосов
/ 01 сентября 2011

Этот код загружает весь файл measure s в вектор с именем data и запоминает все это.Затем, когда пользователь хочет получить доступ к определенному measure, вы можете просто прочитать его из data.

// This demo will only handle three records.
// if you want to work with more records, change this number
const unsigned int numRecords = 3;
// This defines a structure called measures, as you detailed
// I don't create a measure object, I simply tell the computer what it is.
struct measures{ 
    string date; 
    double weight; 
    double size; 
    double fat; 
    double imc; 
    double chest; 
    double waist; 
};
// This is complicated
// Basically, it makes it really easy to load a measure from a stream.
//   like a file stream or std::cin.
// I refer to this as "operator>>"
istream& operator>>(istream& i, measures& m) {
    // The function takes a stream and a measure
    //   and reads each member from the stream one by one into the measure 
    i >> m.date;
    i >> m.weight;
    i >> m.size;
    i >> m.fat;
    i >> m.imc;
    i >> m.chest;
    i >> m.waist;
    // The "operator>>()" function must always return the stream
    return i;
}

int main() {
  // A vector is a container, that holds objects
  // A vector<measures> is a container that contains measure objects.
  // I make a vector<measures> named "data".
  // I use the constructor that takes the size of the vector.
  // We want 3 measures, so I give it the number recNum(3).
  // This makes a container of recNum(3) measures.
  vector<measures> data(numRecords );
  // I assume you already know how to open a file
  std::ifstream myfile("myfile.txt");
  // Now we want to go through the file and load measures
  // recNum will be the line we're at
  // we go from 0 to numRecords(3), one at a time
  for(int recNum=0; recNum<numRecords; recNum += 1) {
      // First we get the measure to be loaded from the container
      // Since the container "owns" the object, I have to get the
      //   object by reference.  That's the "&" symbol.
      // It means I'm changing it, but I don't own it.
      // It belongs to the container.
      // We use the [recNum] to tell it which measure we want
      measures& newMeasure = data[recNum];
      // Now that we have the Measure that needs to be loaded,
      //   we call the special "operator>>" function that I wrote above
      // Yeah.   It's like magic or something.          
      myfile >> data[recNum];
  }
  // Done loading the measures into the container
  // The container now contains numRecords(3) measures.

  // Figure out the record that the user wants here.
  //   and put it in recordNum. (Remember that 0 is the first item,
  //   so 1 is the second item)
  int recordNum = 1; 

  // Again, we get the measure to be loaded from the container
  // We use the [recNum] to tell it which measure we want
  // Since the container "owns" the object, We have to get the
  //   object by reference again.  We don't "own" the object
  measures& userMeasure = data[recordNum];
  // We can access the weight of this measure with userMeasure.weight
  cout << "Record number " <<  recordNum;
  cout << " has a weight of: " << userMeasure .weight << ".\n";
}
0 голосов
/ 01 сентября 2011

Еще более простой способ - создать функцию с двумя параметрами: начальный элемент и «шаг» или количество элементов в строке. Затем вы можете пропустить элементы до начального элемента, а затем пропустить шаг между последовательными элементами:

void printcolumn(int start, int stride, ifstream &in)
{
  string nextToken;

  // skip until the start
  while(start-->0) in >> nextToken;

  // and then start writing the items
  while (in >> nextToken) 
  {
    cout << "Token: " << nextToken << endl;

    // and skip the stride
    for(int i=1;i<stride;++i) in >> nextToken;
  }
}

В вашем конкретном примере вы бы назвали его printcolumn(0, 7, myfile);

...