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

Парсер массива - C++

Восстановить пароль Регистрация
 
Рейтинг: Рейтинг темы: голосов - 11, средняя оценка - 4.64
yardie
 Аватар для yardie
8 / 8 / 0
Регистрация: 14.07.2010
Сообщений: 166
22.12.2010, 18:03     Парсер массива #1
Поскажите пожалуйста, парсер массива чисел на входе: строка вида "число|число|число|число" и кол-во чисел. число - целое, на выходе: массив из чисел
функцию strtok и аналоги не использовать, а atoi можно.

Первый раз пишу парсер, куча ошибок и не доработок, помогите плз

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include <iostream>
using namespace std;
 
void main ()
{
const char * a[10];
int i;
cout<< "Enter characteries: ";
for( i=0; i<10; i++)
{
    cin >> a[i];
cout<<  atoi(a[i])<<" ";
}
system ("pause");
}
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
22.12.2010, 18:03     Парсер массива
Посмотрите здесь:

C++ Парсер
C++ Парсер
C++ парсер строки
Парсер HTML C++
C++ парсер
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Nameless One
Эксперт С++
 Аватар для Nameless One
5754 / 3403 / 255
Регистрация: 08.02.2010
Сообщений: 7,393
22.12.2010, 19:01     Парсер массива #2
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
#include <stdio.h>
#include <stdlib.h>
 
#define BUFFSIZE 80
#define MAXNUMCNT 20
 
int* getNumbers(char*, int*, size_t, size_t*);
 
int main()
{
    char buf[BUFFSIZE + 1];
    int  nums[MAXNUMCNT];
    size_t cnt;
    puts("Введите строку чисел");
    fgets(buf, BUFFSIZE, stdin);
    getNumbers(buf, nums, MAXNUMCNT, &cnt);
    for(size_t i = 0; i < cnt; ++i)
        printf("nums[%02u] = %d\n", i + 1, nums[i]); 
    return 0;
}
 
/* Функция будет разбирать строку str и разбивать ее на числа
 * которые будут храниться в массиве numbers, но не больше, чем
 * size чисел. Если указатель cnt не указывает на NULL, то в нем
 * возвращается количество распарсенных чисел
 * Строка разрушается
 */ 
int* getNumbers(char* str, int* numbers, size_t size, size_t* cnt)
{
    size_t n = 0;
    char *p = str;
    char *q = str;
    
    while(*q && (n <= size))
    {
        if(*q == '|')
        {
            *q++ = '\0';
            numbers[n++] = atoi(p);
            p = q;
        }
        else
            ++q;
    }
    
    if(n < size)
        numbers[n++] = atoi(p);
    
    if(cnt)
        *cnt = n;
        
    return numbers;
}
yardie
 Аватар для yardie
8 / 8 / 0
Регистрация: 14.07.2010
Сообщений: 166
23.12.2010, 11:23  [ТС]     Парсер массива #3
Nameless One, а проще сделать можно?
grrrrr
23.12.2010, 12:00
  #4

Не по теме:


yardie, так намного интересней, зачем упрощать себе жизнь!

Nameless One
Эксперт С++
 Аватар для Nameless One
5754 / 3403 / 255
Регистрация: 08.02.2010
Сообщений: 7,393
23.12.2010, 13:01     Парсер массива #5
Цитата Сообщение от yardie Посмотреть сообщение
Nameless One, а проще сделать можно?
Да куда уж проще?
lemegeton
 Аватар для lemegeton
2910 / 1339 / 133
Регистрация: 29.11.2010
Сообщений: 2,720
23.12.2010, 13:11     Парсер массива #6
Это решение, похоже, исходную строку модифицирует.
Nameless One
Эксперт С++
 Аватар для Nameless One
5754 / 3403 / 255
Регистрация: 08.02.2010
Сообщений: 7,393
23.12.2010, 13:14     Парсер массива #7
lemegeton, ага, что я и написал в комментарии
lemegeton
23.12.2010, 13:16
  #8

Не по теме:

