Narue 5,707 Bad Cop Team Colleague

Assuming you need to do it all manually, how about redirecting output to a temporary file? Then you can echo the temporary file to the screen as well as append it to your log file.

Narue 5,707 Bad Cop Team Colleague

>Hmm... keeping the dictionary in an external file seems like the best approach to me. Correct me if I'm wrong.
How do you suggest looking up a word? Search the file each time? Unless it's a properly designed external database, that's going to be very inefficient. The words will likely all fit in memory, so an internal data structure makes more sense here.

>But to solve this problem he can have all the strings on one line.
Once again, looking up a word is tedious and potentially inefficient. You'd have to parse out the words every time, or store them in a separate data structure. But if you're using a separate data structure anyway, just use that as the primary storage medium.

>Use a linked list of words.
I'd use a balanced binary search tree or a chained hash table. Since this is a dictionary, we can expect lookup to be the primary operation. Searching a linked list of 50k+ words may not be the best approach. Of course, you can try amortizing the performance with tricks like moving the most recent match to the front, but I think a data structure better suited to searching is the superior option.

tux4life commented: Nice post :) +8
Narue 5,707 Bad Cop Team Colleague

I'd use a while loop. But since you can use any loop to simulate the behavior of any other loop, it's really personal preference.

Narue 5,707 Bad Cop Team Colleague

>I was just wondering what other people's opinions were.
I wouldn't bother with any kind of marker in the string. The caller clearly knows what radix they want to generate, so generate the string and let them add a prefix (or suffix) if they so desire.

Narue 5,707 Bad Cop Team Colleague

>First C compiler program compiled on which compiler..???
Unknown, but probably either an assembler or Ken Thompson's B compiler on the PDP-11.

Narue 5,707 Bad Cop Team Colleague

Have you specified -lbgi -lgdi32 -luser32 as extra libraries?

Narue 5,707 Bad Cop Team Colleague

>this is my first time programing and the class i am in uses savitch absolute c++
You don't need to defend yourself. We all had to start somewhere, and making mistakes comes with the territory.

>do you recommend supplementary materials for a beginner, because i am having difficulty with the text.
I haven't read that one. Could you elaborate on what parts you're having trouble with?

chococrack commented: always a delight +2
Narue 5,707 Bad Cop Team Colleague

For starters, operation is a double when it should be a char. You also have a rogue semicolon in your final else that ensures the quotient output will always occur.

Narue 5,707 Bad Cop Team Colleague

Technically it is cleaned up, unless you're on a platform that doesn't reclaim dynamic memory for a process when the process terminates. But if you mean the pointer is never deleted explicitly, that's easy enough. Just print something in the destructor, throw an unhandled exception, and watch the message never get printed:

#include <cstdlib>
#include <exception>
#include <iostream>

class SimpleException {
public:
    SimpleException() { std::cerr<<"Creating MyException object\n"; }
    ~SimpleException() { std::cerr<<"Destroying MyException object\n"; }
};

void unhandled_handler()
{
    std::cerr<<"Terminating due to unhandled exception\n";
    std::exit(EXIT_FAILURE);
}

#define CATCH_UNHANDLED 0 // Set to 1 to catch and delete

int main()
#if CATCH_UNHANDLED
try
#endif
{
    std::set_terminate(unhandled_handler);
    throw new SimpleException();
}
#if CATCH_UNHANDLED
catch (const SimpleException* pex) {
    delete pex;
}
#endif
iamthwee commented: No _jsw variables... This deserves +ve rep. +13
Narue 5,707 Bad Cop Team Colleague

>When I see a thread in C++, and the last poster is "Ancient Dragon"
>or "Narue", I just don't bother even opening the thread.

Sounds like a poor strategy if your goal is self-improvement. I try to read all threads that seem remotely interesting ("Gimme teh codez!" are not, by the way) on the off chance that I'll learn something new, regardless of who the poster is. Though I do tend to focus my attention more on posts from people whom I respect.

