Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / Программирование [игнор отключен] [закрыт для гостей] / Передача указателя в качестве аргумента в С. / 7 сообщений из 7, страница 1 из 1
20.12.2016, 13:46
    #39371009
jenya7
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Передача указателя в качестве аргумента в С.
Есть такая функция.
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
uint32_t XML_PARSER_FindElementEnd(char *xml_str, char* el_name, char* pchr)
{
    uint32_t el_size = strlen(el_name);
    char buf[el_size+4];
  
    memcpy(&buf[0], "<", 1);
    memcpy(&buf[1], el_name, el_size);
    memcpy(&buf[el_size+1], "/>\0", 3);
    
    pchr = strstr(xml_str, buf);
    if(pchr == NULL) return 0;
    else return 1;
}



Внутри функции pchr принимает правильное значение, все прекрасно.

Проверяем
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
uint32_t  XML_PARSER_NewElement(char *xml_str, char *parent, char* el_name)
{
    char *pchr_test=NULL;

    if (!XML_PARSER_FindElementEnd(xml_str, parent, pchr_test));
        return 0;
}


pchr_test остается 0. Подскажите где ошибка.
...
Рейтинг: 0 / 0
20.12.2016, 13:57
    #39371017
Dima T
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Передача указателя в качестве аргумента в С.
Если ты хочешь изменить значение указателя, то надо указатель на указатель использовать.
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
uint32_t XML_PARSER_FindElementEnd(char *xml_str, char* el_name, char** pchr)
{
    uint32_t el_size = strlen(el_name);
    char buf[el_size+4];
  
    memcpy(&buf[0], "<", 1);
    memcpy(&buf[1], el_name, el_size);
    memcpy(&buf[el_size+1], "/>\0", 3);
    
    *pchr = strstr(xml_str, buf);
    if(*pchr == NULL) return 0;
    else return 1;
}


uint32_t  XML_PARSER_NewElement(char *xml_str, char *parent, char* el_name)
{
    char *pchr_test=NULL;

    if (!XML_PARSER_FindElementEnd(xml_str, parent, &pchr_test));
        return 0;
}
...
Рейтинг: 0 / 0
20.12.2016, 14:04
    #39371026
jenya7
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Передача указателя в качестве аргумента в С.
Да точно. Так работает. Спасибо.
...
Рейтинг: 0 / 0
20.12.2016, 16:39
    #39371195
jenya7
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Передача указателя в качестве аргумента в С.
Кстати а как оптимальней всего взять из строки " Attribute="value" " атрибут и значение?
...
Рейтинг: 0 / 0
20.12.2016, 23:06
    #39371448
SashaMercury
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Передача указателя в качестве аргумента в С.
jenya7Кстати а как оптимальней всего взять из строки " Attribute="value" " атрибут и значение?
что вы понимаете под оптимальностью в данном случае? Например, ваша функция XML_PARSER_FindElementEnd на мой взгляд работает далеко не оптимальным образом, даже без учета качества реализации данного алгоритма на языке Си. И кстати не очень понятно, что там у вас работает, особенно аллоцирование подобным образом
Код: plaintext
1.
char buf[el_size+4];

,
...
Рейтинг: 0 / 0
21.12.2016, 04:04
    #39371505
Пётр Седов
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Передача указателя в качестве аргумента в С.
jenya7
Код: plaintext
1.
    memcpy(&buf[el_size+1], "/>\0", 3);

Здесь нулевой char можно не писать, потому что компилятор и так его добавляет:
Код: plaintext
1.
2.
3.
4.
assert(sizeof("/>") == 3);
assert("/>"[0] == '/');
assert("/>"[1] == '>');
assert("/>"[2] == '\0');


jenya7Кстати а как оптимальней всего взять из строки " Attribute="value" " атрибут и значение?Попробуйте так:
Код: plaintext
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.
#include <stdbool.h>
#include <assert.h>
#include <string.h>
#include <stdio.h>

struct attrib_t {
  const char* name;
  size_t name_len;
  const char* value;
  size_t value_len;
};

bool scan_attrib(const char text[], struct attrib_t* attrib) {
  size_t pos, name_pos, name_len, value_pos, value_len;
  const char* equals_sign;
  const char* closing_quote;

  pos = 0;

  /* пропускаем пробелы */
  while (text[pos] == ' ')
    pos++;

  name_pos = pos;
  /* ищем '=' начиная с pos */
  equals_sign = strchr(text + pos, '=');
  if (equals_sign == NULL) return false;
  pos = equals_sign - text;
  assert(text[pos] == '=');

  name_len = pos - name_pos;
  if (name_len == 0) return false; /* имя не может быть пустым */

  pos++; /* пропускаем '=' */

  if (text[pos] != '"') return false;
  pos++; /* пропускаем '"' */

  value_pos = pos;
  /* ищем '"' начиная с pos */
  closing_quote = strchr(text + pos, '"');
  if (closing_quote == NULL) return false;
  pos = closing_quote - text;
  assert(text[pos] == '"');

  value_len = pos - value_pos;

  pos++; /* пропускаем '"' */

  /* пропускаем пробелы */
  while (text[pos] == ' ')
    pos++;

  /* сейчас мы должны быть в конце строки */
  if (text[pos] != '\0') return false;

  attrib->name = text + name_pos;
  attrib->name_len = name_len;
  attrib->value = text + value_pos;
  attrib->value_len = value_len;
  return true;
}

int main() {
  struct attrib_t a;

  if (scan_attrib("   nick=\"jenya7\"   ", &a)) {
    /* строки name и value не завершаются нулевым char-ом ('\0'), поэтому явно указываем их длину */
    printf("name: '%.*s'\n", (int)a.name_len, a.name);
    printf("value: '%.*s'\n", (int)a.value_len, a.value);
  }

  return 0;
}

Вывод на консоль:
Код: sql
1.
2.
name: 'nick'
value: 'jenya7'


SashaMercuryИ кстати не очень понятно, что там у вас работает, особенно аллоцирование подобным образом
Код: plaintext
1.
char buf[el_size+4];

Это C99 VLA (variable-length array). Реализованы обычно через функцию alloca, которая выделяет память в stack-е. Это скользкий момент, потому что в C (и C++) нет нормального способа обработать переполнение stack-а.
...
Рейтинг: 0 / 0
21.12.2016, 09:32
    #39371568
jenya7
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Передача указателя в качестве аргумента в С.
спасибо. попробую ваш алгоритм.
это действительно VLA. тут конечно есть опасность stack overflow. но я думаю есть механизмы контроля. вроде регистр SP доступен. можно посмотреть где мы находимся в стаке и сколько осталось места.
...
Рейтинг: 0 / 0
Форумы / Программирование [игнор отключен] [закрыт для гостей] / Передача указателя в качестве аргумента в С. / 7 сообщений из 7, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]