Page 1 of 1

NXC string manipulation

Posted: 23 Jun 2011, 02:29
by mattallen37
First, I want to say that I don't know the exact term I should use. I think it is "struct", but please correct me if I'm wrong.

I want to have a file with an undetermined number of lines. I want to read it into a struct.

What I have been doing is this:

Code: Select all

#define Max_number_of_lines 25
string Original_Message[Max_number_of_lines];
I specify the max number of lines, and it creates the string to that size. However, I don't want to use more memory than I need to.

After I create that string, I read the individual lines into it using this lib function I coded:

Code: Select all

void ReadFile(string file_name, int & Read_Line_i, string & message_struct[])
{
  byte File_Handle;
  int File_Size;
  string File_Line_Message;
  bool Rdone = false;

  if(OpenFileRead(file_name, File_Size, File_Handle) == NO_ERR)
  {
    until (Rdone == true)  // read the text file till the end
    {
      if(ReadLnString(File_Handle, File_Line_Message) != NO_ERR) Rdone = true;
      message_struct[Read_Line_i] = File_Line_Message;
      Read_Line_i++;
    }
  }
  CloseFile(File_Handle);

  for (int i=Read_Line_i; i < Max_number_of_lines; i++){   //Fill the rest with nothing
    message_struct[i]="";
  }
}
At the end, I have it fill the remaining strings of the struct with "" (nothing).

How can I size it to the exact number of lines, efficiently? For arrays, I use "ArrayInit", and that's supposed to be good, but how do I do it for structs?

How do you recommend I read a file into a struct of strings? I want to address the lines (individual strings) with a variable like this "Original_Message[LineToRead];".

Re: NXC string manipulation

Posted: 23 Jun 2011, 02:59
by muntoo
This is what I'd do:

Code: Select all

#define INIT_LINES 25
string Original_Message[];


#define PUSH(type,out,val) \
	{ \
		type out##_tmp[]; \
		asm \
		{ \
			arrbuild out##_tmp, out, val \
			mov out, out##_tmp \
			arrinit out##_tmp, 0, 0 \
		} \
	}


void ReadFile(string filename, int &lines, string &message[])
{
	byte handle;
	int fsize;
	string line;
	bool Rdone = false;
	
	
	ArrayInit(message, "", INIT_LINES);


	if(OpenFileRead(filename, fsize, handle) == NO_ERR)
	{
		// read the text file till the end
		while(!Rdone)
		{
			if(ReadLnString(handle, line) != NO_ERR)
				Rdone = true;
			
			if(lines < INIT_LINES)
			{
				message[lines] = line;
			}
			else
			{
				PUSH(string, message, line)
			}
			
			++lines;
		}
	}

	CloseFile(handle);
}
If you plan on going above 25 lines, you could speed it up by preallocating twice the current length of message, and then PUSH()ing until the end of the array is reached. (Then you reallocate again.)