Меня сложно упрекнуть в чтении документации.

Nameless One
Эксперт С++
 Аватар для Nameless One
5754 / 3403 / 255
Регистрация: 08.02.2010
Сообщений: 7,393
23.12.2010, 13:31     Парсер массива #9
Цитата Сообщение от lemegeton Посмотреть сообщение
Это решение, похоже, исходную строку модифицирует.
Вот без модификации исходной строки (также немного подправил условие в строке 41):
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
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
 
#define BUFFSIZE 80
#define MAXNUMCNT 20
 
int* getNumbers(const char*, int*, size_t, size_t*);
 
int main()
{
    char buf[BUFFSIZE + 1];
    int  nums[MAXNUMCNT];
    size_t cnt, i;
    puts("Введите строку чисел");
    fgets(buf, BUFFSIZE, stdin);
    getNumbers(buf, nums, MAXNUMCNT, &cnt);
    for(i = 0; i < cnt; ++i)
    printf("nums[%02u] = %d\n", i + 1, nums[i]); 
    return 0;
}
 
/* Функция будет разбирать строку str и разбивать ее на числа
 * которые будут храниться в массиве numbers, но не больше, чем
 * size чисел. Если указатель cnt не указывает на NULL, то в нем
 * возвращается количество распарсенных чисел
 * Строка уже не разрушается
 */ 
int* getNumbers(const char* str, int* numbers, size_t size, size_t* cnt)
{
    char* _str;
    if((_str = strdup(str)) == NULL)
    {
        perror("strdup");
        exit(1);
    }
    size_t n = 0;
    char *p = _str;
    char *q = _str;
        
    while(*q && (n < size))
    {
        if(*q == '|')
        {
            *q++ = '\0';
            numbers[n++] = atoi(p);
            p = q;
        }
        else
             ++q;
    }
        
    if(n < size)
        numbers[n++] = atoi(p);
        
    if(cnt)
        *cnt = n;
               
    free(_str); 
    return numbers;
}
yardie
 Аватар для yardie
8 / 8 / 0
Регистрация: 14.07.2010
Сообщений: 166
23.12.2010, 14:48  [ТС]     Парсер массива #10
не понял вот эту строчку int* getNumbers(char*, int*, size_t, size_t*)
а именно (char*, int*, size_t, size_t*)
распишите по подробней, я ни как не магу врубиться что это и как это, вот сижу книгу читаю, ни как не найду(((
Nameless One
Эксперт С++
 Аватар для Nameless One
5754 / 3403 / 255
Регистрация: 08.02.2010
Сообщений: 7,393
23.12.2010, 14:56     Парсер массива #11
Это прототип функции getNumbers, принимающей параметрами указатель на char, указатель на int, переменную типа size_t и указатель на size_t и возвращающей указатель на int. Прототип просто объявляет интерфейс функции, которая будет определена позднее, при этом имена формальных параметров можно не указывать, достаточно указать только типы. Использовать прототип не обязательно, это всего лишь дело вкуса. В моем случае он нужен потому, что функция getNumbers определена ниже функции main. А можно было бы определить функцию выше функции main и избавиться таким образом от необходимости объявлять прототип функции

Глянь еще здесь
yardie
 Аватар для yardie
8 / 8 / 0
Регистрация: 14.07.2010
Сообщений: 166
23.12.2010, 15:06  [ТС]     Парсер массива #12
Nameless One, ну с прототипом я знаком, я не пойму почему ты используешь size_t и делаешь ещё указатель *size_t
Nameless One
Эксперт С++
 Аватар для Nameless One
5754 / 3403 / 255
Регистрация: 08.02.2010
Сообщений: 7,393
23.12.2010, 15:17     Парсер массива #13
C
1
2
3
4
5
6
7
/* Функция будет разбирать строку str и разбивать ее на числа
 * которые будут храниться в массиве numbers, но не больше, чем
 * size чисел. Если указатель cnt не указывает на NULL, то в нем
 * возвращается количество распарсенных чисел
 * Строка разрушается
 */ 
int* getNumbers(char* str, int* numbers, size_t size, size_t* cnt);
size_t - это беззнаковый целый тип, поэтому логично его использовать для указания размера массива numbers. Переменная size указывает на размер массива numbers, т.е. на максимальное количество чисел, который он может хранить. Но в строке str может встретиться меньше чисел, чем size, именно поэтому нам нужен указатель cnt - в нем будет храниться количество реально распарсенных чисел; в дальнейшем это значение используется для того, чтобы вывести числа из массива на экран. Вообще возможны три варианта:
  1. в строке меньше чисел, чем size - тогда в numbers записываются все встретившиеся числа, а *cnt хранит реальное количество этих чисел (*cnt < size);
  2. в строке ровно size чисел - тогда все эти числа записываются в массив, и *cnt = size;
  3. в строке больше чисел, чем size - тогда в массив записывается ровно size чисел, *cnt = size, а все остальные числа в строке игнорируются.

Вообще можно было бы сделать динамически расширяющийся массив чисел, но тогда на пользователя возлагалась бы задача освобождения выделенной памяти
yardie
 Аватар для yardie
8 / 8 / 0
Регистрация: 14.07.2010
Сообщений: 166
23.12.2010, 16:10  [ТС]     Парсер массива #14
а что эта запись значит char buf[BUFFSIZE + 1] ?
Nameless One
Эксперт С++
 Аватар для Nameless One
5754 / 3403 / 255
Регистрация: 08.02.2010
Сообщений: 7,393
23.12.2010, 16:15     Парсер массива #15
yardie, объявляется строка (массив char) размера BUFFSIZE + 1. Кстати, там лучше было бы под строку выделить не BUFFSIZE + 1, а BUFFSIZE символов:
C
1
char buf[BUFFSIZE];
yardie
 Аватар для yardie
8 / 8 / 0
Регистрация: 14.07.2010
Сообщений: 166
23.12.2010, 16:16  [ТС]     Парсер массива #16
а почему +1, это так для чего делать?
Nameless One
Эксперт С++
 Аватар для Nameless One
5754 / 3403 / 255
Регистрация: 08.02.2010
Сообщений: 7,393
23.12.2010, 16:25     Парсер массива #17
Потому, что строки C обычно заканчиваются на символ '\0', который является признаком конца строки. Многие функции работы со строками неявно записывают этот символ в строку, либо ожидают, чтобы он там присутствовал. Таким образом, мы говорим: создать массив типа char, который может хранить до BUFFSIZE символов + завершающий символ '\0'.

Чуть выше я предложил исправить это объявление на
C
1
char buf[BUFFSIZE];
так как функция fgets прочитает как минимум на один символ меньше, чем мы укажем в соответствующем аргументе, который будет указывать на максимальный размер строки. Таким образом, в любом случае вызов функции fgets(buf, BUFFSIZE, stdin) прочитает не больше BUFFSIZE - 1 символов и обязательно вставит символ '\0' в конец результирующей строки. Таким образом, в данном случае выделять дополнительный символ для строки buf не надо.
Reee
 Аватар для Reee
21 / 21 / 1
Регистрация: 21.09.2010
Сообщений: 65
23.12.2010, 16:27     Парсер массива #18
Этот плюс 1 для '\0' (ограничитель строки)
Nameless One
23.12.2010, 16:28
  #19

Не по теме:

Reee, слеш немного не в ту сторону

MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
23.12.2010, 16:29     Парсер массива
Еще ссылки по теме:

C++ Парсер паскаля
C++ Парсер
C++ Парсер, utf-8

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

Или воспользуйтесь поиском по форуму:
Reee
23.12.2010, 16:29     Парсер массива
  #20

Не по теме:

Цитата Сообщение от Nameless One Посмотреть сообщение

Не по теме:

Reee, слеш немного не в ту сторону

Ой...

Yandex
Объявления
23.12.2010, 16:29     Парсер массива
Ответ Создать тему
Опции темы

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