2013-09-22 5 views
0

Для моего проекта мне нужно перезаписать метод operator >> для чтения в массиве чисел из текстового файла. Это мой первый случай, когда я делаю все это, и я довольно потерян. Мой код до сих пор выглядит так.Чтение txt-файла

std::istream& operator>>(std::istream& in, bigint array){ 

      bool semi = false ; 

      while(!semi){ 
      if(get() = ';') 
       semi = true ; 
      in <<get(); 
      } 
     return in ; 
    } 

И файл выглядит следующим образом.

10000000000000000000000000000000000345; 
299793000000 
00000000000000000000067; 
4208574289572473098273498723475; 
28375039287459832728745982734509872340985729384750928734590827098752938723; 
99999999; 99999999; 

Каждый новый массив останавливается, когда она попадает ";'. Белые пробелы и конечные строки меня тоже путают. Любая помощь будет оценена благодаря вам.

+3

Вы пропустили вопрос – P0W

+2

'get() = ';'' скорее всего будет 'get() == ';''. Предварительным назначением является последнее сравнение. Хотя, вероятно, это тоже неправильно. – Dukeling

+0

Возможный дубликат [Чтение txt-файла] (http://stackoverflow.com/questions/18949872/reading-a-txt-file) – hexacyanide

ответ

2

Вы хотите использовать

bigint& array 

принять значение по ссылки (или вы не могли бы вставить цифры прочитать в него).

Кроме того, вы хотите использовать

char ch; 
in >> ch; 

вместо in << get() (который не компилируется). А еще лучше, добавить обработку ошибок:

if (!(in >> ch)) 
{ 
    // we're in trouble (in.rdstate(), in.eof(), in.fail() or in.bad() to know more) 
} 

Если вы хотите использовать in.get(), вы должны быть готовы, чтобы пропустить свой собственный пробел (включая символ новой строки). Я бы предпочел здесь std::istream_iterator, потому что он автоматически сделает это (если в действительности действует флаг std::ios::skipws, который он по умолчанию).

Так вот simplist подход (который в основном принимает входные данные корректны и пробельные игнорируемые):

#include <vector> 
#include <istream> 
#include <iterator> 

struct bigint 
{ 
    std::vector<char> v; // or whatever representation you use (binary? bcd?) 
}; 

std::istream& operator>>(std::istream& in, bigint& array) 
{ 
    for (std::istream_iterator<char> f(in), l; f != l; ++f) { 
     if (*f>='0' && *f<='9') 
      array.v.push_back(*f - '0'); 
     else if (*f==';') 
      break; 
     else 
      throw "invalid input"; 
    } 

    return in; 
} 

#include <iostream> 
#include <sstream> 

int main() 
{ 
    std::istringstream iss(
      "10000000000000000000000000000000000345;\n" 
      "299793000000\n" 
      "00000000000000000000067;\n" 
      "4208574289572473098273498723475;\n" 
      "28375039287459832728745982734509872340985729384750928734590827098752938723;\n" 
      "99999999; 99999999;\n"); 

    bigint value; 
    while (value.v.clear(), iss >> value) 
     std::cout << "read " << value.v.size() << " digits\n"; 
} 

Посмотреть Live on Coliru

2

Там довольно много замешательства здесь. Я просто перечислил некоторые моменты, но у вас есть возможность пойти, даже если вы исправите эти вещи.

  1. Что именно вы читаете? Вы говорите, что вы читаете массив чисел, но ваш код говорит, что это

    std::istream& operator>>(std::istream& in, bigint array){ 
    

    Я мог бы быть неправильно, но bigint звучит как один номер для меня. Я бы ожидать что-то вроде этого

    std::istream& operator>>(std::istream& in, std::vector<bigint>& array){ 
    
  2. Который приносит мне ко второй точке, оператор >>, как ожидается, изменить это второй аргумент, который означает, что он не может быть передан по значению, вы должны использовать ссылку. Другими словами, это неправильно

    std::istream& operator>>(std::istream& in, X x){ 
    

    , но это нормально

    std::istream& operator>>(std::istream& in, X& x){ 
    
  3. Вы пытаетесь прочитать массив bigints, так что вам нужен цикл (у вас есть, что), и каждый раз округлять цикл вы прочтете один bigint. Итак, вам нужен способ прочитать один bigint, есть ли у вас это?В вашем вопросе или вашем коде ничего нет, что указывает на то, что вы имеете возможность читать bigint, но это, безусловно, важно, что вы делаете. Поэтому, если у вас еще нет кода для чтения bigint, вы можете забыть об этом упражнении до тех пор, пока не получите этот код, поэтому сначала работайте над этим. Когда вы можете прочитать один bigint, только тогда вы должны вернуться к проблеме чтения массива bigints.

  4. Другая сложная часть - это условие остановки, вы останавливаетесь, когда читаете точку с запятой (возможно, перед пробелом). Таким образом, вам нужен способ прочитать следующий непространственный символ, и, самое главное, вам нужно сделать непрочитанным, если он окажется не точкой с запятой. Так что вам нужно что-то вроде этого

    if (!(in >> ch) || ch == ';') 
    { 
        // quit, either no more input, or the next char is a semicolon 
        break; 
    } 
    
    in.putback(ch); // unread the last char read 
    // read the next bigint 
    

Надеется, что это помогает.