Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
Home
Discussion Groups
General
GeneralPortable MacsHardwareNetworking
Applications
Mac ApplicationsEudoraFirefox / MozillaInternet ExplorerOutlook ExpressMS OfficeEntourageExcelPowerPointWordVirtual PCMedia PlayerOther MS Products
Programming
Mac ProgrammingCodeWarriorPerl
Country Specific
Australian Mac GroupUK Mac Group

Mac Forum / Programming / Mac Programming / February 2010



Tip: Looking for answers? Try searching our database.

easy parsing problem in C for beginner

Thread view: 
Enable EMail Alerts  Start New Thread
Thread rating: 
John Mosby - 07 Feb 2010 14:17 GMT
I am having trouble as a C beginning trying to compile the code below
using XCode.  I am new to C and have always programmed in pascal in
the past. This is to be a plugin for 4th Dimension.  Most of the hooks
were generated with "4D Plugin Wizard".  It generates the C code for
the plugin to be used by XCode.  I think most of my errors are simple
declaration problems or problems with the C language.  I am getting
the following errors:

error: parse error before "int"
error: parse error before "char"
error: parse error before '+' token
error: subscripted value is neither array nor pointer

The code follows:

/*
--------------------------------------------------------------------------------
#
#    4DPlugin.c
#    source generated by 4D Plugin Wizard
#    Project : new Project
#    author : subaru
#    1/29/10
#
# This plugin should recieve two variable from the main 4D program.
#
# The first variable from 4D --------------
# One will be an array of length 54 composed of
# characters (0-9 and A-Z).  Each element represents a schedule day.
Each character in the element represents a
# 10 minute block of time in the schedule.  When the character is 0
(zero) there is nothing scheduled for that time.
# The difficulty of the the 10 minute time block increases as the
ascii value of the character that represents it
# increases in value from 0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F,..... etc.
#
# The second variable from 4D --------------
# This variable will be an integer value that represents the
difficulty of the new appointment.
# This value should be subtracted from the ascii value of the
character that represents each 10 minute
# time block.  The harder the new appointment the smaller the value
of the variable for the difficulty.
#
--------------------------------------------------------------------------------
*/

// -------------------------------- schedule Plugin
-------------------------------

void s_Convert_Array( PA_PluginParameters params )
{

    PA_Variable DayArray; //an array of characters of length 54 from 4d
    short Difficulty;  //an interger denoting difficulty of an
appointment
    PA_Variable FinishedArray;  // completed array returned to 4D
    char returnValue[256];

    DayArray = PA_GetVariableParameter( params, 1 );
    Difficulty = PA_GetShortParameter( params, 2 );

    // --- write the code of s_Convert_Array here...

{
int counter = 0;
int array_size = sizeof(DayArray);
int Day_Difficulty_AsciiValue; //used to hold one character
int slot_number;
char slot_char;

while (counter < array_size)  //array_size should be the number of
elements of array DayArray
{
    counter++;

    int counter2 = 0;
    while (counter2 < 55)  //stepping through each character of DayArray
    {
        counter2++;

//ERROR BELOW (error before "int")
        Day_Difficulty_AsciiValue =int(DayArray[counter2]);  // function to
convert a char in array to ascii value
        if (Day_Difficulty_AsciiValue>=65) // is character a letter
            slot_number = Day_Difficulty_AsciiValue-7-48;
        else //character is a number
            slot_number = Day_Difficulty_AsciiValue-48;

        slot_number = slot_number - Day_Difficulty_AsciiValue;

        if(slot_number<0)
            slot_number = 0;

// convert the number to the characters 0-1,A-Z
// 48 is the number of ascii values before the numbers begin
// 7 is the numbere of unused ascii values between the numbers and
capital letters

        if(slot_number>=10) //number will be converted to a character
//ERROR BELOW  (error before "char") (error before '+' token)
            slot_char = char(slot_number+48+7);
        else  // this will be a number
            slot_char = char(slot_number+48);

//ERROR BELOW    (subscripted value is neither array nor pointer)
        FinishedArray[counter2] = slot_char;  // store the character back
into the original array to be passed to 4D
    }

}

}

    PA_SetVariableParameter( params, 3, FinishedArray, 1 );
    PA_ReturnString( params, returnValue );
}
Cliff - 07 Feb 2010 17:59 GMT
> I am having trouble as a C beginning trying to compile the code below
> using XCode.  I am new to C and have always programmed in pascal in
[quoted text clipped - 42 lines]
>  #
> --------------------------------------------------------------------------------
*/

//

> -------------------------------- schedule Plugin
> -------------------------------
[quoted text clipped - 66 lines]
>     PA_ReturnString( params, returnValue );
> }

John,

My C is real rusty but shouldn't type conversions be in their own parens?

I.E.  (NOT TESTED)

Day_Difficulty_AsciiValue =int(DayArray[counter2]);
        becomes
Day_Difficulty_AsciiValue =(int)(DayArray[counter2]);

Other than that, google the functions of atoi and itoa, to explictly do
the type conversions.

Cliff
John Mosby - 07 Feb 2010 21:55 GMT
Cliff,

Sorry to say that did not change the compiling errors. sigh....
Cliff - 08 Feb 2010 02:02 GMT
> Cliff,
>
> Sorry to say that did not change the compiling errors. sigh....

Using one of the previous poster's project preferences, the only
compilrer error I'm getting is the params variable type inb   void
s_Convert_Array(PA_PluginParameters params).

I'm thinking that there are additional header files that need to be included...

By the way,
OSX = v 10.6.2
xCode = v 3.2.1 (64 bit)

Cliff
GreyCloud - 07 Feb 2010 21:35 GMT
> I am having trouble as a C beginning trying to compile the code below
> using XCode.  I am new to C and have always programmed in pascal in
[quoted text clipped - 79 lines]
> //ERROR BELOW (error before "int")
>         Day_Difficulty_AsciiValue = (int)(DayArray[counter2]);  // function to

In C for an int cast it should look like (int).

> convert a char in array to ascii value
>         if (Day_Difficulty_AsciiValue>=65) // is character a letter
[quoted text clipped - 15 lines]
> //ERROR BELOW  (error before "char") (error before '+' token)
>             slot_char = (char)(slot_number+48+7);

Always put a cast inside parentheses.
>         else  // this will be a number
>             slot_char = (char)(slot_number+48);

I've put in the required parens.

> //ERROR BELOW    (subscripted value is neither array nor pointer)
>         FinishedArray[counter2] = slot_char;  // store the character back

I'll need the actual line definition of PA_Variable to figure that one out.

> into the original array to be passed to 4D
>     }
[quoted text clipped - 6 lines]
>     PA_ReturnString( params, returnValue );
> }
John Mosby - 08 Feb 2010 02:40 GMT
Is there a way to capture the ascii values of these printf statments?

char mychar = 'A';

printf("char: %c\n", mychar); // Prints the character 'A'
printf("ASCII: %d\n", mychar); // Prints the number 65

If I could capture the value 97 and the recovert it back to an 'A',
that would go a long way to solving my problem.
GreyCloud - 08 Feb 2010 02:52 GMT
> Is there a way to capture the ascii values of these printf statments?
>
[quoted text clipped - 5 lines]
> If I could capture the value 97 and the recovert it back to an 'A',
> that would go a long way to solving my problem.

Just give the numeric variable a (char) cast and see how it turns out
for you in a printf statement.
Of course if you want to make it an uppercase 'A' there are two
approaches to it.  1) use the toupper function that is in the string
lib.  2) subtract 32 from 97 and then cast it as a char.
I'm sure there are other means as well.
But it would help if I knew what the PA_variable definition is.
Gilles Kohl - 08 Feb 2010 07:42 GMT
John,

>I am having trouble as a C beginning trying to compile the code below
>using XCode.  I am new to C and have always programmed in pascal in
[quoted text clipped - 8 lines]
>error: parse error before '+' token
>error: subscripted value is neither array nor pointer

I agree with what others posted that those are probably syntax errors
related to casts. But I think we could help you better if you told us
what you want to accomplish. What should s_Convert_Array actually do?

A few comments and questions:

- With the assumption that you're trying to somehow convert the
character-based '0'-'9',  'A'-'F' priority logic of 4D to some nicer
value-based encoding, why the two nested while loops? "counter" is
apparently not used (e.g. as an index or parameter) inside the loop
body, except to control the loop?

- Note that C is much more "dangerous" than PASCAL. If your coding
habit is of the style "try to get it working incrementally, fix things
if and when the code crashes", think again (and preferrably, before
starting to code :-)

There are NO safeguards, array boundary checks etc. built into the C
runtime. Stuff will simply be overwritten, with mysterious errors
surfacing at entirely different spots in space and time than where the
actual problem is. The syntax errors are just the beginning - the more
interesting ones are still to follow, you've been warned :-)

- caution with the sizeof(DayArray ). DayArray is of type PA_Variable,
and this: http://www.4d.com/docs/CMU/CMU84858.HTM tells me that that
is a struct containing a union - not suited to determine how many
characters are in that array.

4D seems to have invented their own type system here, and you'll have
to check their documentation on how to access it - as you're already
doing with calls like GetVariableParameter. Check if there's something
like "PA_GetArraySize" or similar.

- To convert a character of type '0'-'9',  'A'-'F' to a number value
ranging from 0 to 15, there's a few approaches you can take.

// Warning: Code entered from the top of my head, untested

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

int PriorityIndexFromCharacter(char priority)
{
  static char *digitTable = "0123456789ABCDEF";

  char *location = strchr(digitTable, toupper(priority));

  if(location == NULL) {
      return -1; // something's wrong - character not in table
  }
  return  (int)(location - digitTable);
}

Another alternative, if they are not going to extend their logic
beyond "F": handle it as a single digit hex char:

#include <stdlib.h>

int PriorityIndexFromCharacter(char priority)
{
  char buffer[2]
  int result;
  char *end;

  buffer[0] = priority;
  buffer[1] = '\0'; // terminate correctly

  result = (int)strtol(buffer, &end, 16);

  if(*end != '\0') {
      return -1; // something's wrong - conversion failed
  }

  return result;
}
     
  Regards,
  Gilles.

>The code follows:
>
[quoted text clipped - 100 lines]
>    PA_ReturnString( params, returnValue );
>}
GreyCloud - 08 Feb 2010 18:44 GMT
> John,
>
[quoted text clipped - 87 lines]
> }
>      

<snip for brevity>
I couldn't agree more.  Well said!
John Mosby - 10 Feb 2010 01:58 GMT
First of all, thanks for your help.  Maybe this will help clear some
things up.

>>>> What should s_Convert_Array actually do?

below is a representation of an array recieved from 4D

element 1 = "774774322333999666644333322555885000000666374446666311"
element 2 = "IIIIIIIIIIII000000000000000000000000000000000000000000"
element 3 = "AAAA55333633352444B99420000HHHHHHH00333463333114555855"
element 4 = "33333311111144433000PPPP000000000000000333330033888555"
element 5 = "5557742220006666631110000000000000000000KKKKKKKK000000"
element 6 = "777774533774111111111133222422222000000666693335555544"
element 7 = "666330666552444441322222000000000000333333666661777430"
element 8 = "333552666685522200000000000555552000000555584777555885"
element 9 = "333330555550111143522333444552222000000333111111444441"
element 10 = "555552333441333220000000666330000000000477774111222222"
element 11 = "222221544441666330333330000333330000000222222111666663"
element 12 = "333330111111433330333441111111000000000555330000777774"

Using the difficulty as 9 the following array is returned by the 4D
plugin (9 is subtracted from the ascii value of each position in all
12 elements)

element 1 = "000000000000000000000000000000000000000000000000000000"
element 2 = "999999999999000000000000000000000000000000000000000000"
element 3 = "111100000000000000200000000888888800000000000000000000"
element 4 = "00000000000000000000GGGG000000000000000000000000000000"
element 5 = "0000000000000000000000000000000000000000BBBBBBBB000000"
element 6 = "000000000000000000000000000000000000000000000000000000"
element 7 = "000000000000000000000000000000000000000000000000000000"
element 8 = "000000000000000000000000000000000000000000000000000000"
element 9 = "000000000000000000000000000000000000000000000000000000"
element 10 = "000000000000000000000000000000000000000000000000000000"
element 11 = "000000000000000000000000000000000000000000000000000000"
element 12 = "000000000000000000000000000000000000000000000000000000"

using the same array at the beginning and a difficulty of 2 the
following array is returned:

