Frequently Asked Questions on General Programming
  1. How to convert integer into octal, hexadecimal or binary format?
  2. Trigraphs such as '??(' are annoying in pattern matching, is it possible to disable trigraphs in Ch?
  3. How to add a directory path in Ch shell?
  4. How to run multiple C statements in one line under a Ch shell
  5. How to edit and execute a Ch program and display its output within a Graphical User Interface(GUI) IDE?
  6. I type a Ch program in Google Docs first. I get syntax errors on the quotation marks when I copy and paste the program from Google Docs into ChIDE. How can I fix this?
  7. How to get the printf() to work for '\r' in ChIDE?
  8. How to close the Debug Console Window in ChIDE?
  9. Why can my program be compiled by a C compiler, but cannot run in Ch?
  10. Why can my program be compiled and run by a C++ compiler, but cannot run in Ch?
  11. How do I run a program with multiple files?
  12. How environmental variables are handled in Ch?
  13. Why does my Ch program not run in other Unix shells?
  14. How can I add my Ch programs to the Ch language environment so that others in the system can access it?
  15. What is a generic function?
  16. How should I implement passing the '...' to the printf function?
  17. What is the built-in string type (string_t) with automatic memory handling?
  18. How to concatenate two or more strings into one?
  19. How to access variables or functions in a Ch program
  20. How to see variables and types in ChIDE or Ch shell?
  21. How to define a C/Ch/C++ function from Ch shell command prompt?
  22. How to load a C/Ch/C++ script program and call its functions from Ch shell command prompt interactively?
  23. How to call functions in a C/C++ binary library from a Ch command shell prompt interactively?
  24. How to call one user-defined function or multiple user-defined functions from Ch?
  25. How to unload defined functions and variables from ch shell or programs?
  26. How to handle general function overloading and polymorphism in Ch?
  27. How to handle C++ class constructor overloading and polymorphism in Ch?
  28. How to handle C++ functions with default parameter values in Ch?
  29. How to handle C++ class inheritance in Ch?
  30. How to keep the same color for different curves in a Ch plot?
  31. For gnuplot axis label, is there any way to show in log scale, such as 10^0, 10^1, with superscript?
  32. How to display real-time data in graphics using SIGL or Embedded Ch Professional?
  33. How to convert my IDE non-English menu into English menu?
  34. How to call a graphical plotting functions with float type instead of double type?
  35. string_t type doesn't work in sprintf?

Q: How to convert integer into octal, hexadecimal or binary format?

You can use printf to do it from ch shell or programming script.

octal hexadecimal binary
printf("%o", 15); printf("%x", 15); printf("%b", 15);

From the Ch shell, you can also quickly run the shift command to manipulate binary.

> 0b00011101<<1
58
> printf("0b%8b", 58)
0b00111010
Q: Trigraphs such as '??(' are annoying in pattern matching, is it possible to disable trigraphs in Ch?

To disable trigraphs in Ch, add

_ignoretrigraph = 1; in startup file _chrc or .chrc in the user's home directory or add #pragma exec _ignoretrigraph = 1 inside a script to ignore trigraphs.

Q: How to add a path in Ch shell or Ch script?

You can modify the file ~/.chrc in unix or ~/_chrc in your home directory to update the directory path. If you don't have such a file, run "ch -d" from ch shell to create one. You should see the samples in the configuration file to follow.

You can add the following command to the configuration file or run the following command from ch shell.

_path = stradd(_path, "C:/add/command/path/;");

To add a directory path without changing configuration file chrc, you can use the following code in ch program file

#pragma _path "/new/directory1;/new/directory2/;" See chapter 5 in Ch User's Guide for more detailed information

Q: How to run multiple C statements in one line under a Ch shell

Multiple single statements in one line in Ch shell won't work directly. It is not recommended to run multiple C statements in one line or multiple lines. It is better to save into a file to run.

There are two ways to run multiple statement Ch shell. You can add { } to form a compound statement with multiple single statements as shown below.

> {int x=0;while(x<10){x++;printf(x);}} Alternatively, type in multiple single statements in multiple lines, one at a time. > int x=0 > while(x<10){x++;printf(x);} Or enter multiple lines by continuation line ending with the character '\' as shown below. > int x=0 > while(x<10){x++; \ > printf(x);} or > int i > for (i=0;i<10;i++) \ > {printf("%d",i);}

