Вопрос по С++

Кто любит RISC в жизни, заходим, не стесняемся.
Ответить
Аватара пользователя
osievskiy
Открыл глаза
Сообщения: 79
Зарегистрирован: Вт июн 18, 2013 11:23:25

Вопрос по С++

Сообщение osievskiy »

Спойлер

Код: Выделить всё

[b]ini.h[/b]


#ifndef __INI_H__
#define __INI_H__
#include "ff.h"


#define INI_MAX_LINE 100
#define MAX_SECTION 50
#define MAX_NAME 50
#define MAX_VALUE 50

//#ifndef INI_ALLOW_MULTILINE
#define INI_ALLOW_MULTILINE 1
//+
#endif

typedef struct {
		char* st;
} Ini_struct;

class INI
{
	

	public:
		int Read(const char* fName);
		char* find(const char* key);
		Ini_struct iniMain[20];
	private:
		
		
		int iniParse();
		char* rstrip(char* s);
		char* lskip(const char* s);
		char* find_char_or_comment(const char* s, char c);
		char* strncpy0(char* dest, const char* src, size_t size);
		const char* filename;
		void handler(const char* key,const char* val);
		FIL file;
		int error;
		int iter;
		
};






#endif /* __INI_H__ */




[b]ini.cpp[/b]




#include <stdio.h>
#include <ctype.h>
#include <string.h>

#include "ini.h"
#include "ff.h"

int INI::Read(const char* fName)
{
	filename = fName;
	iter = 0;
	int eini = f_open(&file,filename,FA_READ);
	if (error!=0) return error;
	
	eini = iniParse();
	if(eini>0) return 0; 
	f_close(&file);
	return eini;
}

int INI::iniParse()
{
		iter = 0;
    char line[INI_MAX_LINE];
    char section[MAX_SECTION] = "";
    char prev_name[MAX_NAME] = "";


    char* start;
    char* end;
    char* name;
    char* value;
    int lineno = 0;
    int error = 0;
		
		
		
		
		
		
		
		
		
		
	
    while (f_gets(line, INI_MAX_LINE, &file) != NULL) {
        lineno++;
        start = lskip(rstrip(line));

        if (*start == ';' || *start == '#') {
          
        }
        else if (*start == '[') {
          
            end = find_char_or_comment(start + 1, ']');
            if (*end == ']') {
                *end = '\0';
                strncpy0(section, start + 1, sizeof(section));
                *prev_name = '\0';
            }
            else if (!error) {

                error = lineno;
            }
        }
        else if (*start && *start != ';') {

            end = find_char_or_comment(start, '=');
            if (*end != '=') {
                end = find_char_or_comment(start, ':');
            }
            if (*end == '=' || *end == ':') {
                *end = '\0';
                name = rstrip(start);
                value = lskip(end + 1);
                end = find_char_or_comment(value, '\0');
                if (*end == ';')
                    *end = '\0';
                rstrip(value);

                /* Valid name[=:]value pair found, call handler */
                strncpy0(prev_name, name, sizeof(prev_name));
								handler(prev_name,value);
								
            }
            else if (!error) {

                error = lineno;
            }
        }
    }

		
    return error;
}


char* INI::rstrip(char* s)
{
    char* t = s + strlen(s);
    while (t > s && isspace((unsigned char)(*--t)))
        *t = '\0';
    return s;
}

char* INI::lskip(const char* s)
{
    while (*s && isspace((unsigned char)(*s)))
        s++;
    return (char*)s;
}

char* INI::find_char_or_comment(const char* s, char c)
{
    int was_whitespace = 0;
    while (*s && *s != c && !(was_whitespace && *s == ';')) {
        was_whitespace = isspace((unsigned char)(*s));
        s++;
    }
    return (char*)s;
}

char* INI::strncpy0(char* dest, const char* src, size_t size)
{
    strncpy(dest, src, size);
    dest[size - 1] = '\0';
    return dest;
}

char* INI::find(const char* keys)
{
	
	for(int i = 0; i < iter; i++)
	{
		
		//if(strcmp(iniMain[i].key, keys)==0) return iniMain[i].val;
		
	}

	return "none";
}

void INI::handler(const char* key,const char* val)
{
		static char prev_k[MAX_NAME] = "";
		static char prev_v[MAX_NAME] = "";

		strncpy(prev_k, key, sizeof(prev_k));
		prev_k[sizeof(prev_k) - 1] = '\0';
		iniMain[++iter].st=prev_k;
	
		strncpy(prev_v, val, sizeof(prev_v));
		prev_v[sizeof(prev_k) - 1] = '\0';
		iniMain[++iter].st=prev_v;
	
}


[b]test.ini[/b]

version=6           
name = Bob Smith
email = bob@smith.com
active = true




Стал вопрос как хранить данные с контроллера. Выбрал INI файл...
Отрывается читается, но в iniMain почему то одинаковые значения...
iniMain[0].st = active
iniMain[1].st = true
iniMain[2].st = active
iniMain[3].st = true
iniMain[4].st = active
iniMain[5].st = true
iniMain[6].st = active
iniMain[0].st = true

в место
iniMain[0].st = version
iniMain[1].st = 6
iniMain[2].st = name
iniMain[3].st = Bob Smith
iniMain[4].st = email
iniMain[5].st = bob@smith.com
iniMain[6].st = active
iniMain[0].st = true


Я уже 2 дня бьюсь с этой проблемой... помогите пожалуйста... подскажите в чем ошибка?
Реклама
bishop-strip
Открыл глаза
Сообщения: 71
Зарегистрирован: Чт окт 28, 2010 11:20:39

Re: Вопрос по С++

Сообщение bishop-strip »

На первый взгляд, я вообще бы для каждого объекта структуры, ее бы члену динамически выделял память, скажем malloc'ом или , если же Си++, то new...
Спойлерvoid INI::handler(const char* key,const char* val)
{
char *prev_k= new char[MAX_NAME]; memset(prev_k, 0, MAX_NAME);
char *prev_v = new char[MAX_NAME]; memset(prev_v, 0, MAX_NAME);

strncpy(prev_k, key, strlen(key));
iniMain[++iter].st=prev_k;
strncpy(prev_v, val, strlen(val);
iniMain[++iter].st=prev_v;
}
Но только потом не задубьте освободить память функцией delete[] или, если на простом Си - free();
А проблема в СТАТИКЕ(по крайней мере в глаза бросается)...
Реклама
Аватара пользователя
balmer
Это не хвост, это антенна
Сообщения: 1433
Зарегистрирован: Вс дек 02, 2012 03:13:48
Откуда: Калининград

Re: Вопрос по С++

Сообщение balmer »

Советую таки, что-то более современное. Например xml и библиотеку PugiXml для работы с этим форматом.
Либо как вариант json, который тоже часто используется в интернет технологиях.

Потом не будет проблемм если захотите импортировать данные в какой либо из скриптовых языков для последующей обработки.

Если пишите на C++, то пользуйтесь stl. Для хранения строчек std::string, для хранения массивов std::vector.
Аватара пользователя
osievskiy
Открыл глаза
Сообщения: 79
Зарегистрирован: Вт июн 18, 2013 11:23:25

Re: Вопрос по С++

Сообщение osievskiy »

Спасибо, попробую! И еще один вопрос...
Я работаю в Keil и пытаясь в этом всем разобраться дебажил через него же... и заметил что изначально в iniMain содержится какой то мусор... почему такое может быть?
Реклама
Эиком - электронные компоненты и радиодетали
bishop-strip
Открыл глаза
Сообщения: 71
Зарегистрирован: Чт окт 28, 2010 11:20:39

Re: Вопрос по С++

Сообщение bishop-strip »

iniMain изначально содержит мусор потоу, что его члены-указатели имеют произвольный адрес, по которому может быть всё что угодно
изначально рекомендуется присваивать указателям адрес 0, но это уже как стиль программирования....
Реклама
Аватара пользователя
osievskiy
Открыл глаза
Сообщения: 79
Зарегистрирован: Вт июн 18, 2013 11:23:25

Re: Вопрос по С++

Сообщение osievskiy »

Понятно! Спасибо огромное!
Реклама
Аватара пользователя
osievskiy
Открыл глаза
Сообщения: 79
Зарегистрирован: Вт июн 18, 2013 11:23:25

Re: Вопрос по С++

Сообщение osievskiy »

У меня есть main.cpp
и
usart.c
usart.h

в main.cpp делаею #include "usart.h"

в usart.h

Код: Выделить всё

extern void MT_USART_Init(void);
extern void MT_USART_SendData(uint8_t *pSendData, uint8_t nNumOfDataToSend);
extern void MT_USART_ReceiveData(uint8_t* pReceivedData, uint8_t nNumOfDataToReceive);

но при компиляции
.\Exti\Exti.axf: Error: L6218E: Undefined symbol MT_USART_Init() (referred from main.o).


Почему так происходит?
Аватара пользователя
urry
Сверлит текстолит когтями
Сообщения: 1262
Зарегистрирован: Пн дек 08, 2008 10:58:48
Откуда: Винница
Контактная информация:

Re: Вопрос по С++

Сообщение urry »

Трудно сказать без текста, но, как вариант, включение uart.h в нескольких местах.
Для начала попробуйте добавить

Код: Выделить всё

#ifndef UART_H
#define UART_H 
extern void MT_USART_Init(void);
extern void MT_USART_SendData(uint8_t *pSendData, uint8_t nNumOfDataToSend);
extern void MT_USART_ReceiveData(uint8_t* pReceivedData, uint8_t nNumOfDataToReceive);
#endif //UART_H
Galizin
Мучитель микросхем
Сообщения: 478
Зарегистрирован: Ср окт 15, 2008 09:33:03
Откуда: Воронеж

Re: Вопрос по С++

Сообщение Galizin »

osievskiy писал(а):но при компиляции
.\Exti\Exti.axf: Error: L6218E: Undefined symbol MT_USART_Init() (referred from main.o).
Небольшое уточнение. Ошибка при компоновке.
Перевод на русский язык звучит примерно так
Не могу найти код функции или определение переменной с данным именем MT_USART_Init (Используется в объектном файле main.o)
Необходимо в проект (makefile) включить файл с исходником или библиотеку с этой функцией.
Компоновщик занимается тем, что включает в конечный модуль код различных функций и переменных с указанием их адресов. До компоновки адреса неопределены. Потом компоновщик смотрит, какие символы (имена переменных и функций) есть в main. Он пытается найти их среди всех откомпилированных файлов и библиотек. Потом то же самое делает с теми функциями и переменными что нашел. И так до тех пор, пока все символы будут найдены. Если хоть один не найден - значит будет такое сообщение о ошибке.
Аватара пользователя
osievskiy
Открыл глаза
Сообщения: 79
Зарегистрирован: Вт июн 18, 2013 11:23:25

Re: Вопрос по С++

Сообщение osievskiy »

Спасибо за ответы, но помогла банальность... просто переименовал uart.c в uart.cpp и все стало нормально
по видимому если файл .c и подключать .h в main.cpp то оно не видит .c а .cpp видит без проблем
Galizin
Мучитель микросхем
Сообщения: 478
Зарегистрирован: Ср окт 15, 2008 09:33:03
Откуда: Воронеж

Re: Вопрос по С++

Сообщение Galizin »

Galizin писал(а):просто переименовал uart.c в uart.cpp и все стало нормально
В с и c++ разное внутренне представление имен. Что бы использовать C файлы совместно с c++ необходимо декларации функций обрамлять extern C
Аватара пользователя
osievskiy
Открыл глаза
Сообщения: 79
Зарегистрирован: Вт июн 18, 2013 11:23:25

Re: Вопрос по С++

Сообщение osievskiy »

ага, спасибо, буду знать...
Трудновато спрыгнуть с не строго типизированных языков на С/С++
Ответить

Вернуться в «ARM»