Tom Gunn 1,164 Practically a Master Poster

You do need to do an fseek to that location, but not because C uses separate read and write pointers. The standard says that when switching between read and write mode on a stream, there needs to be a flush or seek between them. So you would read to the location you want to write, then do fseek(strm, 0, SEEK_CUR); to switch the mode without changing the file position.

And keep in mind that you will be overwriting whatever is there, not inserting.

Tom Gunn 1,164 Practically a Master Poster

Typically the two options for a case like this are a count argument and a sentinel argument:

#include <stdio.h>
#include <stdarg.h>

/* gets a count of arguments */
void TestCount(int x, int n, ...)
{
    va_list args;

    va_start(args, n);

    printf("%d: ", x);
    while (--n >= 0) printf("%-3d", va_arg(args, int));
    putchar('\n');

    va_end(args);
}

/* gets a sentinel as the last argument to mark the end */
void TestSentinel(int x, ...)
{
    va_list args;
    int value;

    va_start(args, x);
    printf("%d: ", x);
    while ((value = va_arg(args, int)) != -1) printf("%-3d", value);
    putchar('\n');

    va_end(args);
}

int main()
{
    TestCount(0, 3, 1, 2, 3);
    TestSentinel(1, 1, 2, 3, -1);

    return 0;
}
Tom Gunn 1,164 Practically a Master Poster

..or may be I am missing some option, in witch case, it should be a lot more visible than it is... I couldn't find it ;-)

I can go to the Delphi forum, then under the Related Forum Features box on the right there is a direct link to all Delphi snippets.

Tom Gunn 1,164 Practically a Master Poster

C++ has two kinds of strings. The strings inherited from C are char arrays with a terminating '\0' character. All of the rules for arrays apply, which means you can only return a pointer to the array somehow. But if the array is local to the function returning it, you are returning a bogus pointer. Not a good thing. ;)

The strings defined by C++ are class objects of the std::string type. They have copy semantics, so it is much easier to use them than the C type strings. I recommend that you use C++ strings until you start getting into the lower levels of C++ because C type strings are very easy to get wrong:

#include <iostream>
#include <string>

std::string Name()
{
    return "Tom";
}

int main()
{
    std::string name = Name();

    std::cout << "My name is " << name << '\n';
}
Tom Gunn 1,164 Practically a Master Poster

Some of the tokens are being stored with blank spaces proceeding them.

That sounds like you need to skip leading whitespace at the token level. When resetting start, instead of incrementing it, walk it over all whitespace. The following is a stream of consciousness. It is meant to spark your imagination, not to be an actual plugin for your code:

// start = (finish != string::npos) ? finish + 1 : string::npos;
if ((start = finish) != string::npos)
{
    while (start < str.length() && isspace(str[start])) ++start;
    if (start == str.length()) start = string::npos;
}
Tom Gunn 1,164 Practically a Master Poster

where is this function and how is it called ?

It is done by the C runtime. The same code that calls main() collects arguments from the command shell and parses them into an array of char pointers.

Tom Gunn 1,164 Practically a Master Poster

Try Tom Gunn's code out. Make sure it "works" for all possible test cases (i.e. change line 11 below for every possible test case you can think of and make sure the code "behaves".

It does not, as you proved. I did not consider adjacent punctuation in my haste to get my post out the door and ended up over engineering the whole thing. Since punctuation is always a single character in this case, the simpler solution for matching punctuation works better:

#include <iostream>
#include <string>
#include <vector>

std::vector<std::string> SplitOnPunct(std::string const& str,
                                      std::string const& punct)
{
    std::vector<std::string> vec;

    if (str.length() == 0) return vec;

    std::string::size_type pos, end;

    for (pos = 0; pos != std::string::npos; pos = end)
    {
        end = str.find_first_of(punct, pos);

        if (end == pos && ++end == str.size()) end = std::string::npos;

        vec.push_back(str.substr(pos, end - pos));
    }

    return vec;
}

int main()
{
    std::vector<std::string> vec = SplitOnPunct("dressed(with)", "+-*/<=!>{()};,");

    for (std::vector<std::string>::size_type a = 0; a < vec.size(); ++a)
    {
        std::cout << "vector " << a << ": " << vec.at(a) << '\n'; 
    }
}

I still do not guarantee 100% correctness because it is hard to find my own mistakes. ;) All of the basic test cases seem to work though.

AdRock commented: works a treat....exactly what i needed +1
Tom Gunn 1,164 Practically a Master Poster

Should I put delete in the constructor of that class

The destructor, yes. Or better yet, use a smart pointer like auto_ptr where you do not need to worry about deleting it at all.

Tom Gunn 1,164 Practically a Master Poster

There are three steps to inserting in an array:

  1. Find the position of the item being inserted.
  2. Make room for the new item by shifting all items from that position forward one spot to the right.
  3. Copy the new item into the position that was vacated.

Graphically it looks like this:

Step 1, inserting 5:

[0][1][2][3][4][6][7][8][][][]
                ^

Step 2:

[0][1][2][3][4][6][6][7][8][][]
                ^

Step 3:

[0][1][2][3][4][5][6][7][8][][]
                ^

See if you can roll that up into an algorithm.

Tom Gunn 1,164 Practically a Master Poster

So at what point I have to delete this pointer?

As long as you have a copy of the pointer that was returned by new , you can delete it. You said that the pointer is stored in another object, so that object's destructor would probably handle the deletion. Though that is not exactly the best design, IMO.

Tom Gunn 1,164 Practically a Master Poster

for windows getch and getchar can be used using the header file <conio.h>
In linux for the same you require <stdlib.h>

Not quite. getchar() is declared in <stdlib.h>, which is a standard header so every compiler will have it. getch() is typically declared in <conio.h>, but only on some Windows compilers. getch() is not available on Linux except when using the curses library.

ankur_ commented: perfect answers +1
Tom Gunn 1,164 Practically a Master Poster

Your search always starts from position 0, that is why tokens are being duplicated. You need to skip over the extracted tokens as you go. Something like this:

#include <iostream>
#include <string>
#include <vector>

int main()
{
    using namespace std;

    string const punct = "+-*/<=!>{()};,";

    string str = "dressed(with)";
    string::size_type pos = 0;
    vector<string> vec;

    while (pos != string::npos)
    {
        string::size_type end = str.find_first_of(punct, pos);

        if (end == pos) end = str.find_first_not_of(punct, pos);

        vec.push_back(str.substr(pos, end - pos));
        pos = end;
    }

    for (int a = 0; a < vec.size(); ++a)
    {
        cout << "vector " << a << ": " << vec.at(a) << '\n'; 
    }

    return 0;
}
VernonDozier commented: Nice snippet. +9
AdRock commented: thank you for your help +1
Tom Gunn 1,164 Practically a Master Poster

That class has a kind of strange way of implementing a failed search. In the constructor you pass a bogus object that will act as the sentinel value, and find() returns that object if it fails. So in your case you will compare mytree->find(joe) against bob , since you passed bob as the constructor argument.

Tom Gunn 1,164 Practically a Master Poster

I just cant seem to fathom the last part of each line is being completely ignored...

I know the answer to this problem because it is a problem I create myself on a regular basis. :) On the last token, finish will be string::npos . After the last token, start should be string::npos so that you do not lose the last token. That means the loop should test on start , and you need to take care not to wrap beyond npos :

start = 0;
finish = tempToken[ x ].find_first_of( " ", start );
while( start != string::npos )
{
    tokens[ y ].tokenString = tempToken[ x ].substr( start, finish - start );
    tokens[ y ].lineNumber = x + 1;
    start = (finish != string::npos) ? finish + 1 : string::npos;
    finish = tempToken[ x ].find_first_of( " ", start );
    y++;
}
Tom Gunn 1,164 Practically a Master Poster

Do not forget to enter curses mode before using getch() and leave curses mode when you are done:

#include <ncurses.h>

int main()
{
    initscr();
    printw("Enter a character: ");
    printw("You entered '%c'\n", getch());
    refresh();
    endwin();

    return 0;
}
Tom Gunn 1,164 Practically a Master Poster

A stringstream is still a stream, and stream objects in C++ do not have copy semantics. You can make that field a reference or a pointer if the stringstream is a necessary instance variable. Or you can recreate the stream each time you need it, but that would depend on what you are using the stream for.

necrolin commented: You're a life saver. Thank you. +1
Tom Gunn 1,164 Practically a Master Poster

Funny Tom you gave me negative feedback yesterday for helping someone with a SIMPLE piece of code...but its ok for you to do it?

I think the difference is clear if you read the questions. The OP you answered was asking for someone to do it for him. This one is actually trying and not making the connection that I showed to be important. But I did solve the problem completely in C++. Pseudo code would have been better, so I will accept your down vote in the spirit it was given. Thank you for keeping me honest. :)

p.s. For what it is worth, I did not test the code, so it might not even compile. ;)

Tom Gunn 1,164 Practically a Master Poster

const just says the function will not change anything

Kind of. const can only be applied to methods, and it means two things:

  1. The immutable state of the object will not be changed within a const method.
  2. The const method can be called by objects that are declared as const.

The mutable keyword was introduced to allow mutable data for const objects. The idea is that mutable data does not contribute to the constness state of the object. Mutable fields can be modified in a const method. Here is a sample program that displays the concept of const methods and mutable fields:

class Test
{
    int _x;
    mutable int _y;
public:
    Test(int x, int y): _x(x), _y(y) {}

    void Method1()
    {
        _x = 0; // OK, _x is mutable in a non-const method
        _y = 0; // OK, _y is mutable in all cases
    }

    void Method2() const
    {
        _x = 0; // will not compile, _x is immmutable in a const method
        _y = 0; // OK, _y is mutable in all cases
    }
};

int main()
{
    Test a(1, 2);
    Test const b(1, 2);

    a.Method1(); // OK, non-const object calling non-const method
    a.Method2(); // OK, non-const object calling const method
    b.Method1(); // will not compile, b is const, but Method1() is not
    b.Method2(); // OK, b is const and Method2() is const
}
Tom Gunn 1,164 Practically a Master Poster

Here is a tutorial on DLLs. It includes writing them, but the part on explicit linking is the one that shows how to load one. You can read more about LoadLibrary here.

abhipro commented: Helped a lot. Thanks +1
Tom Gunn 1,164 Practically a Master Poster

Close, but a temporary copy of the object is still an independent copy. C++ does not make reference copies of objects like Java or C#. To replace the object the iterator refers to, you need to assign to the dereferenced iterator. This will overwrite the object that it refers to:

bool updateListElement(Object* air)
{
    std::list <Object>::iterator iObject;
     for (iObject= list.begin(); iObject != list.end(); ++iObject)
     {
        Object temp = *iObject;
        if (temp.getCode() == air->getCode())
        {
            *iObject = *air;
            return true;
        }
     }
     return false;
}
Tom Gunn 1,164 Practically a Master Poster

Both and neither. Your question is much too vague to answer. Any objective comparison needs to be very specific about what is being tested and using equivalent code.

Tom Gunn 1,164 Practically a Master Poster

the out put is 1, when i have the prototype of the function
4 if i dont have the prototype of the function .

If there is no prototype for a function at the time it is called, the compiler will assume that the function returns int.

if i write any functions in sizeof operator its not generating any errors

In the case of a function return value, sizeof will evaluate the type of the object that the function returns. You are not getting the size of the function itself. I am not even sure how that would work. ;)

ii) i have debugged the code using GDB its doesnt jump to the function calls when functions are included in the sizeof operators
not even bothered whether function names are correct.

Yes! This is a tricky point where you can write correct code that looks wrong. For example:

int* p = malloc(sizeof *p);

Oh noes! An uninitialized pointer is being dereferenced and that is undefined behavior! But the code is correct and nothing is wrong with it because sizeof does not evaluate the expression. It only evaluates the type of the result of the expression. So the pointer is not being dereferenced at all, just like your functions are not being called. A more obvious test follows:

#include <stdio.h>

int main()
{
    int value;

    printf("%d\n", value = 123);
    printf("%lu\n", (unsigned long)sizeof(value = 456));
    printf("%d\n", value);

    return 0;
}

123 will be printed because the …

Tom Gunn 1,164 Practically a Master Poster

is sizeof an opearator(i actually studied it as a operator but then not so serious about the things)

Yes, it is an operator just like return , or = , or << . Sometimes it looks like a function because of parentheses around the operand, but that is just an appearance thing. Any expression can have redundant parentheses. :)

1.why is it called as an opeartor?

Because as an operator it is easier for the compiler to implement. Operators can be evaluated at compile time, and type information is available at compile time. sizeof is defined as evaluating to a compile time constant, so being an operator makes the most sense.

2.sizeof is compile time operator. what does that mean ?

It means that sizeof(expr) will probably be processed by the compiler and replaced with a constant value before generating object code. For example, if the size of an int is 4 on a hypothetical machine, the compiler might process printf("%lu\n", (unsigned long)sizeof(int)); and replace it with printf("%lu\n", (unsigned long)4UL); .

3.what about all other opearators arent they compile time?

If all parts of an expression are compile time constants, it can be evaluated at compile time, but might not be. That is up to the compiler. Otherwise it will be evaluated at run time because it relies on run time values and there is no other option.

when can i ignore the paranthesis around the argument.

When the operand is an object you can omit …

Tom Gunn 1,164 Practically a Master Poster

confused here on how the mapping is done between read ,write and scanf ,printf. because read/write takes file descriptors, buffers and size of data where as printf and scanf takes the variable lenght args: format strings and arguments

It is not a direct mapping. printf() for example does a lot of work to parse the format string and the variable arguments. It also handles output formatting because write() does not do any of that. The file descriptor is usually stored in the FILE object for stdout that printf() uses along with other information needed to make the system calls.

Gaiety commented: Thank a lot Tom U have been so helpfull +1
Tom Gunn 1,164 Practically a Master Poster
lookin dat dar string
    izzit dat vowuel?
        yup, stop lookin'
        nope, keepa goin'

didja find it?
    yup, hola!
    nope, hola louda!
Tom Gunn 1,164 Practically a Master Poster

Yes it is. But it is also called C++Builder, not Turbo C++.

No, I was wrong. Turbo C++ 2006, also called Turbo C++ Explorer, is not available anymore. It looks like the only free option now is a trial version of C++ Builder.

William was advising against the use of Turbo C++, not C++ Builder and they are not the same thing.

I know what William was advising against, but for the last few years Turbo C++ had been resurrected as Turbo C++ Explorer, with the 2006 version of Borland's compiler. I saw it the same as condemning VS2008 based on the problems of VS6, so I was making sure that everyone knew a more recent version of Turbo C++ was available. But I was wrong and that version is not available anymore, so it is safe to assume any mention of Turbo C++ means the ancient versions.

I apologize for giving outdated information. It was accurate when I checked a few months ago, and I made an unwarranted assumption that it was still accurate.

Tom Gunn 1,164 Practically a Master Poster

input == depth will happen for every node at that depth. You only want to print the total after the function returns instead of inside the recursive function. A reference parameter would be better suited to that:

#include <iostream>

struct treeNode
{
    int data;
    treeNode* left;
    treeNode* right;

    treeNode(int data, treeNode* left, treeNode* right)
    {
        this->data = data;
        this->left = left;
        this->right = right;
    }
};

void sumLevel(treeNode *&ptr, int input, int depth, int& depthTotal)
{
    if(input == depth)
    {
        depthTotal = depthTotal + ptr->data;
        return;
    }

    if(ptr->left != NULL)
    {
        sumLevel(ptr->left, input, depth - 1, depthTotal);
    }

    if(ptr->right != NULL)
    {
        sumLevel(ptr->right, input, depth - 1, depthTotal);
    }
}

int main()
{
    treeNode* root = 
        new treeNode(1,
            new treeNode(2,
                new treeNode(4, 0, 0),
                new treeNode(5, 0, 0)),
            new treeNode(3,
                new treeNode(6, 0, 0),
                new treeNode(7, 0, 0)));
    int sum = 0;

    sumLevel(root, -3, -1, sum);
    std::cout << sum << '\n';
}
simonsayz27 commented: A great help! +0
Tom Gunn 1,164 Practically a Master Poster

When i remove the root of the binary tree and I view the binary tree in In-Order Traversal, my program will stop running.