>And besides: nobody is perfect, so you might actually have something to add or correct.
That reminds me of The Game™ some of us play. Correcting technical errors is the goal, with more points being awarded as difficulty increases. Difficulty comes in the form of how complex the topic is (ie. how easy it is to make a mistake in the correction), as well as how often the one being corrected makes mistakes.

The benefit of the game is twofold:

  1. Overall quality increases for each thread because there are many eyes looking to nitpick.
  2. Those who play are in a constant struggle to improve (and thus avoid being corrected).
Narue 5,707 Bad Cop Team Colleague

The two aren't related. Assertions are for catching bugs in the code, exceptions are for managing legitimate errors when the program runs.

Narue 5,707 Bad Cop Team Colleague

>Is it just me, or do you find your patience stretched rather thin when posting here at Daniweb sometimes?
Sometimes? When the majority of questions are students looking for a handout, a constant state of zero patience is normal. Though I have infinite patience for people who are truly interested in bettering themselves and actually try to learn.

>A) People posting completely incorrect code/answers
There's nothing wrong with ignorance. Don't expect everyone to be perfect. Now if they continue to post the same things that are wrong, that's different. Willful ignorance is not cool.

>B) People agreeing with completely incorrect code/answers
Once again, there's nothing wrong with ignorance. A lot of people simply learn the wrong things. We should help them correct the misunderstandings, not berate them and allow them to remain ignorant.

>C) People telling me that my code is wrong/doesn't work when i know perfectly well that it does
While this happens to the best of us, most of the time the best response is to consider that your code actually is broken. If you can prove that it's correct, do so. If not, that's an indication that there's a problem. Despite what Larry Wall says, hubris has no place in programming.

>But is it just me that finds it infuriating having to defend your posts to
>people who clearly have no understanding of the point they are arguing?

I have no problem defending myself if I'm …

Geekitygeek commented: true, true and umm...true :) +0
Narue 5,707 Bad Cop Team Colleague

>Well, that was a giveaway. I answered 'YES'.
The giveaway was that the statement is so biased as to be immediately false. The king of all languages and the best ever made? You seriously answered yes to that? :D

>It's been like 7 years, but C++ still holds its rank as King.
Where did you get seven years? C++ has been standardized for longer than that, and existed as the language of choice for many programmers for about a decade and a half before that. The language itself is over thirty years old.

>IMO opinion, if you know C/C++, you pretty much KNOW programming.
Best of luck moving to a completely different language (like LISP) if all you know is C and/or C++. There's more to programming than you think.

>It's also the hardest language to master IMO.
That's not a totally inaccurate statement, but I would say "one of the hardest".

Narue 5,707 Bad Cop Team Colleague

>So kindly hlp me out to decide it...
I fail to see how we can help. We know nothing about your knowledge or about you...except that you're exceedingly uncreative and generally clueless about what you've been studying for the last N years.

Narue 5,707 Bad Cop Team Colleague

Once link becomes a null pointer, you've left the realm of the tree. Assigning to link at that point does nothing productive. What you need to do is save a pointer to the last node before link become null, and then assign tmp to either the lc or rc link (depending on the direction you're moving) of that node:

#include<stdio.h>
#include<stdlib.h>

struct node {
    int data;
    struct node *lc;
    struct node *rc;
};

int main()
{
    struct node *start = NULL;
    int i,n,flag;

    printf("how many integers you wish to enter\n");
    scanf("%d",&n);

    for(i=0;i<n;i++) {
        struct node *tmp = malloc(sizeof(struct node));
        int a;

        scanf("%d",&a);

        tmp->data=a;
        tmp->lc=NULL;
        tmp->rc=NULL;
        flag=0;

        if (start==NULL)
            start=tmp;
        else {
            struct node *last = start;
            struct node *link = start;

            while (link!=NULL) {
                last = link;
                if (link->data==a) {
                    printf ("The element already exists");
                    flag=1;
                    break;
                }
                else if (a>link->data) {
                    link=link->rc;
                    printf("rc\n");
                }
                else if (a<link->data) {
                    link=link->lc;
                    printf("lc\n");
                }
            }

            if (flag==0) {
                if (a > last->data)
                    last->rc = tmp;
                else
                    last->lc = tmp;
            }
        }
    }

    return 0;
}
Narue 5,707 Bad Cop Team Colleague

>I just (wrongly) assumed that all compilers would compile simple increments the same
As with many compiler specifics, it's not quite that simple. Depending on the target processor, different instructions may be deemed more efficient. So you'll see compilers favoring for example add over inc, or lea over both add and inc. The bias can change even within the same processor family. So the machine code itself may vary depending on hardware targets.

In terms of which of ++x , x++ , x+=1 , and x=x+1 is faster, you're talking about one of the most basic of basic optimizations (even Ritchie's first C compiler did this). Much like I would expect local variable allocation along with the stack frame regardless of scope rather than when execution enters each scope, I would expect all of the above (in isolation) to produce identical instructions even with optimization disabled.

So let's look at the questions I saw pop up in the thread:

  • Q: Which is faster, ++x or x+=1 ?
    A: On any decent compiler there's no difference, but only when the expressions are taken in isolation. As part of a larger expression, there's more to consider. However, the usual guideline of "mind your own business and let the compiler handle micro-management of expressions" applies. It's better at it than you are anyway.
  • Q: Will the above compile to the same machine code on my compiler?
    A: It's very likely, unless you have a compiler that aggressively …
Narue 5,707 Bad Cop Team Colleague

This tutorial might be helpful.

Narue 5,707 Bad Cop Team Colleague

>I can't figure out how to return a local variable.
There are two other common options aside from making the variable static:

  1. Pass in a buffer and work with it.
    char *time_stamp(char *buf, size_t size)
    {
        /* Populate buf */
    
        return buf;
    }
  2. Dynamically allocate the memory.
    char *time_stamp(void)
    {
        char *str = malloc(21);
    
        /* Populate str */
    
        return str;
    }

Just as with static, these options have advantages and disadvantages. It's really up to you to pick which one works best for your application. However, I'll mention that I usually pass in a buffer. That way the caller has more control over memory and things remain cleaner (if more verbose on the caller side).

Narue 5,707 Bad Cop Team Colleague

>Is there any documentation on this sort of thing?
There's documentation on stdio, for sure. But the actual implementation is up to the implementor. If you want to know how people usually do it, their code is the best way to go about it.

Narue 5,707 Bad Cop Team Colleague

Is that a real array or a dynamic array?

Narue 5,707 Bad Cop Team Colleague

What will you do when stdout is redirected to a file? The file descriptor approach is conventional, and your flag idea seems awkward at best. There will be a lot of special cases with the flag while a file descriptor just works naturally.

Narue 5,707 Bad Cop Team Colleague

So I see, though you'll need to go about it less directly:

char *temp = time_stamp();
char *timeBegin = malloc(strlen(temp) + 1);

if (timeBegin == NULL) {
    /* Handle the error */
}

strcpy(timeBegin, temp);

Since the string returned by time_stamp is stored in a static array, you need to make a copy of the data before the next call to time_stamp.

[edit]
>with out haveing to make the local variable (in time_stamp()) static?
Now I'm confused. Is it static or not? That makes a huge difference in your program's correctness. Your first post says it's static and now you imply that it's not.
[/edit]

Narue 5,707 Bad Cop Team Colleague

>char *timeBegin = (char *)malloc(sizeof(char) * 21);
timeBegin is assigned a pointer to dynamic memory.

>timeBegin = time_stamp();
timeBegin is immediately re-assigned to a different pointer, which is not dynamically allocated. The first pointer returned by malloc is lost forever, thus causing a memory leak.

>free(timeBegin);
You're not allowed to free a pointer unless it was originally returned by malloc, calloc, or realloc because it doesn't exist within the dynamic memory manager's list of allocated blocks.

Narue 5,707 Bad Cop Team Colleague

I think your issue will be more algorithm-based than language. How are you generating the combinations?

Narue 5,707 Bad Cop Team Colleague

>Actually, it is
Prove it. I can prove otherwise by showing the lack of a definition for flushall in the C standard, so you're already in a hole.

>and but I have experienced myself, somewhat inconsistent behaviour of C++ compilers where they
>give inaccurate result on first compilation mostly one rebuilding in file operations in C.

While at a glance this (and all of your other posts) look like English, they're largely incomprehensible.

Salem commented: Indeed +17
Narue 5,707 Bad Cop Team Colleague

You're trying to keep 800000 records in memory at once? I strongly suspect that's unnecessary.

Narue 5,707 Bad Cop Team Colleague

flushall isn't guaranteed to be available as it's a non-standard extension. Besides, you can achieve the same effect as flushall (assuming it does what one might expect) with fflush(NULL).

Narue 5,707 Bad Cop Team Colleague

>no it doesnt ..
Did you use it correctly?

fprintf(stdout,"hello-out");
fflush(stdout);
fprintf(stderr,"hello-err");

stdout is buffered by default while stderr is not. The three ways to flush a buffered stream are filling it up ("hello-out" is unlikely to do that), printing a newline (which you don't), and calling fflush.

Narue 5,707 Bad Cop Team Colleague

Post the code you're using right now, and a sample file.

[edit]
Here's another sample to test with:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

struct estr_reg {
    char *molid;
    char *molc;
};

char *clone_str(const char *s)
{
    char *p = malloc(strlen(s) + 1);
    
    if (p != NULL)
        strcpy(p, s);

    return p;
}

int main(void)
{
    FILE *in = fopen("data.txt", "r");

    if (in) {
        struct estr_reg records[10];
        char line[BUFSIZ];
        size_t i, n = 0;

        while (n < 10 && fgets(line, sizeof line, in) != NULL) {
            line[strcspn(line, "\n")] = '\0';
            records[n].molid = clone_str(strtok(line, ";"));
            records[n].molc = clone_str(strtok(NULL, ";"));
            ++n;
        }

        fclose(in);

        for (i = 0; i < n; i++) {
            char *molid = records[i].molid != NULL ? records[i].molid : "(null)";
            char *molc = records[i].molc != NULL ? records[i].molc : "(null)";

            printf("%s\t%s\n", molid, molc);

            free(records[i].molid);
            free(records[i].molc);
        }
    }

    return 0;
}

[/edit]

Narue 5,707 Bad Cop Team Colleague

Adak forgot to allocate memory to molid and molc. For testing purposes, just make those large arrays and see if it works better:

struct estr_reg {
  char molid[BUFSIZ];
  char molc[BUFSIZ];
};
Narue 5,707 Bad Cop Team Colleague

>okay i'v had enuf.
You asked for it.

>go f urself
Haha! I love it when cheaters get all pissy after being told "no".

Narue 5,707 Bad Cop Team Colleague

>but it wud b kinda useful if u cud help...
I'm sure it "wud". But that would defeat the purpose of homework, which is for you to better learn the material. Being given answers doesn't teach you anything except how to be helpless.

Narue 5,707 Bad Cop Team Colleague

>use a loop.
Obviously. Now do it in an elegant way. ;)

Narue 5,707 Bad Cop Team Colleague

>what is it that u guys do here then?
It could best be described as not-for-profit tutoring.

Narue 5,707 Bad Cop Team Colleague

>Both describe typedef as making a "synonym" or "another name", for a data type
Yes, that's how I describe them too. But one mustn't confuse "typedef" with "typecast". That's how I interpreted your initial statement, and why I corrected what I perceived to be the problem.

Narue 5,707 Bad Cop Team Colleague

The argv array is writable, but the size of the array and the size of each element are set in stone. Why not just re-create argv in another variable then use that variable?

int main(int argc, char **argv)
{
    char **temp = malloc(2 * sizeof *temp);
    int i;

    /* No error checking for brevity */
    temp[0] = "aa";
    temp[1] = "bb";

    /* Optional if you really want to use the argv identifier */
    argv = temp;

    /* ... */

    free(temp);
}

I still fail to see why you would want to change argv to something completely different.

Narue 5,707 Bad Cop Team Colleague

Why do students keep expecting us to do their homework?

Narue 5,707 Bad Cop Team Colleague

Why do you want to do this?

Narue 5,707 Bad Cop Team Colleague

