2014-09-06 6 views
0

Я пишу программу на C++, которая читается в файле. Файл должен содержать только числа, а если нет, он просто выдает ошибку.C++ Чтение файла только с номерами

В настоящее время я могу прокрутить файл и строки и получить каждый токен и рассказать, что такое каждый токен, но, видя, что я начинаю с ++, я не знаю, как включать только цифры.

Пример файл будет:

1 2 3 4 5.645 50603 0.543 5.0 
100 5.555555 600 1 0 5 

       67.64 

65.6         70 

       <spaces> 

      90 

Я попытался отрываясь несколько способами, и я попытался использовать пространство для разделителя, но я должен объяснить пустую строку пространств, которой разделители Messes вверх.

Я пробовал эти методы до сих пор:

Этот метод принимает в «5.0», но только печатает его, как «5»: двойной я;

while(fin >> i) 
{ 
    cout << " Token value: " << i << endl; 
} 

Этот метод не будет принимать новой строки/перевод строки только с пробелами:

int i = 0; 
int lineNumber = 1; 
char token; 
const char* const delimeter = " "; 
while (fin.good()) 
{ 
    // read line into memory with a max length of 10 characters per line 
    char buffer[1024]; 
    fin.getline(buffer, 1024); 

    // array to hold the values until compution 
    char* token[1024] = {}; 


    // strtok splits a string into tokens 
    // get the first token 
    token[0] = strtok(buffer, delimeter); 

    // check if the first line is blank (blank is set to 0) 
    if (token[0]) 
    { 
     for (i = 1; i < 1024; i++) 
     { 
      // get more tokens 
      token[i] = strtok(0, delimeter); 

      // check if there are no more tokens 
      if (!token[i]) 
      { 
       break; 
      } 
     } 
    } 

    for (int j = 0; j < i; j++) 
    { 

     // if (token[j] == " ") cout << " this is a space" << endl; 
     cout << " Line: " << lineNumber << " --- Token[" << j << "] = " << token[j] << endl; 
    } 
    cout << endl; 
    i++; 
    lineNumber++; 

} 

Любые предложения для новичка в C++ (У меня есть опыт Java)?

EDIT: Период углу случай:

Там, кажется, нет никакого признания периода, если оно находится на последней строке и единственный символ. Это не ошибка и не распечатывать период:

12 35 67777.75 
54433 
. 

Однако это бросить правильную ошибку, если это так:

12 36 67777.75 
. 
54433 
+0

Какой код вы пробовали? – Gutblender

+0

Добавленный код, который я пробовал до сих пор. – Sej

+0

Важно ли читать файл по строкам, или вам просто нужно читать цифры по одному? – Galik

ответ

1

Это может быть полезно для вас.

Вы можете прочитать в номерах один за другим таким образом:

int main() 
{ 
    std::ifstream fin("mydatafile.txt"); 

    // check for errors 
    if(!fin.is_open()) 
    { 
     std::cerr << "ERROR: opening input file:" << std::endl; 
     return 1; // error code 1 
    } 

    double d; 
    while(fin >> d) // skips spaces and newlines automatically 
    { 
     // do what you want with the number d here (print it?) 
     std::cout << d << '\n'; 
    } 

    // Did we read all the data or was there a problem? 
    if(!fin.eof()) 
    { 
     std::cerr << "ERROR: failed to read all the data from input file:" << std::endl; 
     return 2; // error code 2 
    } 

} 

while(fin >> d) очень идиоматический. Это обеспечило, чтобы тело цикла выполнялось только в том случае, если чтение было успешным. Он учитывает, что ошибки происходят во время прочитанного.

EDIT:

Добавлен тест, чтобы увидеть, если файл был прочитан весь путь до конца или не

EDIT:

В качестве альтернативы вы можете прочитать каждую запись из текстовый файл в std::string, а затем проверьте, преобразуется ли std::string в double или нет:

#include <fstream> 
#include <sstream> 
#include <iostream> 

int main() 
{ 
    std::ifstream fin("mydatafile.txt"); 

    // check for errors 
    if(!fin.is_open()) 
    { 
     std::cerr << "ERROR: opening input file:" << std::endl; 
     return 1; // error code 1 
    } 

    std::string s; 
    while(fin >> s) // skips spaces and newlines automatically 
    { 
     // now see if we can convert s into a number by 
     // turning s into an input stream and read it into a number 

     double d; 
     if(std::istringstream(s) >> d) 
     { 
      // do what you want with the number d here (print it?) 
      std::cout << d << '\n'; 
     } 
     else 
     { 
      std::cerr << "ERROR: bad data: \"" << s << "\"" << std::endl; 
      // continue? Or not? 
     } 
    } 

    if(!fin.eof()) 
    { 
     std::cerr << "ERROR: failed to read all the data from input file:" << std::endl; 
     return 2; // error code 2 
    } 
} 
+1

Вместо использования цикла while вы можете использовать for-loop, чтобы ограничить область d, как в for (double d; fin >> d;) {/ * stuff, используя d * /}. – user515430

+0

Это полезно и работает, за исключением случаев, когда я использую буквы. Мне нужно убедиться, что файл ТОЛЬКО содержит числа, и поэтому, когда я помещаю письмо в файл, он встает на эту букву, а затем просто терпит неудачу, что и нужно. Но тогда нет способа проверить, не получилось ли это правильно или нет. if (stream.fail()) происходит, если файл нашел что-то не число, но также не удалось, если поток завершен, а затем завершен, поэтому он бросается в обоих случаях. Есть ли какой-либо законченный или завершенный оператор для ifstream, чтобы увидеть, успешно ли он прошел проверку? – Sej

+0

@Sej Если весь файл прочитан правильно, должен быть установлен флаг eof (конец файла). Вы можете проверить это с помощью 'fin.eof()'. Я добавлю это к примеру. В качестве альтернативы вы можете читать строки, а не цифры, и пытаться преобразовать каждую строку в число. Если одна из строк терпит неудачу, сообщите о сбое и продолжите или остановите в зависимости от того, что вам нужно. – Galik

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