файл C++ io и разделение разделителем

Словари не поддерживают индексирование, поэтому для печати «Джон» вы не можете индексировать его, однако следующий код может содержать слово:

if "John" in contacts:
   print("Contact details:","John",contacts["John"])

Надеюсь, это поможет

8
задан darudude 6 November 2008 в 01:49
поделиться

7 ответов

Нет действительно ничего неправильно с fscanf, который является, вероятно, быстрым решением в этом случае. И это так же коротко и читаемо как код Python:

FILE *fp = fopen("file.dat", "r");
int x, y, z;
std::vector<int> vx, vy, vz;

while (fscanf(fp, "%d, %d, %d", &x, &y, &z) == 3) {
  vx.push_back(x);
  vy.push_back(y);
  vz.push_back(z);
}
fclose(fp);
4
ответ дан 5 December 2019 в 11:28
поделиться

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

int main(int argc, char* argv[])
{
    ifstream file(argv[1]);

    const unsigned maxIgnore = 10;
    const int delim = ',';
    int x,y,z;

    vector<int> vecx, vecy, vecz;

    while (file)
    {
        file >> x;
        file.ignore(maxIgnore, delim);
        file >> y;
        file.ignore(maxIgnore, delim);
        file >> z;

        vecx.push_back(x);
        vecy.push_back(y);
        vecz.push_back(z);
    }
}

Хотя, если бы я собирался использовать повышение, я предпочел бы простоту токенизатора к regex... :)

6
ответ дан 5 December 2019 в 11:28
поделиться

Что-то как:

vector<int> inint;
vector<int> inbase;
vector<int> outbase;
while (fgets(buf, fh)) {
   char *tok = strtok(buf, ", ");
   inint.push_back(atoi(tok));
   tok = strtok(NULL, ", ");
   inbase.push_back(atoi(tok));
   tok = strtok(NULL, ", ");
   outbase.push_back(atoi(tok));
}

Кроме с проверкой ошибок.

2
ответ дан 5 December 2019 в 11:28
поделиться

станд.:: getline позволяет Вам читать строку текста, и можно использовать строковый поток для парсинга отдельной строки:

string buf;
getline(cin, buf); 
stringstream par(buf);

char buf2[512];
par.getline(buf2, 512, ','); /* Reads until the first token. */

После того как Вы получаете строку текста в строку, можно на самом деле использовать любую функцию парсинга, которую Вы хотите, даже sscanf (buf.c_str (), "%d, %d' %d", &i1, &i2, &i3), при помощи atoi на подстроке с целым числом, или через некоторый другой метод.

Можно также проигнорировать нежелательные символы во входном потоке, если Вы знаете, что они там:

if (cin.peek() == ',')
    cin.ignore(1, ',');
cin >> nextInt;  
1
ответ дан 5 December 2019 в 11:28
поделиться

Если Вы не возражаете пользоваться библиотеками Boost...

#include <string>
#include <vector>
#include <boost/lexical_cast.hpp>
#include <boost/regex.hpp>

std::vector<int> ParseFile(std::istream& in) {
    const boost::regex cItemPattern(" *([0-9]+),?");
    std::vector<int> return_value;

    std::string line;
    while (std::getline(in, line)) {
        string::const_iterator b=line.begin(), e=line.end();
        boost::smatch match;
        while (b!=e && boost::regex_search(b, e, match, cItemPattern)) {
            return_value.push_back(boost::lexical_cast<int>(match[1].str()));
            b=match[0].second;
        };
    };

    return return_value;
}

Это вытягивает строки от потока, затем использует Повышение:: библиотека RegEx (с группой получения) для извлечения каждого числа из строк. Это автоматически игнорирует что-либо, что не является верным номером, хотя это может быть изменено, если Вы желаете.

Это - все еще приблизительно двадцать строк с #includes, но можно использовать его для извлечения по существу чего-либо из строк файла. Это - тривиальный пример, я использую в значительной степени идентичный код для извлечения тегов и дополнительных значений от поля базы данных, единственным существенным различием является регулярное выражение.

Править: Ой, Вы хотели три отдельных вектора. Попробуйте эту небольшую модификацию вместо этого:

const boost::regex cItemPattern(" *([0-9]+), *([0-9]+), *([0-9]+)");
std::vector<int> vector1, vector2, vector3;

std::string line;
while (std::getline(in, line)) {
    string::const_iterator b=line.begin(), e=line.end();
    boost::smatch match;
    while (b!=e && boost::regex_search(b, e, match, cItemPattern)) {
        vector1.push_back(boost::lexical_cast<int>(match[1].str()));
        vector2.push_back(boost::lexical_cast<int>(match[2].str()));
        vector3.push_back(boost::lexical_cast<int>(match[3].str()));
        b=match[0].second;
    };
};
1
ответ дан 5 December 2019 в 11:28
поделиться

почему не тот же код как в Python :)?

std::ifstream file("input_hard.dat");
std::vector<int> inint, inbase, outbase;

while (file.good()){
    int val1, val2, val3;
    char delim;
    file >> val1 >> delim >> val2 >> delim >> val3;

    inint.push_back(val1);
    inbase.push_back(val2);
    outbase.push_back(val3);
}
1
ответ дан 5 December 2019 в 11:28
поделиться

Если Вы хотите смочь масштабироваться к более твердым форматам ввода, необходимо рассмотреть дух, синтаксический анализатор повышения combinator библиотека.

Эта страница имеет пример, которые почти делают то, в чем Вы нуждаетесь (с реалами и одним вектором хотя)

0
ответ дан 5 December 2019 в 11:28
поделиться
Другие вопросы по тегам:

Похожие вопросы: