Форум программистов, компьютерный форум CyberForum.ru

Парсинг чисел из текстовика - C++

Восстановить пароль Регистрация
 
Рейтинг: Рейтинг темы: голосов - 12, средняя оценка - 4.67
Zaсk
0 / 0 / 0
Регистрация: 04.07.2011
Сообщений: 4
04.07.2011, 15:46     Парсинг чисел из текстовика #1
Я начинающий, но не знаю как справиться с заданием:

Дан текстовый файл в котором в рандомном порядке расположены вперемешку числа и фрагменты текста. Задача - сохранить во второй файл только числа, причем они должны быть отсортированы.

Т.е. как задача разделяется:
1) Парсинг чисел из файла в некий буферный массив, допустим, динамически расширяющийся по мере чтения исходного файла и занесением данных в массив.
2) Сортировка полученного буфера.
3) Запись.

Все бы ничего, но я совершенно не догадываюсь, как стоит грамотно сделать парсинг и как его сделать вообще, при том, что стоит обходиться (к сожалению) без потокового ввода. Алсо, в задании еще указано, что прсить следует тип данных double, на практике же достаточно указать тип буферного массива. Я буду крайне благодарен любым подсказкам!
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
04.07.2011, 15:46     Парсинг чисел из текстовика
Посмотрите здесь:

Парсинг C++
C++ Парсинг
C++ Считывание числа из текстовика посимвольно
C++ Парсинг шрифтов
Рекурсивный парсинг C++
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Yur4e
2 / 2 / 0
Регистрация: 20.10.2010
Сообщений: 21
04.07.2011, 16:25     Парсинг чисел из текстовика #2
Выбирай построчно файл, в каждой строке ищи числа связкой
C++
1
string.find_first_of("0123456789");
и
C++
1
string.find_first_not_of("0123456789");
. Используя double atof ( const char * str ); преобразуй полученную подстроку в double.
Как-то так =)
ForEveR
Модератор
Эксперт C++
 Аватар для ForEveR
7927 / 4709 / 318
Регистрация: 24.06.2010
Сообщений: 10,524
Завершенные тесты: 3
04.07.2011, 16:35     Парсинг чисел из текстовика #3
Yur4e, Лучше с переводом просто придумать ничего не могли, да?
Use std::stringstream or boost::lexical_cast.
Yur4e
2 / 2 / 0
Регистрация: 20.10.2010
Сообщений: 21
04.07.2011, 16:39     Парсинг чисел из текстовика #4
ForEveR,
Цитата Сообщение от Zaсk Посмотреть сообщение
стоит обходиться (к сожалению) без потокового ввода
Zaсk
0 / 0 / 0
Регистрация: 04.07.2011
Сообщений: 4
04.07.2011, 16:46  [ТС]     Парсинг чисел из текстовика #5
Прошу прощения, можно ли рассмотреть сабж, к примеру, на сишке, без фраймворка?
Yur4e
2 / 2 / 0
Регистрация: 20.10.2010
Сообщений: 21
04.07.2011, 18:58     Парсинг чисел из текстовика #6
Цитата Сообщение от Zaсk Посмотреть сообщение
Прошу прощения, можно ли рассмотреть сабж, к примеру, на сишке, без фраймворка?
Реализация необходима на C или C++?
igorrr37
 Аватар для igorrr37
1593 / 1221 / 118
Регистрация: 21.12.2010
Сообщений: 1,868
Записей в блоге: 7
04.07.2011, 19:48     Парсинг чисел из текстовика #7
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include <iostream>
#include <string>
#include <fstream>
#include <algorithm>
#include <cctype>
#include <iterator>
#include <sstream>
#include <set>
 
int main(){
    std::ifstream ifs("1.txt");
    if(!ifs){std::cerr<<"File not found\n"; return 1;}
    std::string s((std::istreambuf_iterator<char>(ifs)), std::istreambuf_iterator<char>());
    ifs.close();
    std::replace_if(s.begin(), s.end(), [](char x){return !(isdigit(x)||x=='.'||x=='-');}, ' ');
    std::istringstream iss(s);
    std::multiset<double> setd((std::istream_iterator<double>(iss)), std::istream_iterator<double>());
    std::ofstream ofs("2.txt");
    std::copy(setd.begin(), setd.end(), std::ostream_iterator<double>(ofs, "  "));
    ofs.close();
    return 0;
}
Zaсk
0 / 0 / 0
Регистрация: 04.07.2011
Сообщений: 4
04.07.2011, 21:45  [ТС]     Парсинг чисел из текстовика #8
Yur4e, чистый Си.
xAtom
 Аватар для xAtom