Q: How to edit and execute a Ch program and display its output within a Graphical User Interface(GUI) IDE?

SoftIntegration partners have provided Integrated Development Environment (IDE) for Ch. A Ch IDE allows you to edit and execute C/Ch/C++ programs with syntax highlighting, and display the output within the same Graphical User Interface.

Please check our third party solutions for Ch IDE.

I type a Ch program in Google Docs first. I get syntax errors on the quotation marks when I copy and paste the program from Google Docs into ChIDE. How can I fix this?

Google Docs uses a different symbol for quotation marks that ChIDE does not recognize. Google offers a free plugin called Text that can be downloaded and used to write Ch programs in. If you write a program using Text and save it as a .ch file, you will not have syntax errors when opening the program in ChIDE.

Q:How to get the printf() to work for '\r' in ChIDE?

The character '\r' in printf() returns to the beginning of the line without going to a new line. Programs using the character '\r' work fine in a Ch command shell. However, in ChIDE, it works only if you run the code from "Start" button in debug mode instead of "Run" button.

Q: How to close the Debug Console Window in ChIDE?

You can press F11 or click menu button View , then click to uncheck the button for Debug Console Windows.

Q: Why can my program be compiled by a C compiler, but cannot run in Ch?

Although Ch is designed to be a superset of C, like C++, there are some subtle differences between Ch and C. Therefore, some C programs straight out of a box may need to be polished to run in Ch. You should know the differences between Ch and C, before run a C program in Ch.

The most common problems for running C programs straight out of a box in the Ch language environment at this point of implementation of Ch are as follows:

  1. Ch supports many new features in the latest C99 standard. C99 introduced many new functions and macros. Existing C code may have used the same identifier with different types. For example, function fmin() is introduced with prototype double fmin(double x, double y); If identifier fmin has been used for other purpose, the existing C code will not work in Ch.

    Solution: Modify your C code to conform to the new C99 standard.

    Rationale: Ch supports international standards.

  2. Like C++, the obsolete old-style function definition with default return type of int, for example, funct (int a, float b) { ...} is not supported in Ch.

    Solution: Use new function prototype. The above example should be changed to

    int funct (int a, float b) { ...} Rationale: It is well-known that the obsolete old-style function definition is problematic. It is also prohibited in C++.

  3. The supported struct initialization. Ch only supports the following struct initialization.
    typedef struct StructName {
        int myvalue;
        double mydouble;
        } my_struct; 
    
    my_struct a = { 23, 5.6};
    
    Ch doesn't support the following struct initialization.
    typedef struct StructName {
        int myvalue;
        double mydouble;
        } my_struct;
    
    my_struct a = { .myvalue=23, .mydouble=5.6};
    
  4. There are more keywords in Ch than in C. Check to see if a particular identifier, say public and fmin, is a keyword, function, or environmental variables or not by typing
           which -a public fmin
    
    in the Ch language environment.

    Rationale: To make Ch a better C and for shell programming.

  5. If the above notes still cannot solve your problem, your C code may have a hidden bug such as a memory problem. Ch often detects bugs that are passed through a C compiler without warning.

    Solution: Fix your C code so that it will work in both C and Ch.

Q: Why can my program be compiled and run by a C++ compiler, but cannot run in Ch?

C++ class initialization such as

     myclass obj(i); 
is not valid in Ch. It can be replaced by
     myclass obj = myclass(i); 
which is valid in both C++ and Ch. More examples can be found below:
myclass ob1 = myclass(i);   // ok in  both C++ and Ch
myclass ob2 = myclass(2);   // ok in  both C++ and Ch
myclass ob3(i);             // ok in C++, bad in Ch
myclass ob4(2);             // ok in C++, bad in Ch

Q: How do I run a program with multiple files?

There are many ways to run a program with multiple files. Two of them are listed below. Other methods, including special handling of static variables, are described in Ch User's Guide.

  1. A program consisting of multiple files can be run by adding import and importf following the preprocessor directive #pragma. The changes won't affect your C code for compiling.

    Unlike included header files which search the directory specified in the system variable _ipath, the directories specified in system variables _path, and _fpath, are searched for the program following import and importf, respectively.

    For example, assume command command consists of four separate files command.c, module1.c, module2.c, module3.c, then program command.c can be written as follows.

    /* Program command.c */ #include <stdio.h> int main() { int i =90; printf("main() program \n"); /* ... main program goes here */ } #pragma importf "module1.c" /* search module1.c in current directory first, then directories specified in _fpath */ #pragma import "module2.c" /* search module2.c in current directory first, then directories specified in _path */ #pragma importf <module3.c> /* search module3.c in directories specified in _fpath only */ Static variables in files module1.c, module2.c, and module3.c have file scope. Command file command.c shall have read/execute permission, whereas files module1.c, module2.c, module3.c shall have read permission. Note the difference between import and importf in this example. File module2.c is searched in the current working directory first, then in the directories specified in _path, not in _fpath. The system variables _path, _fpath, and _ipath can be modified in startup file .chrc in Unix or _chrc in Windows in the user's home directory. This startup file can be copied from CHHOME/config/ directory by executing command
        ch -d
    
    For more information about using _ipath and _fpath in pragma, please check section 5.9 Pragma Directives and Chapter 22 Library, Toolkit, and Package in Ch User's Guide available at CHHOME/docs/chguide.pdf

  2. Alternatively, you can run a program with multiple files without modification of the original source code.
    For example, if you have two files called chmain.c and chfun.c, the content for chmain.c is listed below.
    #include<stdio.h> void chfun(int); int main(int argc, char *argv[]) { int i; printf("argc = %d\n", argc); for ( i=0; i < argc; i++) { printf("argv[%d] = %s\n", i, argv[i]); } chfun(argc); }
    The content for the file chfun.c is listed below:
    void chfun(int i) { printf("i in chfun() = %d\n", i); } You can create a Ch program multiple_file.ch with the following content: #!/bin/ch /* multiple_file.ch */ #pragma import "chmain.c" #pragma import "chfun.c" File multipe_file.ch shall have the read/execute permission, and chmain.c and chfun.c have the read permission. You can run the program by the following command multiple_file.ch or multiple_file.ch arg1 arg2 For more information, please check section 5.9 Pragma Directives and Chapter 22 Library, Toolkit, and Package in Ch User's Guide available at CHHOME/docs/chguide.pdf
Q: How environmental variables are handled in Ch?

The environmenal variables in Ch are similar to the environmental variables in Unix shell such as bash and csh, and MS-DOS shell.

There are four functions in Ch that can be used to handle environental varaibles. Function putenv() can add an environmental varialble to the system. Given an environmental variable, function getenv() can get its corresponding value. Function remenv() can remove an environmental variable. Function isenv() can test if a symbol is an environmental variable. The interactive command execution below demonstrates their application.

> putenv("ENVVAR=value") > getenv("ENVVAR") value > isenv("ENVVAR") 1 > remenv("ENVVAR") > isenv("ENVVAR") 0 Both Ch programs below can print out all enviromental variables and their corresponding values. /* program 1 */ #include <stdio.h> int main(int argc, char *argcv[], char **environ) { int i; for(i=0; environ[i] != NULL; i++) { printf("%s\n", environ[i]); } } /* program 2 */ #include <stdio.h> #include <stdlib.h> int main() { int i; for(i=0; environ[i] != NULL; i++) { printf("%s\n", environ[i]); } } In Unix, a system command env can also be used to display all enviromental variables.

Q: Why does my Ch program not run in other Unix shells?

At this point, other Unix shells such as Bourne-shell and C-shell do not recognize Ch program unless the following statement is included as the first line of the Ch program

#!/bin/ch or #!/bin/ch [options] The above Ch shell identification line is not needed if you run a Ch or C program within the Ch shell. You may also modify the source code of other shells so that they can recognize C program and pass it to the Ch shell. Then, C programs can be run without any modification and compilation from other shells.

NOTE: The character # shall be the first character of the file in order to run under other shells. No blank space or tab is permitted at the beginning of the file.

Q: How can I add my Ch programs to the Ch language environment so that others in the system can access it?

The Ch language environment is an open system. There is a variety of ways to integrate your programs into the Ch language environment. If you put your program in any one of the directories in string _path specified by the system level startup file CHHOME/config/chrc, the program can be executed by others in the system. If your programs are function files, they shall be placed in a directory specified by string _fpath in file CHHOME/config/chrc. Likewise, files to be included by the preprocessor directive,

#include <your_file.h>
they shall be placed in a directory speficied by string _ipath in file CHHOME/config/chrc.

Q: What is a generic function?

A generic function is a built-in system function. Most generic functions are polymorphic for math. For example, x in sin(x) can be a type of int, float, double, complex, array double(computational array). They are also available in Ch shell conveniently.

Below is a list of all generic functions in Ch.
abs access acos acosh alias asin asinh atan atan2 atanh atexit ceil clock conj cos cosh dlerror dlopen dlrunfun dlsym exp elementtype fgets floor fmod fprintf fread free frexp fscanf getenv gets imag ioctl ldexp log log10 max memcpy memmove memset min modf open polar pow printf read real recv scanf setrlimit shape sin sinh sprintf sqrt sscanf stradd strcat strchr strcmp strcoll strcpy strerror streval strlen strncat strncpy strparse strtod strtok strtol strtoul strxfrm tan tanh transpose umask vprintf vfprintf vsprintf

Q: How should I implement passing the '...' to the printf function?

You can use define.

   #define display(...) printf(__VAR_ARGS__)
Q: What is the built-in string type (string_t) with automatic memory handling?

string_t is the built-in string type in Ch, and it can be used the same way as char* or char[]. The memory for the variable will be allocated and deallocated automatically. It will be hard to corrupt other parts of memory and will prevent from buffer overflow effectively.

Here is an example.

#!/bin/ch #include <stdio.h> int main() { string_t bstr="built-in string"; printf("the content in bstr: %s \n", bstr); strcpy(bstr, "This is the new string with more bytes than original bstr"); printf("new content in bstr: %s \n", bstr); }

Q: How to concatenate two or more strings into one?

stradd() function is introduced in Ch for the convenience of concatenating two or more strings into one. stradd() allows variable argument of strings.

For example, if you run the code below, you will get the result "Hello world" and "Hello world from SoftIntegration!".

string_t result; char a[]="Hello "; char *b="world "; char c[6]="from "; string_t d="SoftIntegration!"; result = stradd(a, b); printf("%s \n", result); result = stradd(a, b, c, d); printf("%s \n", result);

Q: How to access variables or functions in a Ch program from Ch shell command line?

In Ch shell, You can access variables or functions in a Ch file if they are global variables or functions. For example, if you have a file called test.ch, You can access variable var in Ch shell after running the "test.ch". The following example is an example for accessing function in a Ch file from Ch shell.

> cat test.ch /* this is the file test.ch */ #include <stdio.h> int var = 5; var += 1; // or any other statements
in Ch Shell,
> . test.ch > var 6 >

Q: How to see variables and types in ChIDE or Ch shell?

In ChIDE, you can use debug mode and then check variable type and value from the the menu button "Debug".

In Ch shell, you can use command "showvar", "remvar". "remvar" can remove the declaration of variable.

> int i = 90 > showvar i 90 > remvar i

Q: How to define a C/Ch/C++ function from Ch shell command prompt?

Here is an example how you can do it.

C:/Users> double add(double input) { return input+4;} C:/Users> add(5) 9.0000 C:/Users> If you want to define a function using multiple lines from command line, here is another example: C:/Users> double multiple(double input) \ C:/Users> {return input*4; } C:/Users> multiple (2) 8.0000 C:/Users> If you want to re-define, or type something wrong during the definition, you need to remove the function using remvar, here is the example: C:/Users> remvar multiple

Q: How to load a C/Ch/C++ script program and call its functions from Ch shell command prompt interactively?

Here is an example how it can be done in a Ch shell.

> cat prog.cpp #include <iostream> using namespace std; class tag { private: int m_i; public: tag(); void memfunc(); }; int func(int i) { return 2*i; } tag::tag() { m_i=10; } int tag::memfunc(int i) { cout << m_i+i << endl; return m_i+i+1; } /* the following code can be omitted if you just want to load above functions in command line mode */ int main() { class tag c1; printf("func(5) = %d\n", func(5)); printf("c1.memfunc(5) = %d\n", c1.memfunc(5)); } > . prog.cpp func(5) = 10 15 c1.memfunc(5) = 16 > func(10) 20 > class tag c > c.memfunc(10) 20 21 > In the above example, cat is used to display a C++ program prog.cpp. The command ". prog.cpp" loads and executes program prog.cpp in the current shell with output of. func(5) = 10 15 c1.memfunc(5) = 16 The use of "." to invoke a program in the current Ch shell is similar to that of sh, bash and ksh shells. Command func(10) in the command prompt calls the function func() in the program loaded in the current shell. Declaration statement "class tag c" instantiates an object c of class tag. When the member function tag::memfunc() is invoked interactively by function call c.memfunc(5), the result of value 15 will be displayed and the value 16 will be returned.