Then you are not resetting the links the way they should be. Removing the root means replacing the root with either the inorder predecessor or successor. Something like this:

Original:
    D
 B     F
A C   E G

Delete the root:
    *
 B     F
A C   E G

Make the inorder predecessor the root:
    C
 B     F
A *   E G

Delete the inorder predecessor:
    C
 B     F
A     E G

That behavior should fall out of your deletion algorithm because it is the same as the two child case for any node. But you also need to reset the root pointer. In the example above, if root still points to D after the algorithm finishes, the tree will be broken. So at the end, the address of C should be assigned to root to finish things up, but only if it was D that was deleted. That is an easy test because parent will be NULL if the root has a matching value.

cjjack88 commented: nice explaination +1
Tom Gunn 1,164 Practically a Master Poster

Pointers to functions and pointers to methods are not the same thing. A pointer to a method is really an offset into the class, not a real pointer with an address value. You need to make two overloads of the Integral() function. One that takes a function pointer and one that takes a method pointer:

#include <iostream>

typedef double real;

real Integral(real (*func)(real))
{
    return func(0);
}

template <typename ClassType>
real Integral(ClassType& obj, real (ClassType::*func)(real))
{
    return (obj.*func)(0);
}

class myclass{
public:  
    real classfunction(real);
};

real myclass::classfunction(real x)
{
    return 3.14;
};

real myfunc(real x)
{
    return 1.23;
}

int main()
{
    myclass probe;

    std::cout << Integral(myfunc) << '\n'
              << Integral(probe, &myclass::classfunction) << '\n';
}

An extra complexity with pointers to class members is that the pointer is defined on the class, but to use the pointer you need an object of that class to access the member. That is why the Integral() overload for the member pointer also has an argument for an object of the class type.

Tom Gunn 1,164 Practically a Master Poster

i would like to know the way we can make user enter a number in a menu reply perhaps so that he doesnt have to press the enter key

For this question we need to know what compiler and OS you use because there are no portable answers that will work everywhere. The answer needs to be tailored to your setup.

Just be wary that the getch() function and the associated conio.h header file are not portable.

This caveat applies to every solution because the problem itself is not portable. There is no standard way in C to read input without the possibility of buffering at a higher level. It is a system dependency.

Tom Gunn 1,164 Practically a Master Poster

Newbies not using code tags are a huge issue for us, and we finally made some successful progress

It must have been a sad state of affairs before that progress, because almost none of the new members use code tags in the C and C++ forums now.

Tom Gunn 1,164 Practically a Master Poster

Assignment statements do not work at the global scope. Put it in the main() function:

#include <iostream>

using namespace std;

int anArray[3];

int main()
{
	anArray[0] = 7;

	return 0;
}

It is also a good idea to avoid global variables, but that is a lesson for another day. :)

Your_mum commented: Problem Sovled!! : ] +1
Tom Gunn 1,164 Practically a Master Poster

It's by far the best compiler/debugger on the market.

Best is subjective. I do not think M$'s compiler is the best, but it is competitive with the other top compilers. The IDE and debugger are the biggest selling points for VS, in my opinion.

I rather use the VS 2008 complier myself but AFAIK it is NOT standard (eg. it will comply exactly in another IDE/complier/etc).

As I said before, VS 2008 is a C89/95 compliant compiler. You said you do not care about C99, so I do not understand why you keep insisting that VC is not standard. If you have specific complaints about VC that make it not standard in your opinion, I can address them. But until then, it is just going to be back and forth with no progress.

Dave Sinkula commented: You're really selling VS quite well. I'm the closest ever to trying it out. :icon_razz: +13
Tom Gunn 1,164 Practically a Master Poster

How to pass array of pointers to structures using functions in C?

Pointers are very regular. Once you know the basics, you can apply those basics to any level of indirection and everything will work the same way. Start with the two basic rules:

  1. A pointer variable is declared by appending * to the type.
  2. A pointer value is acquired by using the & unary operator.

Obviously things like this follow those rules, and you can find tons of examples in books or online:

int obj = 5;
int* p = &obj; /* p is a pointer to int and refers to obj's adress */

Pointers are used to pass large objects around without copying them, to dynamically manage blocks of memory, and to simulate pass-by-reference semantics. Pass-by-reference basically means that changes to a function parameter will affect the original object and not just a copy of it.

The two rules are recursive within limits, so you can add another level of indirection and get a pointer to a pointer:

int obj = 5;
int* p = &obj;
int** pp = &p; /* &&obj will not work because &obj is not an object with an address */

Pointers to pointers are usually used to simulate pass-by-reference semantics on pointers or to manage dynamic multidimensional arrays. The lesson to take away from this is pointers are just another type, and you can add a level of indirection to almost any type.

Arrays are an …

tux4life commented: Another great post :) +6
Tom Gunn 1,164 Practically a Master Poster

I cant use Visual Studio 2008 (which Id like to) as it uses it own compiler.

Most IDEs, including Visual Studio, can be configured to use a different compiler. I am wondering why you think gcc is the best C compiler. It is certainly good, but not really much better than the other popular alternatives, in my opinion. I would say the best is Comeau because it conforms to the latest standards of both C and C++. The only problems with Comeau are it is not free, and it is only a front-end compiler, so it is not as easy as install and go.

If you will not consider anything but gcc, I think Code::Blocks is your best option. MinGW comes packaged with gcc as the default compiler, installation is a snap, and the IDE is pretty good.

Tom Gunn 1,164 Practically a Master Poster

Strings in C are terminated by a '\0' character, but there is no magic that stops loops on it. Nothing stops you from walking past that character if the loop does not account for it. Change your loop to something like this and it will stop in the right place:

for(int i = 0; i < 10 && user_input[i] != '\0'; ++i)
{
    /* print user_input[i] */
}

This will make sure your loop stops when '\0' is found or the limit of the array is reached. To be strictly safe in C++, you should also limit cin when reading the string:

cin >> setw(10) >> user_input;

In C you can do the same thing with scanf():

scanf("%9s", user_input);
Tom Gunn 1,164 Practically a Master Poster

Is it true that some compilers require void before main ?

No. Any compiler that claims to compile C is required to allow a return value of int from main(). A return of void from main() is an extension that only some compilers allow. These two definitions of main(), and anything equivalent, are the only correct and portable options:

int main()
{
    /*...*/
}
int main(int argc, char* argv[])
{
    /*...*/
}

Why this error ?

I cannot say without seeing more code. It is probably in the wrong place, judging from the misplacement of clrscr() in your first post.

Tom Gunn 1,164 Practically a Master Poster

If the problem is that answer is 0, it is likely that you are dividing everything away. Because int does not have a precision, anything past the radix will be truncated. 1/2 is 0.5 as double, but 0 as int because the .5 is cut off.

Tom Gunn 1,164 Practically a Master Poster

what is the time cost of the actual re balancing of the tree

It depends on how the algorithms are implemented, but ideally for insertion the cost of rebalancing is constant. Only one part of the tree will ever be out of balance and at most two rotations will bring it back into balance. For deletion there could be one rebalance step for each node along the search path, so the number of rebalances on deletion is O(log(n)).

why is this ignored?

Rebalancing is a constant time operation and time complexities remove constant values. Instead of saying that AVL deletion is O(log(n) + m) where m is the time a rebalance takes, the m is trimmed away as an unnecessary part and the result is simplified to O(log(n)).

Tom Gunn 1,164 Practically a Master Poster
main()

If you do not specify a return type for main(), it does not mean you are exempt from returning a value. This feature is called implicit int. It means that if a data type is expected but not provided, int is assumed. So these two definitions of main() are exactly the same and the return statement is required for both:

main()
{
    return 0;
}
int main()
{
    return 0;
}

Relying on implicit int is not a good practice because the latest C standard removes the feature. Your code will not compile as C99, and that adds one more thing that needs to be changed to make it conform.

char STR1[100];

Names in all upper case are usually reserved for macros. It is up to you whether or not to use that convention, but people reading your code will be confused that STR1 is an array object and not a macro.

clrscr();

clrscr() is a non-standard function from conio.h, but you did not include conio.h. I would not recommend anything from conio.h, but like the naming conventions, it is up to you whether or not to take that advice. The portability police will not haul you away if you choose to use unportable stuff. :)

gets (STR1);

gets() is always unsafe and cannot be made safe through good coding practices. Never use it, because there is always a risk of array overflow. The safe alternative to gets() is fgets():

Tom Gunn 1,164 Practically a Master Poster

So to conclude: in standard C there's no straightforward way to find out how many subscripts you assigned a value to.

A second variable with the number of used items is straightforward. This approach is no different from a vector in C++, except for a little extra work in maintaining the count. As long as the array is filled in a non-random manner, the count variable is easy to use:

#include <stdio.h>

int main()
{
    int a[10];
    int n = 0;
    int x;

    fputs("Enter a list of integers: ", stdout);
    fflush(stdout);

    while (n < 10 && scanf("%d", &a[n]) == 1) ++n;

    printf("There are %d integers in the list:\n", n);

    for (x = 0; x < n; ++x) printf("%d\n", a[x]);

    return 0;
}

If the array is filled at random indexes the count variable will still work, but to avoid accessing uninitialized indexes there needs to be an empty value to mark the element as empty. With that in place an algorithm similar to strlen() can also count the non-empty elements:

#include <stdio.h>
#include <ctype.h>

#define SZ 'Z'-'A'+1

int arraylen(int a[], size_t sz)
{
    int n = 0;
    int x;

    for (x = 0; x < sz; ++x)
    {
        if (a[x]) ++n;
    }

    return n;
}

int main()
{
    int a[SZ] = {0};
    int c;
    int x;

    fputs("Enter a string: ", stdout);
    fflush(stdout);

    while ((c = getchar()) != EOF)
    {
        c = toupper(c);

        if (isalpha(c)) ++a[c-'A'];
    }

    printf("There are %d unique letters\n", arraylen(a, SZ));

    for (x = 0; x …
Tom Gunn 1,164 Practically a Master Poster

i dont know what is -pedantic mean

Here is a quote from the online manual for gcc:

-pedantic

Issue all the warnings demanded by strict ISO C and ISO C++; reject all programs that use forbidden extensions, and some other programs that do not follow ISO C and ISO C++. For ISO C, follows the version of the ISO C standard specified by any -std option used.

i think with compliance to ansi standards
but the latest compilers are ISO do we still need to stick to
ansi

Gcc probably uses -ansi as a historic artifact, but it really does mean ISO C90 and not ANSI C89:

-ansi

In C mode, support all ISO C90 programs. In C++ mode, remove GNU extensions that conflict with ISO C++.

Functionally there is not really much difference between ANSI C89 and ISO C90. Alternatively, you can use -std= to get the same effect and also for C99 conformance:

// ISO C90
gcc -Wall -std=c89 -pedantic test.c

// ISO C99
gcc -Wall -std=c99 -pedantic test.c

There are a bunch of other options. You can read about them here.

Tom Gunn 1,164 Practically a Master Poster

You differentiate between logical and actual links. Logical links are part of an n-ary node, but represented with actual binary links. If you can do that, you will be able to figure out how to move when doing any traversal. Red black trees do this well, if you need a real world example. Red links are logical links and black links are actual links, and they come together to represent a 2-3 tree with a binary structure.

Tom Gunn 1,164 Practically a Master Poster

string is not a good name because that name is already used for the std::string class. At the very least you should put your class in a namespace. I do not have Dev-C++, so I cannot reproduce your error, but I would guess that is the cause of the error.

There are also other errors. One that might be confusing is that this is a pointer, so you cannot use the . operator like that to get to members. Use the -> operator instead.

Tom Gunn 1,164 Practically a Master Poster

Replace this part of your header:

#define N_GLAC=22;
#define latGLAC[22] = {43.96875, 45.34375, 45.34375, 46.15625, 46.21875, 46.28125, 46.78125, 46.84375, 46.84375, 46.84375, 46.90625, 47.46875, 47.53125, 47.78125, 47.78125, 48.03125, 48.03125, 48.59375, 48.78125, 48.78125, 48.96875, 51.46875};
#define lonGLAC[22] = {-110.84375, -121.65625, -121.71875, -121.46875, -121.53125, -121.84375, -121.71875, -121.65625, -121.71875, -121.78125, -121.78125, -120.84375, -121.21875, -123.65625, -123.71875, -121.09375, -121.15625, -113.71875, -121.34375, -121.84375, -114.21875, -117.78125};

With this:

#define N_GLAC 22
double latGLAC[22] = {43.96875, 45.34375, 45.34375, 46.15625, 46.21875, 46.28125, 46.78125, 46.84375, 46.84375, 46.84375, 46.90625, 47.46875, 47.53125, 47.78125, 47.78125, 48.03125, 48.03125, 48.59375, 48.78125, 48.78125, 48.96875, 51.46875};
double lonGLAC[22] = {-110.84375, -121.65625, -121.71875, -121.46875, -121.53125, -121.84375, -121.71875, -121.65625, -121.71875, -121.78125, -121.78125, -120.84375, -121.21875, -123.65625, -123.71875, -121.09375, -121.15625, -113.71875, -121.34375, -121.84375, -114.21875, -117.78125};

There were two problems. First is you were defining N_GLAC the wrong way for a macro. Macros do not use the = sign to assign a value, and they do not end with a semicolon. Second, you were trying to define arrays with macro syntax. A header is nothing special when it comes to defining objects. You do it the same way as any global variable.

vaishnavi_5 commented: I tried to const uint16_t Cos12bit[361] = {4000,....}; with 361 elements in main.h but it shows error as duplicate definition in main.o & stm32f30x.o +0
Tom Gunn 1,164 Practically a Master Poster

Is that simply what I must do or is there a way to make it so the two functions have the same name?

There is a way, but it means writing a dispatch function or macro and all of the complexity involved. It is pretty simple if you are working with a small number of known functions, but something generic will probably be hairy. It is easier and probably better overall to avoid all of those moving parts and just use different names for each function. ;)

Tom Gunn 1,164 Practically a Master Poster

please help.

What do you want us to do? The only legal course of action is talking to the moderators of that forum on your behalf and convincing them to unban you. But we are random geeks, not mediators, so I cannot imagine why you are appealing to us instead of the people who banned you.

Tom Gunn 1,164 Practically a Master Poster

But i've read about some which come only in VC++ and googling usually doesn't fix the issue :/

All compilers throw errors like that. That is why relying on google to solve your problems is not the best idea. ;) I have never gotten an error that I could not decipher after a some thinking, and I guess everyone else is the same, so switching compilers because you do not like the errors is a step backward. Now you have to learn what a whole new set of errors mean.

Anyway, VC++ is too big and Code::blocks is smaller

Now it seems like you are reaching for any reason to switch compilers. If you want to do it that badly, you do not need to justify the decision to me. But it is OK to backtrack if you ever find out that your original decision was not the best one. I have seen several projects die because the team could not stand to admit mistakes and kept chugging along on a path to doom.

I am not saying that your switching compilers is a path to doom, of course. Knowing more than one compiler is a good thing. But programmers thrive on logic, and a weak logical case like jumping from "throwing lots of stupid errors" to "X is to big and Y is smaller" is suspicious. ;)

Tom Gunn 1,164 Practically a Master Poster

A struct with no members is not legal C. Your compiler should not allow it. C++ allows empty struct definitions, but all objects must have a size, so it will always be at least 1.

Tom Gunn 1,164 Practically a Master Poster

Is pass by value and call by reference the same?

No. Pass/Call by value makes an independent copy of the value for use in a function, but pass/call by reference uses the same object that was passed as an argument. Everyone likes to keep saying it, but C does not have pass by reference. It can only be faked passing pointers by value and using indirection them to get the original object.

why do we use call by value and pass by value? what are its uses?

Here is a 10,000 foot overview. Use pass by reference when:

  • The object is very large and passing it by value would be costly for memory. Make it const if it should not be changed.
  • The original object needs to be changed within a function and cannot be used as a return value.

Use pass by value when:

  • The value is small and the original object does not need to be changed within a function.

In the context of C, 'pass by reference' really means 'pass a pointer by value'. The whole thing is kind of a solved problem because C is such a small language. You either pass a pointer or not, depending on your needs. I think a more interesting question is whether or not value parameters should be made const:

void Function1(int x, int y);
void Function2(int const x, int const y);

But that is too far off topic for the thread. …