>Well, casting is not the same thing as typecasting.
Erm, yes it is.

>Typecasting just creates an "alias" (another name), your program
>can use, for a certain datatype (typically a struct name).

You're thinking of typedefing. Casting, typecasting, explicit conversion, and type coercion are pretty much the same thing.

>A cast in C is redundant, generally.
When used properly a cast accomplishes one of two goals:

  • Force a conversion where no implicit conversion is allowed. A good example is type punning:
    int x = 12345;
    char *p = (char*)&x;

    &x is a pointer to int, but that type is incompatible with a pointer to char. The cast is required here.

  • Force a conversion where an implicit conversion is allowed to silence warnings. One such example is a truncation warning when there's no chance of truncation:
    char s[BUFSIZ];
    size_t i = 0;
    int ch;
    
    while ((ch = getchar()) != EOF)
        s[i++] = (char)ch;

    getchar returns int only to support EOF. Since EOF is handled separately and won't ever participate in the assignment to char, the possibility that char might be unsigned is irrelevant. As such, on compilers where the int to char conversion throws a warning, the cast says "Yes, I really do know what I'm doing and this conversion is safe"[1].

I know you were talking about casting malloc, but I just wanted to make things clear. In the case of malloc, an implicit conversion of T*<-->void* is allowed, which means the …

Narue 5,707 Bad Cop Team Colleague

>By undefined behavior, do you mean that sometimes it can be changed and sometimes cannot be?
By undefined behavior I mean the C standard makes no guarantees at all about what might happen when your program runs. It's completely unpredictable, even on different runs of the same build. Worse yet, the undefined behavior isn't restricted to that one operation. Once you invoke undefined behavior, your entire program's behavior becomes undefined.

Narue 5,707 Bad Cop Team Colleague

>Can you please elaborate a little more.
It seems like you're making the proper distinction between headers and header files (ie. a header need not be a file). However, aside from that distinction, there's no difference: Include a header and a bunch of stuff gets textually pasted into your translation unit. No magic, just glorified copy/paste.

Narue 5,707 Bad Cop Team Colleague

>Well, unlike C, C++ provides a concept of headers(not header files)
The concept of headers is identical between C and C++.

Narue 5,707 Bad Cop Team Colleague

>is it possible to create my own simple programming language in c++?
Of course it's possible. But it's harder than you probably think.

Narue 5,707 Bad Cop Team Colleague

I like the explicit nature of the new rules. They should be much easier to enforce as well as making more sense to regular members.

Narue 5,707 Bad Cop Team Colleague

-1 in an unsigned context is portable, yes.

Narue 5,707 Bad Cop Team Colleague

>It's the way I test c++.
Unfortunately, there are so many areas of undefined, unspecified, and implementation-defined behavior in C++ that empirical tests only go as far as the "it works for me" argument. You can test using varying compilers and varying systems for more portable results, though.

Narue 5,707 Bad Cop Team Colleague

>I know that by declaring a variable as 'const', its stored in read only memory
Incorrect. There's no rule that says const qualified objects must be stored in read-only memory.

>I found that a const variable's value can be changed using pointers.
Maybe, maybe not. Attempting to modify the value of a const qualified object invokes undefined behavior. There's also no rule that says const qualified objects cannot be stored in read-only memory.

Narue 5,707 Bad Cop Team Colleague

>I think you have bigger issues to address first. My compiler returned 40+ errors.
I got the distinct impression that the code is for illustrative purposes only. It's not his actual code, merely an ad hoc example of the overall design. Simple bugs can be ignored in this case, I believe.

Narue 5,707 Bad Cop Team Colleague

>That wasn't all that helpful.
Explanations of undefined behavior are rarely helpful. Just don't write code like that. ;)

Narue 5,707 Bad Cop Team Colleague

>Because it is an unsigned integer, shouldn't it only be able to store positive values
Yes, that's it exactly.

>Or is the -1 just like a catch all method, so that nothing else can possibly have that value?
If it helps, you can think of -1 in unsigned context as (0U - 1) . The effect is the same: subtracting 1 from 0 underflows and wraps around to the largest value for unsigned int.