element 1 = "552552100111777444422111100333663000000444152224444100"
element 2 = "GGGGGGGGGGGG000000000000000000000000000000000000000000"
element 3 = "888833111411130222977200000FFFFFFF00111241111002333633"
element 4 = "11111100000022211000NNNN000000000000000111110011666333"
element 5 = "3335520000004444410000000000000000000000IIIIIIII000000"
element 6 = "555552311552000000000011000200000000000444471113333322"
element 7 = "444110444330222220100000000000000000111111444440555210"
element 8 = "111330444463300000000000000333330000000333362555333663"
element 9 = "111110333330000021300111222330000000000111000000222220"
element 10 = "333330111220111000000000444110000000000255552000000000"
element 11 = "000000322220444110111110000111110000000000000000444441"
element 12 = "111110000000211110111220000000000000000333110000555552"

>>>>>>why the two nested while loops?
As an inexperienced C "hacker" I was not able to get FOR loops to work
so I went with the WHILE loops and my own counter.  I would rather use
FOR loops.

>>>>>you've been warned :-)
Yes, I know.  I'm just trying to hack my way through this.  I'm
working on it.

> - caution with the sizeof(DayArray ). DayArray is of type PA_Variable,
> and this:http://www.4d.com/docs/CMU/CMU84858.HTMtells me that that
> is a struct containing a union - not suited to determine how many
> characters are in that array.

Should I send the array length as another parameter?  It will always
be 54 characters long with varying numbers of elements.  Can't I just
make that assumption in the C code?

> 4D seems to have invented their own type system here, and you'll have
> to check their documentation on how to access it - as you're already
[quoted text clipped - 3 lines]
> - To convert a character of type '0'-'9',  'A'-'F' to a number value
> ranging from 0 to 15, there's a few approaches you can take.

I don't want to use hex values.  I would like to stick to the ascii
values because I may be using other letters of the alphabet.  That
gives me 36 different values (26 alpha and 10 numbers) instead of just
16.
John Mosby - 10 Feb 2010 04:05 GMT
Below is new code that actually compiles in XCode with a warning on
one line near the bottom.  This is when the return array is assigned.
I don't have any idea what the warning means or how to correct the
problem.

/*
--------------------------------------------------------------------------------
#
#    4DPlugin.c
#    source generated by 4D Plugin Wizard
#    Project : new Project
#    author : subaru
#    1/29/10
#
# This plugin should recieve two variable from the main 4D program.
#
# The first variable from 4D --------------
# One will be an array of length 54 composed of
# characters (0-9 and A-Z).  Each element represents a schedule day.
Each character in the element represents a
# 10 minute block of time in the schedule.  When the character is 0
(zero) there is nothing scheduled for that time.
# The difficulty of the the 10 minute time block increases as the
ascii value of the character that represents it
# increases in value from 0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F,..... etc.
#
# The second variable from 4D --------------
# This variable will be an integer value that represents the
difficulty of the new appointment.
# This value should be subtracted from the ascii value of the
character that represents each 10 minute
# time block.  The harder the new appointment the smaller the value
of the variable for the difficulty.
#
--------------------------------------------------------------------------------
*/

#include "4DPluginAPI.h"
#include "4DPlugin.h"

void PluginMain( long selector, PA_PluginParameters params )
{
    switch( selector )
    {
// --- schedule Plugin

        case 1 :
            s_Convert_Array( params );
            break;

    }
}

// -------------------------------- schedule Plugin
-------------------------------

void s_Convert_Array( PA_PluginParameters params )
{

    PA_Variable DayArray; //an array of characters of length 54 from 4d
    short Difficulty;  //an interger denoting difficulty of an
appointment
    PA_Variable FinishedArray;  // completed array returned to 4D
    char returnValue[256];

    DayArray = PA_GetVariableParameter( params, 1 );
    Difficulty = PA_GetShortParameter( params, 2 );

    // --- write the code of s_Convert_Array here...

{
int counter = 0;
int array_size = sizeof(DayArray);
int Day_Difficulty_AsciiValue; //used to hold one character
int slot_number;
char slot_char;

while (counter < array_size)  //array_size should be the number of
elements of array DayArray
{
    counter++;

    int counter2 = 0;
    while (counter2 < 55)  //stepping through each character of DayArray
    {
        counter2++;

        Day_Difficulty_AsciiValue =
(int)DayArray.uValue.fArray.fData[counter2];   // function to convert
a char in array to ascii value
        if (Day_Difficulty_AsciiValue>=65) // is character a letter
            slot_number = Day_Difficulty_AsciiValue-7-48;
        else //character is a number
            slot_number = Day_Difficulty_AsciiValue-48;

        slot_number = slot_number - Day_Difficulty_AsciiValue;

        if(slot_number<0)
            slot_number = 0;

// convert the number to the characters 0-1,A-Z
// 48 is the number of ascii values before the numbers begin
// 7 is the numbere of unused ascii values between the numbers and
capital letters

        if(slot_number>=10) //number will be converted to a character
            slot_char = (char)(slot_number+48+7);
        else  // this will be a number
            slot_char = (char)(slot_number+48);

        FinishedArray.uValue.fArray.fData[counter2] = slot_char;  // store
the character back into the original array to be passed to 4D

//WARNING WHEN COMPILING... THE ABOVE LINE HAS THE WARNING...
// warning: assignment makes pointer from integer without a cast

    }

}

}

    PA_SetVariableParameter( params, 3, FinishedArray, 1 );
    PA_ReturnString( params, returnValue );
}
Gilles Kohl - 15 Feb 2010 07:28 GMT
>First of all, thanks for your help.  Maybe this will help clear some
>things up.
>
>>>>> What should s_Convert_Array actually do?
>
>below is a representation of an array recieved from 4D

An example isn't of much use here - what is the _intention_ of the
routine? What is the purpose you want to achieve - why do you need a
plug-in?

As far as I can tell you're getting an array of time slot priorities
and a "difficulty", and somehow subtract the latter from the former, I
find it hard to understand why the 4D programmers left this as an
exercise for the user?

>element 1 = "774774322333999666644333322555885000000666374446666311"
>element 2 = "IIIIIIIIIIII000000000000000000000000000000000000000000"
[quoted text clipped - 12 lines]
>plugin (9 is subtracted from the ascii value of each position in all
>12 elements)

IIRC, if the subtraction would go below '0', the result is replaced by
'0'? How high can "difficulty" go? Is it an actual value, or is it
following this same strange "digits, then letters" encoding scheme?

[snip]

>>>>>>>why the two nested while loops?
>As an inexperienced C "hacker" I was not able to get FOR loops to work
>so I went with the WHILE loops and my own counter.  I would rather use
>FOR loops.

Example:

  int dayCount = PA_GetArraySize(DayArray);
  int day;
  PA_Variable newDayArray = PA_CreateArray(dayCount);

 
  // loop over all days
  for(day = 0; day < dayCount; day++) {
     // get current element
     PA_Variable currentDay =
         PA_GetArrayElementAtIndex(DayArray, day);

    int characterCount =  PA_GetArraySize(currentElement);      

    PA_Variable newDay = PA_CreateArray(characterCount);
 
    // loop over characters
    for(i = 0; i < characterCount; i++) {
       char prio = PA_GetArrayElementAtIndex(currentDay, i);
       prio = ComputeNewPrio(prio, difficulty);
       PA_SetArrayElementAtIndex(newDay, i, prio);
    }
    SetArrayElementAtIndex(newDayArray, day, newDay);
  }  

Most of the PA_xxx routines are of my invention - they illustrate the
way you'll probably have to handle interop with the 4D types. Check
their documentation. ComputeNewPrio is your logic to substract a
difficulty value from a character.

>>>>>>you've been warned :-)
>Yes, I know.  I'm just trying to hack my way through this.  I'm
[quoted text clipped - 8 lines]
>be 54 characters long with varying numbers of elements.  Can't I just
>make that assumption in the C code?

That depends on how "cast in stone" that constant is. Could it change
if the user configured another work day, e.g. from 8am to 8pm?

>        FinishedArray.uValue.fArray.fData[counter2] = slot_char;  // store
> the character back into the original array to be passed to 4D
> //WARNING WHEN COMPILING... THE ABOVE LINE HAS THE WARNING...
> // warning: assignment makes pointer from integer without a cast

AFAICT without knowing the 4D types, you're mixing levels of
indirection here - you have two-dimensional data (elements or lines or
strings, whatever you want to call them, and characters, difficulties
or priorities. You even have two nested loops to iterate over the
characters in the elements.

But you never actually use your first "counter" except to initialize
and increment it! Which means that you're not really accessing
characters at all - what you think is a character is probably a
pointer to the start of the array element.

Also, note that you're not handling 54, but 55 elements in your outer
loop.

I'm afraid you won't be able to "cheat" this. You'll need to learn the
basics of C, read the 4D interop docs, and also spend more time
_thinking_ about your problem before you start typing - the above two
problems have nothing to do with being unfamiliar with C.

  Regards,
  Gilles.
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2010 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.