2015-01-13 6 views
-1

Для моей команды по робототехнике мне было поручено написать функцию, которая позволит нам хранить значения переменных в текстовом файле, чтобы мы могли обновлять значения без необходимости обновления кода. пример: увеличение скорости колеса. формат, который мы определили; пробел или #, имя переменной, пробел, значение переменной.Чтение переменных из текстового файла C++

variable1 1 
#variable3 4 
setspeed 10 

Что мне нужно сделать, так как требуется переменная, моя функция будет искать первый столбец для запрашиваемой переменной и вернуть ее. было рекомендовано, чтобы я использовал fgets для чтения по строкам, но я не уверен, как разбить линию, используя наш формат.

+3

Для поиска используйте «Переполнение стека» для «чтения файла C++». До сих пор существует слишком много вариаций. –

+0

Также есть много библиотек для такого рода вещей (например, [libini] (http://sourceforge.net/projects/libini/)) - лучше использовать один из них, чем изобретать колесо. –

+0

Большинство примеров используют 'std :: getline', а также' std :: string' для строки (типы текста). Вы ограничены использованием 'fgets'? –

ответ

0

Вы можете разбить линию в формате, указанном с помощью std::stringstream. Вот пример:

std::string line;    // A line of key/values from text 
    std::string key;    // Temporary for our key 
    std::string value;    // Temporary for our value 
    std::ifstream stream(path);  // Load the file stream 
    std::stringstream splitter;  // Prepare a stringstream as a splitter (splits on spaces) for reading key/values from a line 

    // Make sure we can read the stream 
    if (stream) { 
     // As long as there are lines of data, we read the file 
     while (std::getline(stream, line)) { 
      splitter << line;         // Load line into splitter 
      splitter >> key;         // Read the key back into temporary 
      splitter >> value;         // Read the value back into temporary 
      splitter.clear();         // Clear for next line 
      variables[key] = value;        // Store the key/value pair in our variable map. 
     } 
    } 
    else { 
     // The file was not found or locked, etc... 
     std::cout << "Unable to open file: " << path << std::endl; 
    } 

Не забудьте включить <string> и <sstream>. Я думаю, вам также понадобится <iostream> для getline().

ПРИМЕЧАНИЕ: У меня есть полный рабочий пример этого, который я могу опубликовать, но я решил, что оставлю вам полное упражнение. Если вам нужно больше, дайте мне знать, но я считаю, что лучше всего изучить, исследуя решение, вместо того, чтобы оно было передано вам. Удачи вам на роботе!

ВАЖНО: Мне просто пришло в голову, что мое решение не касается префикса white-space или '#', который вы выражаете. Я бы рекомендовал либо изменить требования, либо вам придется использовать это как промежуточную точку для решения немного более сложного разбора. Например, вы можете проверить, свободен ли ключ, и если да, то переменная имела префикс пробела. Затем вы повторно загрузите ключ и добавьте перед ним пробел, чтобы получить свое окончательное имя переменной. Аналогично, вы можете проверить первый символ ключа для «#». Это немного больше работы, но должно быть выполнимо, изменив мой пример кода.

0
//---------------------------------------------------------------------------- 
#include <iostream> 
#include <sstream> 
#include <fstream> 
//---------------------------------------------------------------------------- 
class Entry 
{ 
public: 
    Entry():name("\0"), value(0.0){} 
    //Entry (std::string _name, double _value): name(_name), value(_value){} 
    ~Entry() {} 

    friend std::ostream& operator<<(std::ostream& os, const Entry& entry); 
    friend std::istream& operator>> (std::istream& is, Entry& entry); 

    std::string GetName() {return name;} 
    double GetValue() {return value;} 

private: 
    std::string name; 
    double value; 
} ; 

std::istream& operator>> (std::istream& is, Entry& entry) 
{ 
    is >> entry.name >> entry.value; 
    return is; 
} 

std::ostream& operator<<(std::ostream& os, const Entry& entry) 
{ 
    os << entry.name << " = " << entry.value << "\n"; 
    return os; 
} 

//---------------------------------------------------------------------------- 
int main() 
{ 
     std::string filename = "test.txt"; 
     std::ifstream ifs (filename); 

     if (ifs.is_open()) 
     { 
      std::cout << "Variable name:\t"; 
      std::string name; 
      std::getline(std::cin, name); 
      Entry entry; 
      bool found = false; 

      while (ifs >> entry) 
       if (entry.GetName() == name) 
       { 
        found = true; 
        std::cout << entry; 
        break; 
       } 

      if (!found) 
       std::cout << "The name is wrong\n"; 

      ifs.close(); 
     } 
     else 
      std::cout << "Error opening file "<< filename; 

     std::cin.sync(); 
     std::cin.get(); 
     return 0; 
} 
//----------------------------------------------------------------------------- 

Я считаю, что начать переменное имя с места - это не отличная идея. Я предлагаю «%» и «#» внести изменения, если это необходимо.

Смежные вопросы