Прекратить чтение при несовпадении форматов - PullRequest
3 голосов
/ 31 марта 2011

У меня есть файл, такой как:

 1.0000000e+01   8.0123000e+01   1.0000000e+01   1.0000000e+01   1.0000000e+01
-1.0000000e+01   1.0000000e+01   1.0001110e+01   1.0000000e+01   1.0000000e+01
 1.0000000e+01   1.0000000e+01  -5.0000000e+01   1.0000000e+01   1.0000000e+01
 //... (repeated scientific numbers)
 1 2 3 4
 2 4 5 60
 100 3 5 63
 //... (repeated integer numbers)

Я хотел бы прочитать эти числа из файла на C ++, , но только цифры в научном формате , поэтому янужен код для остановки при изменении числового формата.У меня также есть преимущество в том, что числа с плавающей точкой находятся в 5 столбцах, а целые числа - в 4 столбцах.

Итак, как лучше всего это сделать в C ++?

Ответы [ 5 ]

2 голосов
/ 31 марта 2011

Игнорирование EOL (продолжает читать целые числа):

typedef double d[5] Datum;
Datum d;
vector<Datum> data;
while (true) {
  Datum t;
  istr >> t[0] >> t[1] >> t[2] >> t[3] >> t[4];
  if (!istr) break;
  data.push_back(t);
}

Использование количества столбцов и EOL:

while (istr) {
  string line;
  getline(istr, line);
  Datum t;
  istringstream temp(line);
  temp >> t[0] >> t[1] >> t[2] >> t[3] >> t[4];
  if (temp.fail()) break;
  data.push_back(t);
}
0 голосов
/ 31 марта 2011

regex - лучший способ сделать это, здесь вы можете попробовать fscanf ()

0 голосов
/ 31 марта 2011

Боюсь, что нет прямого способа сделать это. То есть вы не можете передавать (>>) число с плавающей точкой в ​​определенном формате. Так что, если вам нужна эта функциональность, вы должны прочитать строки как строки, а затем проанализировать их вручную. Конечно, это не означает, что вы должны строить число с плавающей запятой цифра за цифрой. После того, как вы установили границы входного файла, из которого вы хотите прочитать float, используйте stringstreams для их чтения.

0 голосов
/ 31 марта 2011

Вы можете использовать регулярные выражения, чтобы соответствовать только те, которые вам нужны: -?\d+\.\d+e[+-]\d+

Я уверен, что это не лучший способ, но если производительность не является большой проблемой, это простой выход

Предупреждение: автоматически сгенерированный код из RegexBuddy

pcre *myregexp;
const char *error;
int erroroffset;
int offsetcount;
int offsets[(0+1)*3]; // (max_capturing_groups+1)*3
myregexp = pcre_compile("-?\\d+\\.\\d+e[+-]\\d+", 0, &error, &erroroffset, NULL);
if (myregexp != NULL) {
    offsetcount = pcre_exec(myregexp, NULL, subject, strlen(subject), 0, 0, offsets, (0+1)*3);
    while (offsetcount > 0) {
        // match offset = offsets[0];
        // match length = offsets[1] - offsets[0];
        if (pcre_get_substring(subject, &offsets, offsetcount, 0, &result) >= 0) {
            // Do something with match we just stored into result
        }
        offsetcount = pcre_exec(myregexp, NULL, subject, strlen(subject), 0, offsets[1], offsets, (0+1)*3);
    } 
} else {
    // Syntax error in the regular expression at erroroffset
}
0 голосов
/ 31 марта 2011

Вы можете использовать strstr для поиска «e +» в каждой строке.

http://www.cplusplus.com/reference/clibrary/cstring/strstr/

Если вы хотите быть более навороченным, вы используете библиотеку регулярных выражений (например, boost:: regex), который также поможет вам извлечь строки из каждой строки.

...