View unanswered posts | View active topics It is currently Thu Aug 21, 2014 6:55 am






Reply to topic  [ 23 posts ]  Go to page 1, 2  Next
1.38 BUG: errors at string and char[] operations 
Author Message
Guru
User avatar

Joined: Sat Mar 01, 2008 12:52 pm
Posts: 1030
Post 1.38 BUG: errors at string and char[] operations
why do I always get errors here?

Code:
#define println nxtDisplayTextLine

char chstr1[20];
char chstr2[20];
string s;

task main()
{
    s="abcdefg";
    chstr1="qwertzu"; // error
    strcpy(chstr2,s); // error

    println(0,"%s",s);
    println(1,"%s",chstr1); // error
    println(2,"%s",chstr2); // error

  while(true) { wait1Msec(50); }
}


what's wrong?

_________________
regards,
HaWe aka Ford
#define S sqrt(t+2*i*i)<2
#define F(a,b) for(a=0;a<b;++a)
float x,y,r,i,s,j,t,n;task main(){F(y,64){F(x,99){r=i=t=0;s=x/33-2;j=y/32-1;F(n,50&S){t=r*r-i*i;i=2*r*i+j;r=t+s;}if(S){PutPixel(x,y);}}}while(1)}


Last edited by Ford Prefect on Fri Jul 25, 2008 3:51 pm, edited 4 times in total.



Sat Mar 22, 2008 2:12 pm
Profile
Rookie

Joined: Sun Mar 02, 2008 9:41 am
Posts: 25
Post hi
I dont think u can do that kind of allocation in the array. You need to define the starting bit of where you start storing values in the array, or you need to specify for every single character in which point of the array it should be stored.


hope this helps


Sat Mar 22, 2008 3:28 pm
Profile
Guru
User avatar

Joined: Sat Mar 01, 2008 12:52 pm
Posts: 1030
Post 
no way to store a string to an array of char? :evil:

and what about to allocate or access a single character in a string, such as

Code:
char c;
string s;

s="qwertz";
c=s[3]; // should be "e" (or "r" if counting started with 0)


:?:

_________________
regards,
HaWe aka Ford
#define S sqrt(t+2*i*i)<2
#define F(a,b) for(a=0;a<b;++a)
float x,y,r,i,s,j,t,n;task main(){F(y,64){F(x,99){r=i=t=0;s=x/33-2;j=y/32-1;F(n,50&S){t=r*r-i*i;i=2*r*i+j;r=t+s;}if(S){PutPixel(x,y);}}}while(1)}


Last edited by Ford Prefect on Sat Mar 22, 2008 4:00 pm, edited 1 time in total.



Sat Mar 22, 2008 3:40 pm
Profile
Rookie

Joined: Fri Apr 20, 2007 3:22 am
Posts: 36
Post 
It's becasue a chr array is not the same as a string.

chstr1="qwertzu";

should be

chstr1 = {"q","w","e","r","t","z","u"}

strcpy won't work here either


memcpy(chrstr1, s, sizeof(s)); should work


Sat Mar 22, 2008 3:50 pm
Profile
Guru
User avatar

Joined: Sat Mar 01, 2008 12:52 pm
Posts: 1030
Post 
ok, thx, this might work! :)

But then 2 questions are left:

1) how can I print this array of char?

and
2)how to allocate or access a single character in a string, such as

Code:
char c;
string s;

s="qwertz";
c=s[3]; // should be "e" (or "r" if counting started with 0)

_________________
regards,
HaWe aka Ford
#define S sqrt(t+2*i*i)<2
#define F(a,b) for(a=0;a<b;++a)
float x,y,r,i,s,j,t,n;task main(){F(y,64){F(x,99){r=i=t=0;s=x/33-2;j=y/32-1;F(n,50&S){t=r*r-i*i;i=2*r*i+j;r=t+s;}if(S){PutPixel(x,y);}}}while(1)}


Sat Mar 22, 2008 3:57 pm
Profile
Rookie

Joined: Fri Apr 20, 2007 3:22 am
Posts: 36
Post 
Code:
char subchar(string source,int element)
{
   char temp[sizeof(source)];
   memcpy( temp,source, sizeof(source));
   return temp[element];
}

task main()
{
   string s = "Hello";
   char mychar;

   mychar = subchar(s,2);

   nxtDisplayTextLine(1,"%s",s);
   nxtDisplayTextLine(2,"%s",(string)mychar);

   char cArray[10];
   memcpy( cArray,s, sizeof(s));

   nxtDisplayTextLine(3,"%s",(string)cArray[1]);

   while(true);
}


is that what you're after?


Sat Mar 22, 2008 5:10 pm
Profile
Rookie

Joined: Fri Apr 20, 2007 3:22 am
Posts: 36
Post 
Poking a bit more, there really should be a substring fucntion

so

Code:
char subchar(string source,int element)
{
   char temp[sizeof(source)];
   memcpy( temp,source, sizeof(source));
   return temp[element];
}

void substring(string source, string &back, int v1,int v2)
{
      back="";
      int i;
      char temp[sizeof(source)];
      char outString[sizeof(source)];
      memcpy( temp,source, sizeof(source));
      for(i = v1; i<=v2; i++)
         outString[i-v1] = (byte)temp[i];

      outString[v2-v1+1]= (byte)"\0";
       memcpy(back,outString,(v2-v1+1));
}

task main()
{
   string s = "Hello";
   char mychar;

   mychar = subchar(s,2);

   nxtDisplayTextLine(1,"%s",s);
   nxtDisplayTextLine(2,"%s",(string)mychar);

   char cArray[10];
   memcpy( cArray,s, sizeof(s));

   nxtDisplayTextLine(3,"%s",(string)cArray[1]);

   string substr;

   substring(s,substr,2,3);
   nxtDisplayTextLine(4,"%s",substr);


   while(true);
}


This works but I'm not entirely sure it's "propper" :wink:


Sat Mar 22, 2008 5:30 pm
Profile
Guru
User avatar

Joined: Sat Mar 01, 2008 12:52 pm
Posts: 1030
Post 
it's fine! thx a lot!

But to the developers: I wonder why the code posted above doesn't work...

_________________
regards,
HaWe aka Ford
#define S sqrt(t+2*i*i)<2
#define F(a,b) for(a=0;a<b;++a)
float x,y,r,i,s,j,t,n;task main(){F(y,64){F(x,99){r=i=t=0;s=x/33-2;j=y/32-1;F(n,50&S){t=r*r-i*i;i=2*r*i+j;r=t+s;}if(S){PutPixel(x,y);}}}while(1)}


Last edited by Ford Prefect on Sat Jul 12, 2008 2:08 pm, edited 2 times in total.



Sat Mar 22, 2008 6:22 pm
Profile
Rookie

Joined: Wed Jun 25, 2008 9:38 pm
Posts: 6
Post 
What am I overlooking? I copied squiggy's code and compiled -> all is fine.

Then I commented out three lines:

Code:
char subchar(string source,int element)
{
   char temp[sizeof(source)];
   memcpy( temp,source, sizeof(source));
   return temp[element];
}

void substring(string source, string &back, int v1,int v2)
{
      back="";
      int i;
      char temp[sizeof(source)];
      char outString[sizeof(source)];
      memcpy( temp,source, sizeof(source));
      for(i = v1; i<=v2; i++)
         outString[i-v1] = (byte)temp[i];

      outString[v2-v1+1]= (byte)"\0";
       memcpy(back,outString,(v2-v1+1));
}


task main()
{
   string s = "Hello";
   char mychar;

   mychar = subchar(s,2);

   nxtDisplayTextLine(1,"%s",s);
   nxtDisplayTextLine(2,"%s",(string)mychar);

//   char cArray[10];
//   memcpy( cArray,s, sizeof(s));

//   nxtDisplayTextLine(3,"%s",(string)cArray[1]);

   string substr;

   substring(s,substr,2,3);
   nxtDisplayTextLine(4,"%s",substr);


   while(true);
}


and the last line is empty now. Why? The lines should not change anything about the string variable s?!?


Wed Jun 25, 2008 9:55 pm
Profile
Rookie
User avatar

Joined: Thu Jun 26, 2008 11:27 am
Posts: 21
Location: Johannesburg, South Africa
Post Convert string to array
'strcpy' won't work to copy a string to an array but strangely 'strcat' does

