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

С++ для начинающих

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

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

04.07.2011, 15:46. Просмотров 1615. Ответов 10
Метки нет (Все метки)

Я начинающий, но не знаю как справиться с заданием:

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

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

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

Считывание числа из текстовика посимвольно - C++
в текстовом файле забито число(например 1368), нужно посимвольно его подсчитать и вывести на экран. цикл написал: for...

Парсинг чисел из строки - C++
Подскажите пожалуйста функцию, которая моглабы парсить из строки. Ну что-то на подобии sscanf, только наоборот Чтобы получилось что то...

Изменение текстовика - Delphi
Вообщем есть текстовик по адресу: H:/ololo.txt Нужно найти в нем следующий текст и удалить его: "Report". На его же месте написать:...

Имя создаваемого текстовика - Windows 7
всем доброго времени суток стоит win 7 максимальная от монкрус'а вчера/сегодня создаваемые текстовики стали называться иначе: Text...

Спарсить данные с текстовика - C#
Пишу парсер данных с cs-сервера. IPEndPoint ipendpoint = null; byte message = udp.Receive(ref ipendpoint); ...

Кодировка текстовика! (Вирус) - Безопасность
Возникла проблема, отходил по делам за компьютер сели родственники, в итоге по возвращению наблюдал картину, некоторые текстовые файлы с...

Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
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.
Как-то так =)
0
ForEveR
В астрале
Эксперт С++
7973 / 4735 / 321
Регистрация: 24.06.2010
Сообщений: 10,542
Завершенные тесты: 3
04.07.2011, 16:35 #3
Yur4e, Лучше с переводом просто придумать ничего не могли, да?
Use std::stringstream or boost::lexical_cast.
0
Yur4e
2 / 2 / 0
Регистрация: 20.10.2010
Сообщений: 21
04.07.2011, 16:39 #4
ForEveR,
Цитата Сообщение от Zaсk Посмотреть сообщение
стоит обходиться (к сожалению) без потокового ввода
1
Zaсk
0 / 0 / 0
Регистрация: 04.07.2011
Сообщений: 4
04.07.2011, 16:46  [ТС] #5
Прошу прощения, можно ли рассмотреть сабж, к примеру, на сишке, без фраймворка?
0
Yur4e
2 / 2 / 0
Регистрация: 20.10.2010
Сообщений: 21
04.07.2011, 18:58 #6
Цитата Сообщение от Zaсk Посмотреть сообщение
Прошу прощения, можно ли рассмотреть сабж, к примеру, на сишке, без фраймворка?
Реализация необходима на C или C++?
0
igorrr37
1647 / 1275 / 133
Регистрация: 21.12.2010
Сообщений: 1,932
Записей в блоге: 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;
}
0
Zaсk
0 / 0 / 0
Регистрация: 04.07.2011
Сообщений: 4
04.07.2011, 21:45  [ТС] #8
Yur4e, чистый Си.
0
xAtom
915 / 740 / 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;
}
1
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. Только еще больше запутался..
0
ForEveR
В астрале
Эксперт С++
7973 / 4735 / 321
Регистрация: 24.06.2010
Сообщений: 10,542
Завершенные тесты: 3
05.07.2011, 08:12 #11
Zaсk, русские символы не вводите.
0
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
05.07.2011, 08:12
Привет! Вот еще темы с ответами:

Delphi вытащить текст из текстовика - Delphi
в текстовике proba.txt заполнен текст &lt;1&gt;1111&lt;/1&gt; &lt;2&gt;2222&lt;/2&gt; &lt;3&gt;3333&lt;/3&gt; как вытащить текст между &lt;2&gt; и &lt;/2&gt; и вывести в...

Проверка состояния данных из текстовика в PHP - PHP
Здравствуйте дорогие комрады, помогите пожалуйста , стоит у меня такая задача: Нажимая на кнопку на сайте включать\выключать реле и...

Скопировать текст из текстовика на сервере в label - Delphi
Привет всем Защитил свою программу от распространения с помощью онлайн верификации, и хотелось бы уведомлять пользователя о том, какая у...

Как программой выдернуть все ссылки с текстовика - Delphi
Нужно вытащить ссылки с моего text.txt файла весом 100 мб нужна программа способная выдернуть из текстовика все содержащиеся в нем...


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

Или воспользуйтесь поиском по форуму:
Yandex
Объявления
05.07.2011, 08:12
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru