2013-02-22 2 views
1

Мой входной файл, как это:Читать входной файл с обратной косой черты () разделителем C++

C:\Users\DeadCoder\AppData\Local\CoCreate 

творю дерево, и мне нужно абстрагировать имена каталогов при чтении из входного файла с \ разделителем. Как и в приведенном выше примере, мне нужно отдельно отделить пользователей c :, DeadCoder, Appdata .... Надеюсь, каждый понимает вопросы. Теперь рассмотрим варианты, которые у нас есть.

1-istringstream работает отлично для whitespace, но не для \.

2-strtok() работает на char. Поэтому мне пришлось бы изменить свою строку на char, и я действительно не хочу этого делать.

3- Boost Tokenizer() Это кажется интересным, и у меня нет никакого знакомства с ним в прошлом, за исключением того, что я только что заглянул в него пораньше. Я скопировал код и он выглядит так:

#include <boost/foreach.hpp> 
#include <boost/tokenizer.hpp> 
using namespace boost; 

int main(){ 

    string tempStr; 
    ifstream fin; 
    fin.open("input.txt"); 
    int i=0; 

    while (!fin.eof()){ 
     getline(fin,tempStr); 
     char_separator<char> sep("\"); // error: missing terminating " character 
     tokenizer<char_separator<char>> tokens(tempStr, sep); 
     for (const auto& t : tokens) { 
      cout << t << "." << endl; 
     } 
} 

Теперь это дает ошибку, что "error: boost/foreach.hpp: No such file or directory" может кто-то помочь мне здесь. И есть ли еще better way для чтения входного файла с \ delimiter. Пожалуйста, не используйте расширенные коды, такие как class tokenizer(), поскольку я все еще изучаю C++.

EDIT: У меня не было установленной библиотеки boost, поэтому у меня была эта ошибка. было бы очень полезно, если кто-то может объяснить лучший способ для строки tokenize без установки третьей библиотеки.

Лучшее; DeadCoder.

+0

У вас установлена ​​библиотека 'Boost'? – Mahesh

+0

Нет. Разве это не по умолчанию. – DeadCoder

+0

Это сторонняя библиотека. Загрузите его с http://www.boost.org/ – Mahesh

ответ

3

В C++ (и на другом языке на основе C) символ \ в строке или символьном литерале является символом escape. Это означает, что это escapes следующий символ в буквальном. Это значит, что у вас может быть, например, " внутри строки. Чтобы иметь \ внутри строкового литерала, вам необходимо скрыть обратную косую черту, имея два из них: "\\".

Вы можете узнать больше о допустимых escape-последовательностях в C++, например. in this reference.

Что касается проблемы с Boost, вам необходимо сообщить компилятору, где вы его установили. Это делается в свойствах проекта вашей среды IDE.


Если вы хотите разметить без с использованием библиотеки сторонних производителей, таких как Boost, есть несколько способов. Один из способов может заключаться в использовании std::istringstream и std::getline. Другой fo использует функции find и substr стандартного класса string.

+0

Хорошо, это сработало, но мне действительно нужно знать, почему я должен использовать два \\. Потому что вы не понимаете меня в приведенном выше утверждении. – DeadCoder

+0

@DeadCoder Вы знаете, как написать литерал новой строки внутри строки? Вы используете '' \ n "' правильно? Это то же самое, что использовать '' \\ "' для обозначения одной обратной косой черты. Обратная косая черта внутри символа или строки _literal_ сообщает компилятору, что следующий символ является специальным символом, который означает что-то еще. –

+0

@DeadCoder Вы должны использовать два \\, потому что это способ определения языка. –

1
char_separator<char> sep("\") 
          ^^^ You need to escape the \ . use "\\" 

\ предназначенный для обозначения последовательности эвакуации.Но to escape that escape, you need other escape

Используйте это: char_separator<char> sep("\\")

Для установки наддува LIB: Install Boost

Другой выбор:

getline(fin,tempStr); 
char *cstr=new char[tempStr.length()+1]; 
strcpy(cstr,tempStr.c_str()) 

//... Now you can use strtok() on cstr 
+0

Спасибо большое .... теперь для меня намного больше смысла. – DeadCoder

2

Любой вид обобщенной Tokenizer здесь будет избыточна. Просто используйте std::find(s.begin(), s.end(), '\\'), чтобы найти каждый разделитель, и два конструктора итератора std::string, чтобы поместить его в отдельную строку. (Ваш компилятор обрабатывает первый \ как экранирующего символа.) Что-то вроде:

std::vector<std::string> fields; 
std::string::const_iterator end = s.end(); 
std::string::const_iterator current = s.begin(); 
std::string::const_iterator next 
     = std::find(current, end, '\\'): 
while (next != end) { 
    fields.push_back(std::string(current, next)); 
    current = next + 1; 
    next = std::find(current, end, '\\'); 
} 
fields.push_back(std::string(current, next)); 

должен сделать трюк.

+0

Спасибо ..... каждый день новый материал, чтобы узнать ..... :) – DeadCoder

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