910 / 735 / 60
Регистрация: 09.12.2010
Сообщений: 1,346
Записей в блоге: 1
04.07.2011, 21:49     Парсинг чисел из текстовика #9
Вот на С как вариант. Не целые в файле должны быть с точкой = 3.14, массив растёт динамически при переполнение границы массива индексом он престраивает массив с новым размером....
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
 
// аллокатор - управление динамической памятью
void  allocate(double** arr, int  size, int* alloc) {
    if(!(*arr))
        (*arr) = (double*) malloc(sizeof(double) * (*alloc));
    else {
        if(size + 1 >= (*alloc)) {
            *alloc = size + (*alloc);
            (*arr)    = (double*) realloc((*arr), sizeof(double) * (*alloc));
        }
    }
}
 
 
// сортировка  по-asc
double*  sort(double* arr, int size) {
    int inx = 0, i;
    double  tmp;
    while(1) {
        inx   = 0;
        for(i = 0; i < size - 1; i++) {
            if( *((arr) + i) > *((arr) + i + 1) ) {
               tmp    = *((arr) + i + 1);
               *((arr) + i + 1) = *((arr) + i);
               *((arr) + i)       = tmp;
               inx    = 1;
            }
        }
       if(! inx)
           break;
    }
    return arr;
}
 
 
// простой тест
int is_test(const char* src) {
    int len = 0;
    while( *src ) {
          if(isdigit(*src++))
             len++;
    }
    return (! len) ? 0 : 1;
}
 
 
// сам процесс парсинга чисел
 
int parse(const char* src, double** arr, int size, int* alloc) {
   char  snum[32];
   char* iter = snum, ch;
   do {
         if( isdigit(*src) || *src == '-' && ! isdigit(ch) || *src == '.' && isdigit(ch)){
            *iter = *src;
            ++iter;
         } else {
             *iter = '\0';
             if(is_test(snum)) {
                allocate(arr, size, alloc);
                *(((*arr)) + size) = atof(snum);
                size++;
             }
             snum[0] = '\0';
             iter    = snum;
         }
         ch = *src;
   } while( *src++ != '\0' );
   return size;
}
 
 
int main(void)
{
   int        size  = 0, alloc = 32, i;
   double* arr   = NULL;
   char     snum[1024];
   char*   iter;
 
   FILE*  fp   = fopen("double.txt", "r");  
   if(! fp)
       exit(1);
 
   while(! feof(fp)) {
        snum[0] = '\0';
        fgets(snum, sizeof(snum), fp);
        size = parse(snum, &arr, size, &alloc);
   }
   fclose(fp);
 
   arr = sort(arr, size);  // сортируем
 
   fp  = fopen("sort.txt", "w");
 
   for(i = 0; i < size; i++)  {
       fprintf(fp, "%.2f\n", *((arr) + i));
       fprintf(stdout, "%.2f\n", *((arr) + i));
   }
   fflush(fp);
   fclose(fp);
 
   free(arr);
   arr = NULL;
 
   system("pause");
   return 0;
}
Zaсk
0 / 0 / 0
Регистрация: 04.07.2011
Сообщений: 4
05.07.2011, 07:40  [ТС]     Парсинг чисел из текстовика #10
xAtom, начал отладку, мелкософтская студия кидает ошибку:

...f:\dd\vctools\crt_bld|self_x86\crt\src\isctype.c
Line: 56

Expression: (unsigned(c + 1) <=256

Кидает на строке
C
1
size = parse(snum, &arr, size, &alloc);
Я воспользовался поиском, но нашел только ссылки на забугорные обсуждения где все не совсем ясно. Вы можете помочь диагностировать проблему?

Добавлено через 30 минут
Стал копать дальше, нашел связь с isdigit. Только еще больше запутался..
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
05.07.2011, 08:12     Парсинг чисел из текстовика
Еще ссылки по теме:

C++ Парсинг чисел из строки
C++ Парсинг строки
C++ Парсинг

Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
ForEveR
Модератор
Эксперт C++
 Аватар для ForEveR
7927 / 4709 / 318
Регистрация: 24.06.2010
Сообщений: 10,524
Завершенные тесты: 3
05.07.2011, 08:12     Парсинг чисел из текстовика #11
Zaсk, русские символы не вводите.
Yandex
Объявления
05.07.2011, 08:12     Парсинг чисел из текстовика
Ответ Создать тему
Опции темы

Текущее время: 06:39. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru