I have a bug with my printf() function im implementing for OS. Basically the problem is, it dosent increment through the list. For example lets say i have:
printf("%d %d",19,58);
what will show on my OS is :
19 19
the 58 for some reason is not going thourgh. I have debugged this for quite some time, but cant find problem :( . Here is the stdio.c++:
#include "stdio.h"
static size_t terminal_row = 0;
static size_t terminal_column = 0;
static uint16_t* VideoMemory =((uint16_t*)0xb8000);
static bool continue_ex = false;
SerialPort sp_std_io;
void printf(char *str, ...)
{
va_list arg;
va_start(arg, str);
for(int32_t i=0;str[i]!='\0'; ++i)
{
putchar(str[i],str[i+1],arg);
}
va_end(arg);
}
void strcat(char *destination, const char *source)
{
int x = 0;
while (destination[x] != '\0')
{
x++;
}
for (int i=0; source[i] != '\0'; i++)
{
destination[x++] = source[i];
}
destination[x] = '\0';
}
void put_char_helper_neg(char chr)
{
const size_t index = (terminal_row * VGA_WIDTH + terminal_column);
terminal_column++;
VideoMemory[index]= (VideoMemory[index] & 0xFF00)|chr;
}
void putstring_t(char str)
{
size_t index = (terminal_row * VGA_WIDTH + terminal_column);
terminal_column++;
VideoMemory[index]= (VideoMemory[index] & 0xFF00)|str;
}
void putchar(char str,char next_str, va_list arg)
{
if(!continue_ex)
{
uint32_t ch_per;
char* str_use,str_use_space;
const char per = '%';
if(str == '\b')
{
terminal_column--;
}
const size_t index = (terminal_row * VGA_WIDTH + terminal_column);
char space = ' ';
switch(str)
{
case '\n':
terminal_row++;
terminal_column = 0;
break;
case '\b':
VideoMemory[index]= (VideoMemory[index] & 0xFF00)|space;
break;
case '%':
switch(next_str)
{
case 'd':
ch_per = va_arg(arg,int);
if(ch_per<0)
{
ch_per = -ch_per;
put_char_helper_neg('-');
}
str_use = itoa(ch_per);
terminal_column++;
for(int32_t i=0;str_use[i]!='\0'; ++i)
{
putstring_t(str_use[i]);
}
// sp_std_io.write_number_serial(ch_per);
// sp_std_io.write_string_serial(str_use);
continue_ex = true;
break;
default:
terminal_column++;
VideoMemory[index]= (VideoMemory[index] & 0xFF00)|per;
}
break;
default:
terminal_column++;
VideoMemory[index]= (VideoMemory[index] & 0xFF00)|str;
break;
}
}
else
{
continue_ex = false;
}
}
int32_t strlen(int8_t* str)
{
int32_t l=0;
while(str[l]!='\0')l++;
return l;
}
char *itoa(int val)
{
uint8_t *ptr;
static uint8_t buffer[16];
ptr = buffer + sizeof(buffer);
*--ptr = '\0';
if (val == 0)
{
*--ptr = '0';
}
else while (val != 0)
{
*--ptr = (val % 10) + '0';
val = val / 10;
}
return((char*)ptr);
}
and stdio.h:
#ifndef _STD_LIB_H_
#pragma once
#define _STD_LIB_H_ 1
#include <stddef.h>
#include <stdint.h>
#include <stdarg.h>
#include "math.h"
#include "serial.h"
static const size_t VGA_WIDTH = 80;
static const size_t VGA_HEIGHT = 25;
//static int num_count_viedo_memory = 0;
void printf(char *str,...);
void putchar(char str,char next_str,va_list arg);
int32_t strlen(int8_t *str);
void strcat(char * Dest, char const * Src);
//int8_t* str_cat(int8_t *dest, const int8_t *src);
void reverse(char str[], int32_t length);
char* itoa(int val);
#endif
Like i described above , it is not incrementing through the args for some reason. Help would be appreciated! :)
Pass arg into your putchar function by reference instead of by value:
void putchar(char str,char next_str, va_list& arg)
What's happening is that it gets incremented inside your putchar function, but then the function returns and it has no effect on the variable in printf because putchar is passed a copy rather than a reference to it.
Related
I've been working on a C++ program, I've made the logic but I'm unable to execute it. The question is:
Task: Write a program, using functions only, with the following features.
Program reads paragraph(s) from the file and stores in a string.
Then program counts the occurrence of each word in the paragraph(s) and stores all words with their number of occurrences.
If that word has appeared more than one time in whole string, it should store the word only once along its total occurrences.
The output described in above (in part 3) must be stored in a new file.
Sample input:
is the is and the is and the and is and only that is
Sample output:
is 5
the 3
and 4
only 1
that 1
I'll cut short to Occurrence program that I've written,
My logic is to store token into character array and then compare that array with main character array and do the increment:
void occurances() {
char* string = getInputFromFile();
char separators[] = ",.\n\t ";
char* token;
char* nextToken;
char* temp[100];
token = strtok_s(string, separators, &nextToken);
cout << temp;
int counter = 0;
int i = 0;
while ((token != NULL)) {
temp[i] = token;
i++;
for (int i = 0; i < strlen(string); i++) {
for (int j = 0; j < 100; j++) {
if ((strcmp(token, *temp)) == 0) {
counter++;
}
}
cout << temp << " : " << counter << endl;
}
if (token != NULL) {
token = strtok_s(NULL, separators, &nextToken);
}
}
}
This code is preposterous I know that, But please anyone be kind enough to give me a clue, actually I'm new to C++ . Thank you
If you store token into array this array should grow dynamically because the number of tokens is not known at the beginning. And according to the task description, you cannot use C++ standard containers, so, it is necessary to implement dynamic array manually, for example:
#include <iostream>
std::size_t increase_capacity_value(std::size_t capacity) {
if (capacity == 0) {
return 1;
}
else if (capacity < (SIZE_MAX / 2)) {
return capacity * 2;
}
return SIZE_MAX;
}
bool increase_array_capacity(char**& tokens_array, std::size_t*& tokens_count, std::size_t& capacity) {
const std::size_t new_capacity = increase_capacity_value(capacity);
if (new_capacity <= capacity) {
return false;
}
const std::size_t tokens_array_byte_size = new_capacity * sizeof(char*);
char** const new_tokens_array = static_cast<char**>(std::realloc(tokens_array, tokens_array_byte_size));
if (new_tokens_array == nullptr) {
return false;
}
tokens_array = new_tokens_array;
const std::size_t tokens_count_byte_size = new_capacity * sizeof(std::size_t);
std::size_t* const new_tokens_count = static_cast<std::size_t*>(std::realloc(tokens_count, tokens_count_byte_size));
if (new_tokens_count == nullptr) {
return false;
}
tokens_count = new_tokens_count;
capacity = new_capacity;
return true;
}
bool add_token(char* token, char**& tokens_array, std::size_t*& tokens_count, std::size_t& array_size, std::size_t& array_capacity) {
if (array_size == array_capacity) {
if (!increase_array_capacity(tokens_array, tokens_count, array_capacity)) {
return false;
}
}
tokens_array[array_size] = token;
tokens_count[array_size] = 1;
++array_size;
return true;
}
std::size_t* get_token_count_storage(char* token, char** tokens_array, std::size_t* tokens_count, std::size_t array_size) {
for (std::size_t i = 0; i < array_size; ++i) {
if (std::strcmp(token, tokens_array[i]) == 0) {
return tokens_count + i;
}
}
return nullptr;
}
bool process_token(char* token, char**& tokens_array, std::size_t*& tokens_count, std::size_t& array_size, std::size_t& array_capacity) {
std::size_t* token_count_ptr = get_token_count_storage(token, tokens_array, tokens_count, array_size);
if (token_count_ptr == nullptr) {
if (!add_token(token, tokens_array, tokens_count, array_size, array_capacity)) {
return false;
}
}
else {
++(*token_count_ptr);
}
return true;
}
int main() {
char string[] = "is the is and the is and the and is and only that is";
char separators[] = ",.\n\t ";
std::size_t token_array_capacity = 0;
std::size_t token_array_size = 0;
char** tokens_array = nullptr;
std::size_t* tokens_count = nullptr;
char* current_token = std::strtok(string, separators);
while (current_token != nullptr) {
if (!process_token(current_token, tokens_array, tokens_count, token_array_size, token_array_capacity)) {
break;
}
current_token = std::strtok(nullptr, separators);
}
// print the report only if all tokens were processed
if (current_token == nullptr) {
for (std::size_t i = 0; i < token_array_size; ++i) {
std::cout << tokens_array[i] << " : " << tokens_count[i] << std::endl;
}
}
std::free(tokens_array);
std::free(tokens_count);
}
godbolt.org
okay what if i want to store any token once, in an array and then replace it with new word while deleting duplicates in character array
It is also possible solution. But in general case, it is also necessary to allocate the memory dynamically for the current token. Because the lengths of tokens are also not known at the beginning:
void replace_chars(char* str, const char* chars_to_replace) {
while (str && *str != '\0') {
str = std::strpbrk(str, chars_to_replace);
if (str == nullptr) {
break;
}
const std::size_t number_of_delimiters = std::strspn(str, chars_to_replace);
for (std::size_t i = 0; i < number_of_delimiters; ++i) {
str[i] = '\0';
}
str += number_of_delimiters;
}
}
bool keep_token(char*& token_storage, const char* new_token) {
if (new_token == nullptr) {
return false;
}
const std::size_t current_token_len = token_storage ? std::strlen(token_storage) : 0;
const std::size_t requried_token_len = std::strlen(new_token);
if (token_storage == nullptr || current_token_len < requried_token_len) {
token_storage =
static_cast<char*>(std::realloc(token_storage, (requried_token_len + 1) * sizeof(char)));
if (token_storage == nullptr) {
return false;
}
}
std::strcpy(token_storage, new_token);
return true;
}
std::size_t count_tokens_and_replace(char* str, std::size_t str_len, const char* token) {
std::size_t number_of_tokens = 0;
std::size_t i = 0;
while (i < str_len) {
while (str[i] == '\0') ++i;
if (std::strcmp(str + i, token) == 0) {
replace_chars(str + i, token);
++number_of_tokens;
}
i += std::strlen(str + i);
}
return number_of_tokens;
}
int main() {
char string[] = "is the is and the is and the and is and only that is";
char separators[] = ",.\n\t ";
const std::size_t string_len = std::strlen(string);
replace_chars(string, separators);
std::size_t i = 0;
char* token = nullptr;
while (true) {
while (i < string_len && string[i] == '\0') ++i;
if (i == string_len || !keep_token(token, string + i)) break;
std::cout << token << " : " << count_tokens_and_replace(string + i, string_len - i, token) << std::endl;
}
std::free(token);
}
godbolt.org
But if it is known that the token length cannot be greater than N, it is possible to use the static array of chars to keep the current token. And it will allow to remove dynamic memory allocation from the code.
I 'm reading "The Algorithm Design Manual (2nd Edition)". C++ is new for me.
I try to use example of author: string_compare(), and only code by myself main(). Output is wrong. I guess my main 's having problem with char s[], pointer.
Anyone can help me finding my mistake.
Code by C++, and very simple input
int main()
{
char s[] = "A"; // "thou shalt not"; //"FOOD";
char t[] = "B"; // "you should not"; //"MONEY";
int i = sizeof(s)/sizeof(char);
int j = sizeof(t)/sizeof(char);
int resultDistance = string_compare(s, t, i, j);
printf("N steps = %d\n", resultDistance);
reconstruct_path(s, t, i, j);
}
int string_compare(char *s, char *t, int i, int j)
{
int k; /* counter */
int opt[3]; /* cost of the three options */
int lowest_cost; /* lowest cost */
if (i == 0) return(j * indel(' '));
if (j == 0) return(i * indel(' '));
opt[MATCH] = string_compare(s,t,i-1,j-1) + match(s[i],t[j]);
opt[INSERT] = string_compare(s,t,i,j-1) + indel(t[j]);
opt[DELETE] = string_compare(s,t,i-1,j) + indel(s[i]);
lowest_cost = opt[MATCH];
for (k=INSERT; k<=DELETE; k++)
if (opt[k] < lowest_cost) lowest_cost = opt[k];
m[i][j].cost = lowest_cost; /* REMOVE FROM PRINTED VERSION */
return( lowest_cost );
}
int reconstruct_path(char *s, char *t, int i, int j)
{
/*printf("trace (%d,%d)\n",i,j);*/
if (m[i][j].parent == -1) return(0);
if (m[i][j].parent == MATCH) {
reconstruct_path(s,t,i-1,j-1);
match_out(s, t, i, j);
return(0);
}
if (m[i][j].parent == INSERT) {
reconstruct_path(s,t,i,j-1);
insert_out(t,j);
return(0);
}
if (m[i][j].parent == DELETE) {
reconstruct_path(s,t,i-1,j);
delete_out(s,i);
return(0);
}
}
int match_out(char *s, char *t, int i, int j)
{
if (s[i]==t[j]) printf("M");
else printf("S");
return(0);
}
void insert_out(char *t, int j)
{
printf("I");
}
void delete_out(char *s, int i)
{
printf("D");
}
int indel(char c)
{
return(1);
}
int match(char c, char d)
{
if (c == d) return(0);
else return(1);
}
My code on github: https://github.com/hoangvu1991/EditDistanceRecursive/blob/master/EditDistanceRecursive.cpp
actual: 0 | expect:1
Try following:
opt[MATCH] = string_compare(s,t,i-1,j-1) + match(s[i-1],t[j-1]);
instead of
opt[MATCH] = string_compare(s,t,i-1,j-1) + match(s[i],t[j]);
I have a function that takes a user entered string and splits it into individual words using a dynamically allocated two-dimensional array. The words are separated by delimiters used as indicators of where one word ends and another begins.
Here is my code:
int countWords(const char * sentence, char * delims)
{
int wordsInArray = 0;
int count = 0;
while(*(sentence + count) != '\0')
{
if(*(sentence + count) == *delims && *(sentence + count + 1) != *delims)
{
wordsInArray++;
}
if(*(sentence + count + 1) == '\0')
{
wordsInArray++;
}
count++;
}
return wordsInArray;
}
int getLength(const char * sentence)
{
const char *p = sentence;
while(*p != '\0')
{
p++;
}
return p-sentence;
}
char ** getWords(const char * sentence, int & wordcount)
{
char delims[] = " .,\t?!";
int sentenceLength = getLength(sentence);
wordcount = countWords(sentence, delims);
char ** words;
words = new char *[wordcount];
int length = 0;
int count = 0;
for (int a = 0; a < sentenceLength; a++)
{
if(*(sentence + a) != *delims)
{
length++;
}
else if ((*(sentence + a) == *delims && *(sentence + a + 1) != *delims) || *(sentence + a) == '\0')
{
*(words + count) = new char[length+1];
for (int z = 0; z < length; z++)
{
*(*(words + count) + z) = *(sentence + z);
}
length = 0;
count++;
}
}
return words;
}
However, my countWords function is not properly counting the words in the string, and I do not know why.
Try something more like this:
int indexOf(const char * sequence, char ch) {
const char *p = sequence;
while (*p != '\0') {
if (*p == ch) {
return p - sequence;
}
}
return -1;
}
const char* findFirstOf(const char * sequence, const char *chars) {
const char *p = sequence;
while (*p != '\0') {
if (indexOf(chars, *p) != -1) {
return p;
}
}
return NULL;
}
const char* findFirstNotOf(const char * sequence, const char *chars) {
const char *p = sequence;
while (*p != '\0') {
if (indexOf(chars, *p) == -1) {
return p;
}
}
return NULL;
}
int countWords(const char * sequence, char * delims) {
int count = 0;
const char *p = sequence;
do {
p = findFirstNotOf(p, delims);
if (p == NULL) break;
++count;
p = findFirstOf(p, delims);
}
while (p != NULL);
return count;
}
int getLength(const char * sequence) {
const char *p = sequence;
while (*p != '\0') {
++p;
}
return p-sequence;
}
char* dupString(const char * sequence, int length = -1) {
if (length == -1) {
length = getLength(sequence);
}
char *result = new char[length+1];
for (int i = 0; i < length; ++i) {
result[i] = sequence[i];
}
result[length] = '\0';
return result;
}
char** getWords(const char * sequence, int & wordcount) {
const char delims[] = " .,\t?!";
int count = countWords(sequence, delims);
char ** words = new char *[count];
if (count > 0) {
count = 0;
const char *p = sequence;
do {
p = findFirstNotOf(p, delims);
if (p == NULL) break;
const char *q = findFirstOf(p, delims);
if (q == NULL) {
words[count++] = dupString(p);
break;
}
words[count++] = dupString(p, q-p);
p = ++q;
}
while (true);
}
wordcount = count;
return words;
}
That being said, the fact you are using new[] means you are using C++, so you should be using the STL to make life easier:
#include <string>
#include <vector>
std::vector<std::string> getWords(const std::string & sequence) {
const char delims[] = " .,\t?!";
std::vector<std::string> words;
std::string::size_type i = 0;
do {
i = sequence.find_first_not_of(delims, i);
if (i == std::string::npos) break;
std::string::size_type j = sequence.find_first_of(delims, i);
if (j == std::string::npos) {
words.push_back(sequence.substr(i));
break;
}
words.push_back(sequence.substr(i, j-i));
i = ++j;
}
while (true);
return words;
}
Header code
/*
* MngCommunication.h
*
* Created on: 26 gen 2017
* Author: Giuliano
*/
#ifndef _MNGCOMMUNICATION_H_
#define _MNGCOMMUNICATION_H_
// ------------------------- N.B. MngCommunication is a Singleton class!!! ----------------------------
#if (ARDUINO < 100)
#include <WProgram.h>
#else
#include <Arduino.h>
#endif
class MngCommunication
{
public:
static MngCommunication* getInstance();
size_t LogLine(const __FlashStringHelper *ifsh, boolean end=false);
size_t LogLine(const String &str, boolean end=false);
size_t LogLine(const char str[], boolean end=false);
size_t LogLine(const unsigned char n, boolean end=false);
size_t LogLine(const int n, boolean end=false);
size_t LogLine(const unsigned int n, boolean end=false);
size_t LogLine(const long n, boolean end=false);
size_t LogLine(const unsigned long n, boolean end=false);
size_t LogLine(const double n, boolean end=false);
size_t LogLine(const Printable&str, boolean end=false);
protected:
static MngCommunication* _inst_;
MngCommunication();
};
#endif /* MNGCOMMUNICATION_MNGCOMMUNICATION_H_ */
C++ code
/*
* MngCommunication.cpp
*
* Created on: 26 gen 2017
* Author: Giuliano
*/
#include <string.h>
#include "MngCommunication.h"
MngCommunication* MngCommunication::_inst_ = NULL;
MngCommunication::MngCommunication()
{
Serial.begin(57600);
}
MngCommunication* MngCommunication::getInstance()
{
if (_inst_ == NULL) _inst_ = new MngCommunication;
return _inst_;
}
//--------------------------------------------------------------------
//--------------------------------------------------------------------
// ------------------------ LOGGING FUNCTION -------------------------
//--------------------------------------------------------------------
//--------------------------------------------------------------------
boolean started=false;
inline size_t startLine(void)
{
static char timebuffer[8];
size_t sz = 0;
sprintf(timebuffer,"%08lu", millis());
sz += Serial.print("#L-");
sz += Serial.print(timebuffer);
sz += Serial.print("-");
started=true;
return sz;
}
inline size_t endline(void)
{
started = false;
return Serial.write("\r\n");
}
size_t MngCommunication::LogLine(const __FlashStringHelper *ifsh, boolean end)
{
size_t sz=0;
if (!started)
{
sz += startLine();
started = true;
}
sz += Serial.print(ifsh);
if (end)
{
sz += endline();
}
return sz;
}
size_t MngCommunication::LogLine(const String &str, boolean end)
{
size_t sz=0;
if (!started)
{
sz += startLine();
started = true;
}
sz += Serial.print(str);
if (end)
{
sz += endline();
}
return sz;
}
size_t MngCommunication::LogLine(const char str[], boolean end)
{
size_t sz=0;
if (!started)
{
sz += startLine();
started = true;
}
sz += Serial.print(str);
if (end)
{
sz += endline();
}
return sz;
}
size_t MngCommunication::LogLine(const unsigned char n, boolean end)
{
return LogLine((unsigned long) n, end);
}
size_t MngCommunication::LogLine(const int n, boolean end)
{
return LogLine((long) n, end);
}
size_t MngCommunication::LogLine(const unsigned int n, boolean end)
{
return LogLine((unsigned long) n, end);
}
size_t MngCommunication::LogLine(const long n, boolean end)
{
size_t sz=0;
if (!started)
{
sz += startLine();
started = true;
}
sz += Serial.print(n);
if (end)
{
sz += endline();
}
return sz;
}
size_t MngCommunication::LogLine(const unsigned long n, boolean end)
{
size_t sz=0;
if (!started)
{
sz += startLine();
started = true;
}
sz += Serial.print(n);
if (end)
{
sz += endline();
}
return sz;
}
size_t MngCommunication::LogLine(const double n, boolean end)
{
size_t sz=0;
if (!started)
{
sz += startLine();
started = true;
}
sz += Serial.print(n);
if (end)
{
sz += endline();
}
return sz;
}
size_t MngCommunication::LogLine(const Printable&str, boolean end)
{
size_t sz=0;
if (!started)
{
sz += startLine();
started = true;
}
sz += Serial.print(str);
if (end)
{
sz += endline();
}
return sz;
}
If I use LogLine() function with string or char buffers, all is OK. e.g.:
MngCommunication* Comm;
Comm = MngCommunication::getInstance();
Comm.LogLine("this ");
Comm.LogLine("is ");
Comm.LogLine("a ");
Comm.LogLine("test!!! ", true);
The strange is the call with number:
if i call LogLine() with number e.g.:
MngCommunication* Comm;
Comm = MngCommunication::getInstance();
Comm.LogLine(millis());
code execution is OK. but a second call, with number or string, reboot Arduino. The same is if i call the function first with string and then with number. e.g.:
MngCommunication* Comm;
Comm = MngCommunication::getInstance();
Comm.LogLine("this ");
Comm.LogLine("is ");
Comm.LogLine("a ");
Comm.LogLine("test!!! ");
Comm.LogLine("time= ");
Comm.LogLine(mills());
static char timebuffer[8];
sprintf(timebuffer,"%08lu", millis());
First of all this buffer is too small. There has to be space for the string terminator (zero byte), so you have a buffer overflow which can cause all sort of strange effects.
This buffer should be at least 11 bytes long. 10 bytes for the max number (32 bit) and one for the string terminator.
I suppose mills() was a typo?
Do you have the same problem when using a constant value, like Comm.LogLine(123);?
And what if you call:
Comm.LogLine(123, true);
Comm.LogLine(456);
I searched over the net how to return a vector object but I can't find the simplest one. First of all, I am not expert in C++ and I just started C++ few weeks ago. Is it not okay to return an object vector?
I have something like this.
I pushed it somewhere through this:
MAIN File:
int main()
{
XIniFile *f = new XIniFile();
int result = 0;
int v = 0;
char *val;
result = f->open("doc2.ini");
if (INI_FILE_RES_OK == result) {
}
else
printf("Error[%d]\n", result);
}
CPP File:
XKey::XKey()
{
}
XKey::~XKey()
{
}
XSection::XSection()
{
}
XSection::~XSection()
{
}
XKey *XSection::addKey(const char *k, const char *val)
{
XKey *nk = new XKey;
nk->setName(k);
nk->setValue(val);
m_vkey.push_back(*nk);
return nk;
}
void XSection::showKey()
{
vector<XKey>::iterator ik;
for (ik = m_vkey.begin(); ik != m_vkey.end(); ik++)
printf("%s = %s\n", ik->getName(), ik->getValue());
}
XIniFile::XIniFile()
{
m_modified = false;
}
int XIniFile::open(const char *fn)
{
XSection *cs;
char *sn;
char *kn;
char *val;
int i = 0;
FILE *f;
f = fopen(fn, "r");
if (!f)
return INI_FILE_ERROR;
struct stat file_stat;
stat(fn, &file_stat);
int size = file_stat.st_size;
m_name = strdup(fn);
char *d = (char *)malloc(size * sizeof(char *) + 1);
fread(d, size, 1, f);
while (i < size) {
while (d[i] != '[') i++;
if (d[i] == '[') {
i++;
while (isspace(d[i])) i++;
sn = &d[i];
while (d[i] != ']')
i++;
d[i++] = 0;
cs = addSection(sn);
while (isspace(d[++i]));
while(d[i] != '[') {
while (isspace(d[i])) i++;
kn = &d[i];
while (d[i] != '=') i++;
d[i-1] = 0;
i++;
while (isspace(d[i])) i++;
if (d[i] == '[') {
i++;
val = &d[i];
while (isspace(d[i])) i++;
d[i-1] = 0;
}
else {
val = &d[i];
while (d[i] != '\n') i++;
d[i] = 0;
}
i++;
cs->addKey(kn, val);
while (isspace(d[i])) {
i++;
if (i >= size) break;
}
if (i >= size) break;
}
}
}
free(d);
vector<XSection>::iterator is;
for (is = m_vsection.begin(); is != m_vsection.end(); is++) {
printf("[%s]\n", is->getName());
printf("is->getSize()[%d]\n", is->getSize());
}
fclose(f);
return INI_FILE_RES_OK;
}
XIniFile::~XIniFile()
{
delete m_name;
}
XSection *XIniFile::addSection(const char *s)
{
XSection *ns = new XSection;
ns->setName(s);
m_vsection.push_back(*ns);
return ns;
}
void XIniFile::showSection()
{
vector<XSection>::iterator is;
for (is = m_vsection.begin(); is != m_vsection.end(); is++)
printf("[%s]\n", is->getName());
printf("End\n");
}
Header File:
class XKey
{
public:
XKey();
virtual ~XKey();
void *setName(const char *k) {m_name = strdup(k);}
void *setValue(const char *v) {m_value = strdup(v);}
char *getName(){return m_name;}
char *getValue(){return m_value;}
private:
char *m_name;
char *m_value;
};
class XSection
{
public:
XSection();
virtual ~XSection();
void *setName(const char *n) {m_name = strdup(n);}
char *getName() {return m_name;}
XKey *addKey(const char *k, const char *v);
vector<XKey> getKey() {return m_vkey;}
int getSize() {return m_vkey.size();}
void showKey();
private:
char *m_name;
vector<XKey> m_vkey;
};
class XIniFile
{
public:
XIniFile();
virtual ~XIniFile();
int open(const char *);
int readString(const char *, const char *, char **);
int readInt(const char *, const char *, int *);
XSection *addSection(const char *);
void showSection();
private:
char *m_name;
vector<XSection> m_vsection;
bool m_modified;
};
the problem here is that under CPP file is->getSize() doesn't increase even if I used push_back on m_vkey which could be found on my addKey method.
It's because the object you're modifying is not the same as the one you're storing.
Look here:
XSection *XIniFile::addSection(const char *s)
{
XSection *ns = new XSection; // Create a new XSection
ns->setName(s);
m_vsection.push_back(*ns); // Store a copy of ns
return ns; // Return the original ns
}
Now when you do something with the return value, the object in m_vsection is unaffected.
The quickest fix is to store the pointers you're returning in m_vsection instead, and similar for the section objects.
Although you should probably start using std::shared_ptr (not to mention std::string) if at all possible.