Q: How to call functions in a C/C++ binary library from a Ch command shell prompt interactively?

We have a demo example for doing it in Windows and Unix. Please click the link to download it. This demo example is also available at CHHOME/toolkit/demos/SDK/chapters/runc2chf_dll/chf/ directory.

Q: How to call one user-defined function or multiple user-defined functions from Ch?

Function files can be created to make user-defined functions available in Ch shell. The name of a function file shall be the same as the function name with file extension .chf. This solution requires one function file for one function. For example, if you want to have a function named as myfind(), you can create a myfind.chf file with the following content.

void myfind(string_t name) { find . -name $name -print } myfind.chf must be in one of directories specified in the system variable _fpath. If you put myfind.chf into a directory such as /home/myhome/lib or C:/lib, you should add the following statement in startup file .chrc in Unix or _chrc in Windows. _fpath=stradd(_fpath, "/home/myhome/lib"); or _fpath=stradd(_fpath, "c:/lib"); Once you have done the above setup, you can invoke function call myfind("my_file_name") interactively in a Ch shell or from a Ch program. More examples about function file can be found here.

To preload a large number of user-defined functions, you can put all function file names in a new file, say 'myfuncs.chf' with the contents as follows.

/* File Name: myfuncs.chf */ #include <myheader.h> #pragma importf <myfunc1.chf> #pragma importf <myfunc2.chf> #pragma importf <myfunc3.chf> ...

To load this file in a program, you can put the statement

#pragma importf <myfuncs.chf> in a header file or program.

To pre-load your functions in a command shell, you may place

#pragma _fpath "/add/the/path/where/myfuncs.chf/located" #pragma importf <myfuncs.chf> in your startup file .chrc for Unix and _chrc for Windows in your home directory.

Q: How to unload defined functions and variables from Ch shell or programs?

You need to use the command remvar to remove the defined functions or variables.

> int var = 90 > remvar var > float var = 5.0 // now you can redefine 'var' If a defined function such as blah() is called at the command prompt, you need to remove the definition from the ch command shell with remvar, before modifying the function definition. Otherwise, the modified function definition won't work at the current command prompt.

Here is an example as demonstrated below.

> blah() > vi blah.chf or blah.ch // editing function blah() definition > blah() // the old blah() function inside memory will still be used > remvar blah // remove blah() definition from the memory > blah() // new blah() will be used. If you want to remove a variable in a program, int var = 90; #pragma remvar(var) float var = 5.0; If you want to remove a keyword in a program, #pragma remkey (strcpy)

Q: How to handle general function overloading and polymorphism in Ch?

Ch supports function overloading or polymorphism. The syntax of function overloading in Ch is different from that in C++. But, sementically, they are more or less the same. Ch let users overload a function by themselves.

In C, a function must have at least one named parameter if you have variable-length argument list. Ch supports this feature.

Moreover, Ch supports variable length argument without specifying the first named argument in the form of "type funcname(...)". Thus the number and types of arguments are flexible and can be overloading with the same function name, except that the function return value type has to be fixed and cannot be overloaded. However, you can put the returned value of different types into a function argument if it is a concern. The number of arguments, data type of each argument, array information for array argument, etc. are available to users for function overloading.

/* FileName: multiply.ch This example demonstrates how Ch handles C++ function overloading int multiply (int arg1, int arg2); int multiply (int arg1, int arg2, int arg3); int multiply (int arg1, int arg2) { return arg2 * arg2; } int multiply (int arg1, int arg2, int arg3) { int result; result = multiply(arg1, arg2); return multiply(result, arg3); } */ #include <stdarg.h> int multiply (...); int main() { printf (" multiply(2,3) is %d \n", multiply(2,3)); printf (" multiply(2,3,4) is %d \n", multiply(2,3,4)); return 0; } int multiply (...) { va_list ap; int count; int arg1, arg2, arg3, result; va_start(ap, VA_NOARG); count = va_count(ap); arg1 = va_arg(ap, int); arg2 = va_arg(ap, int); if (count == 2) { return (arg1 * arg2); } else if(count == 3) { arg3 = va_arg(ap, int); result = multiply(arg1, arg2); return multiply(result, arg3); } else { printf("Error: invalid number of arguments for %s()\n", __func__); return -1; } }

Q: How to handle C++ class constructor overloading and polymorphism in Ch?

The example above demonstrates how to overload functions in Ch. For handling C++ constructors with polymorphism, please check Ch User's Guide sections about Variable Number Arguments in Functions and Polymorphism for member functions and contructors.

Q: How to handle C++ functions with default parameter values in Ch?

The default parameter value syntax is implemented using function overloading in C++. Ch doesn't support such a function definition in syntax directly. Ch supports it indrectly and users can enjoy the same benefit of such a C++ feature.

In Ch, you can use int f(int a, ...) to handle it. All information in function arguments can be obtained using va_*() functions. (Note: Ch also supports function such as int f(...)).

For example, the following C++ function

int msgbox(char* msg, int used=100);

can be handled in Ch as:

#include <stdarg.h> int msgbox(char* msg, ...); int msgbox(char* msg, ...) { int used = 100; va_list ap; va_start(ap, msg); if(va_count(ap) ==1) used = va_arg(ap, int); /* function defintion goes here below */ ... }

Q: How to handle C++ inheritance in Ch?

Ch itself doesn't support inheritance. However, you can modify C++ to work in both Ch and C++. For example, for the C++ code below:

class base { public: int get_base_i(); void set_base_i(int i); virtual void mybase(); private: int base_i; } class super:base{ public: int super(); virtual void mybase(); } You can create an equivalent Ch class called super listed below. class super{ public: int super(); int get_base_i(); void set_base_i(int i); void mybase(); } This Ch class can also interface the binary C++ class super using Ch SDK. Then you can access all binary member functions in C++ super class from Ch class.

Q: How to keep the same color for different curves in a Ch plot?

Set the line type of the third argument of CPlot::plotType() with the same value for different curves so that the line type and color of different curves remain the same.

Q: For Ch Prof and SIGL plotting in axis label, is there any way to show in log scale, such as 10^0, 10^1, with superscript?

Yes, you can use the following functions:

plot.enhanceText();
plot.lable(PLOT_AXIS_X, "10^1");

Q: How to display real-time data in graphics using SIGL or Embedded Ch Professional?

Your C or C++ program may need two threads. One for incoming data, and other for plotting. When you have a set of data, one thread uses SIGL to plot and convert the data to be displayed inside your GUI. When you have new or updated data set, you use SIGL to replot and display the updated plot inside the same window of your GUI.

You can download the demo code at http://www.softintegration.com/products/sdk/embedch/realtimeplotexample/

For general plotting from GUI, you can find the examples from the link below.

    
http://www.softintegration.com/products/sdk/embedch/plotexample/

Q: How to convert my IDE non-English menu into English menu?

During the software installation, ChIDE will detect if the opertaing system is non-English and load up its local language menu. If you want to keep English Menu for ChIDE, you can remove the file CHHOME/chide/locale.properties. CHHOME is the directory where Ch was installed. By default, it is C:\Ch in Windows and /usr/local/ch in Unix.

Q: How to call a graphical plotting functions with float type instead of double type?

You may find that cast the floats to double in the function might not work. However, you may try to convert from float to double first before calling the function. Here is an example:


array float A[12][12];
array float b[12];
array float x[12] ; // the output result

array double A2[12][12];
array double b2[12];
array double x2[12] ;

A2 = A;
b2= b;
linsolve(x2, A2, b2);

x=x2; 
Q: string_t type doesn't work in sprintf?

For 64 bit, the internal sprintf handling is quite different and sprintf doesn't support the type string_t in Ch directly as the first argument, you may use the solution below.

  int tmp = 1456;
  char buf[1024];
  string_t str;

  str = "A long string for testing the sprintf function";
  sprintf(buf, "%d", tmp);
  str = buf;
  printf("str = %s\n", str);