eg
string str = "ABCD";
char chars[5];
strcat(chars,str);


Thu Jun 26, 2008 11:42 am
Profile WWW
Rookie

Joined: Fri Apr 20, 2007 3:22 am
Posts: 36
Post 
I'm not sure if this is a bug in the program or robotc.

It has to do with the char temp[sizeof(source)]; line.

if you remove that that and add a global variable ` char temp[20]; ` it;'s fine.

It's actaully the removal of the ` char cArray[10]; ` that causes the problem.

I'm not sure why this is happening. I've tried a bunch of variations on the code and can't figure out exactly what's happening.

I would think that the inclusion of char cArray[10]; was providing a buffer for the temp array in substring. If that is correct then if i tried the following

Code:
task main()
{
   string s = "Hello";
   char mychar;
   string substr;

   mychar = subchar(s,2);

   nxtDisplayTextLine(1,"%s",s);
   nxtDisplayTextLine(2,"%s",(string)mychar);

   char cArray[sizeof(s)];
   memcpy( cArray,s, sizeof(s));

   substring(s,substr,2,3);

   nxtDisplayTextLine(4,"%s",substr);

   nxtDisplayTextLine(3,"%s",(string)cArray[1]);

   while(true);
}


I would expect the results in cArray to get currupted by the substring call. But they don't.

I'm not sure that the line char temp[sizeof(source)]; is ok in robotc. I think that dimensions need to be static. However that doesn't work either. So I don't know.


Sat Jun 28, 2008 1:21 am
Profile
Rookie
User avatar

Joined: Thu Jun 26, 2008 11:27 am
Posts: 21
Location: Johannesburg, South Africa
Post 
I use the following code to get a substring. There seems to be rather a lot of bugs with arrays and strings in v1.10 but the following seems to work fine.
Code:
 void SubString(string inStr,string& outStr,int start, int len)
 {
      string tmpStr = "";
      char chars[20];
     strcat(chars,inStr);
     for (int ctr = start;ctr<start + len;++ctr)
      tmpStr += chars[ctr];

   outStr = tmpStr;
 }
 task main ()
 {
     string str;
      SubString("ABCDEFGHIJK",str,4,2);
      nxtDisplayTextLine(3,str);

      wait10Msec(1000);
}


Sat Jun 28, 2008 4:07 am
Profile WWW
Guru
User avatar

Joined: Sat Mar 01, 2008 12:52 pm
Posts: 1030
Post 
hi, actually your code is fine;
but to my opinion there should be a clear difference between ANSI C and C++ operations, and in both cases RobotC should match the standards!

This is how it should work:

(ANSI C):
strcpy , strcat, strcmp
are working with arrays of char:
Code:
#define printf nxtDisplayTextLine
char name1[8], name2[8], temp[20];

strcpy(name1,"Athene");
strcpy(name2,"Zeus");
if strcmp(name1,name2)>0
{ strcpy(temp,name1);}
else
strcpy(temp, name2);
printf(1, "%s","bigger: ");
printf(2, "%s", temp);
temp="";
strcat(temp, name1);
strcat(temp, " & ");
strcat(temp, name2);
printf(3, "%s", "both: ");
printf(4, "%s", temp);


(C++):
is working with type "string" (terminated by chr(0))
see this: http://www.bgsu.edu/departments/compsci/docs/string.html
especially:
Code:
Substring s = s2.substr(1,4);
s = s2.substr(1,50);

The first example starts in position 1 of s2 and takes 4 characters, setting s to "bcde". In the second example, s is set to "bcde uvwxyz". If the length specified is longer than the remaining number of characters, the rest of the string is used. The first position in a string is position 0.

Character array to string
Code:
s = ch;

Converts character array ch into string s.

String to character array
Code:
cp = s.c_str();

Pointer cp points to a character array with the same characters as s

I don't understand, why RobotC consistantly mismatches C and C++ definitions !?!!

_________________
regards,
HaWe aka Ford
#define S sqrt(t+2*i*i)<2
#define F(a,b) for(a=0;a<b;++a)
float x,y,r,i,s,j,t,n;task main(){F(y,64){F(x,99){r=i=t=0;s=x/33-2;j=y/32-1;F(n,50&S){t=r*r-i*i;i=2*r*i+j;r=t+s;}if(S){PutPixel(x,y);}}}while(1)}


Sat Jun 28, 2008 4:44 am
Profile
Rookie

Joined: Wed Jun 25, 2008 9:38 pm
Posts: 6
Post 
The purpose of strcat(a,b) seems to be something completely different: It theoretically should append b to a if I didn't get the help completely wrong. I guess that in your programs the right strings happened to be next to each other in the nxt's memory.

Here are to programs:

Code:
#pragma platform(NXT)

#define min(a,b) ((a<b)?a:b)
#define max(a,b) ((a<b)?b:a)

#define FULLDEBUG
#ifdef FULLDEBUG
#define DEBUG
#endif

string progs[16];

void init()
{
   char tmpchars[20];
   TFileIOResult nIoResult;
   TFileHandle dscFile;
   short nFileSize;
   FindFirstFile(dscFile, nIoResult, "*.dsc", progs[0], nFileSize);
   if (nIoResult != 0)
   {
      nxtDisplayTextLine(3,"ERROR: NO FILE!");
   }
   else
   {
      strcat(tmpchars, "Hallo");
//      nxtDisplayTextLine(6, "Huhuh %s", (string) tmpchars[3]);
//      progs[0] = 0;
//      for (int i = 1; i<3; i++)
//      {
//         progs[0] += (string) tmpchars[i];
//      }
//      progs[0] = "Hallo";
      for (int i = 1; nIoResult == 0; i++)
      {
         FindNextFile(dscFile, nIoResult, progs[i], nFileSize);
      }
   }
}

task main()
{
   init();
   int i = 0;
   while ((strcmp(progs[i], "") != 0) || (i <= 2))
   {
      nxtDisplayTextLine(i, "%d%s", i, progs[i]);
      i++;
   }
   wait1Msec(2000);
}


and


Code:
#pragma platform(NXT)

#define min(a,b) ((a<b)?a:b)
#define max(a,b) ((a<b)?b:a)

#define FULLDEBUG
#ifdef FULLDEBUG
#define DEBUG
#endif

string progs[16];

void init()
{
   char tmpchars[20];
   TFileIOResult nIoResult;
   TFileHandle dscFile;
   short nFileSize;
   FindFirstFile(dscFile, nIoResult, "*.dsc", progs[0], nFileSize);
   if (nIoResult != 0)
   {
      nxtDisplayTextLine(3,"ERROR: NO FILE!");
   }
   else
   {
//      strcat(tmpchars, "Hallo");
//      nxtDisplayTextLine(6, "Huhuh %s", (string) tmpchars[3]);
//      progs[0] = 0;
//      for (int i = 1; i<3; i++)
//      {
//         progs[0] += (string) tmpchars[i];
//      }
//      progs[0] = "Hallo";
      for (int i = 1; nIoResult == 0; i++)
      {
         FindNextFile(dscFile, nIoResult, progs[i], nFileSize);
      }
   }
}

task main()
{
   init();
   int i = 0;
   while ((strcmp(progs[i], "") != 0) || (i <= 2))
   {
      nxtDisplayTextLine(i, "%d%s", i, progs[i]);
      i++;
   }
   wait1Msec(2000);
}


(Sorry for the mess) The line I commented out in the second file should not change anything. In fact, the first program lists all files named *.dsc on the brick, the second doesn't.


Tue Jul 01, 2008 10:33 am
Profile
Rookie

Joined: Wed Jun 25, 2008 9:38 pm
Posts: 6
Post 
All in all, I have not yet seen any way to transfer a string into chars. I even can't access the 2. letter of a string like one might expect:

Code:
string tmp = "Hello World";
nxtDisplayTextLine(1,"%s",tmp[1]);


Anything like this would solve my problem.


Tue Jul 01, 2008 10:59 am
Profile
Display posts from previous:  Sort by  
Reply to topic   [ 23 posts ]  Go to page 1, 2  Next

Who is online

Users browsing this forum: No registered users and 2 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  



Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group.
Designed by ST Software for PTF.