Narue 5,707 Bad Cop Team Colleague

Maybe he doesn't know the code so he did the easiest thing to increase his posting.

I strongly doubt it. Walt is one of the better programmers on this forum.

Anyways here's the code.

And it doesn't solve the stated problem. But on the plus side, I can't scold you for giving away answers to obvious homework problems when your code is clearly unacceptable as a solution. :)

A book like "Yashwant Kanetkar Let Us C (Indian author)" will help for the basics alone!

A book is a good idea, but please recommend better books. Let Us C is utter crap.

Shorter and better algorithm means quicker execution and lesser memory.

Shorter and better are often mutually exclusive when it comes to algorithms. As an example, bubble sort is shorter, but quicksort is better.

Let's look at the code.

>#define SIZE 50 // Maximum length of sentence
That's a pretty short sentence.

>int main()
Kudos for using a correct definition of main().

>char s,temp[SIZE/2]; temp is unused.

>printf("\nInput string: ");
I never understood this whole newline at the beginning convention. It offers no benefits except a pointless blank line. A newline at the end makes more sense. Anyway, in this case you cannot guarantee that the prompt will be displayed before gets() blocks for input, so a call to fflush() is warranted:

printf("\nInput string: ");
fflush(stdout);

There are three times when the stream will be flushed:

  • When …
Narue 5,707 Bad Cop Team Colleague

What you need to do is debug your program. Step through it and check the indices. You can do this programmatically by adding debug checks at risky points if desired. For example:

void compare(int numberstocheck[], int n) 
{
  int i, j, k;
  int thebucket[n];
  for(i = 0; i < n; i++) {
    thebucket[i] = 0;
  }
 
  for(i = 0; i < n; i++) {
    int index = numberstocheck[i];

    if (index < 0 || index >= n) {
      printf("out of range at index numberstocheck[%d] with value %d\n", i, index);
      getchar();
    }

    thebucket[numberstocheck[i]]++;
  }

  for(i = 0, j = 0; i < n; i++) {
    for(k = thebucket[i]; k > 0; k--){
      if (j < 0 || j >= n) {
        printf("out of range at index numberstocheck[%d]\n", j);
        getchar();
      }

      numberstocheck[j++] = i;
    }
  }
}

Anywhere you have a potentially unbounded array index, check the index and display a debug message if it fails. Note that things like thebucket[i] are safe in a loop that's strictly controlled.

Mouche commented: Helpful advice for finding index overruns! +7
Narue 5,707 Bad Cop Team Colleague

Create a signature and post on forums that are relevant to your niche. It will take time and effort but it can be a strategy which can work.

There's a caveat to this approach: make sure your posts are relevant and useful to the forum. Otherwise you'll either 1) be tagged as a spammer and banned quite quickly or 2) viewed by the community as a prat who's only interested in selfishly promoting his website to the detriment of the forum. Both are frowned upon. ;)

Narue 5,707 Bad Cop Team Colleague

You failed to give your structure a name. A typedef identifier is not the same as a structure tag, but you can use the same identifier for both because they're in different name spaces:

typedef struct node
{	char v;
	struct node *next;
}node;

This produces the usual C++ behavior:

struct node x; /* OK */
node x; /* Also OK */
Narue 5,707 Bad Cop Team Colleague

lots of contradictory replies,

which one's right?

Please notify the Oxford English dictionary. "Lots" has been redefined to mean "two". :icon_rolleyes: But given cscgal's track record with this site, I'd lean toward her opinion of having great content and letting the backlinks handle themselves...even if it didn't seem otherwise obvious.

Narue 5,707 Bad Cop Team Colleague

The usual methods of storing passwords aren't reversible, so the only option is resetting the password. You can then either email the new password to your users and give them the option of changing it, or invalidate the password and force them to change it rather than risk sending a temporary password in the clear.

For security reasons, the latter option is preferred.

sknake commented: +1 for you posting in the C# forum :) +14
Narue 5,707 Bad Cop Team Colleague

I didn't get what you mean and you can't express yourself well enough to help me understand? Well, then all I can do is interpret what you mean by your actions, and your actions are that of a lazy leech. Sorry.

Narue 5,707 Bad Cop Team Colleague

And how do I increase the size of an dynamic array when needed?

C++ doesn't have a version of realloc() that pairs with new[] and delete[], so your only option is to allocate a new array of the larger size, copy the existing elements to that new array, then release the old array:

int *resize_array(int *old_array, int old_size, int new_size)
{
    if (old_size >= new_size)
        return a;

    int *new_array = new int[new_size];

    for (int i = 0; i < old_size; i++)
        new_array[i] = old_array[i];

    delete[] old_array;

    return new_array;
}

Don't forget to use the new address, so all pointers to and into the old array must be assumed to be invalidated by the resize.

Narue 5,707 Bad Cop Team Colleague

but can you show me the full code?

Nope. The code you posted isn't even close to a voting program, so I can't justify giving you "full code" as it would constitute doing your homework for you.

i can't assemble these 2 parts

It sounds to me like you're overwhelmed and need to start smaller. Here's a good thread on the iterative development process. The only part that's missing is organizing your thoughts beforehand, and having a strong idea of how the program should work (in simple steps, like a flowchart) before writing any code.

Narue 5,707 Bad Cop Team Colleague

42.

NathanOliver commented: Good answer. It works for everything :) +10
Narue 5,707 Bad Cop Team Colleague

Particularly in the case of older-aged employees--they may have a problem but not have a clue in the world about how to explain it to you. Normally they might ramble on and on about irrelevant details and the only part of concern is a few words out of it.

Actually, that sounds a lot like students trying to explain their problems with homework. ;) It's also very common even with younger employees in the real world because the problems tend to be complex.

Make sure you get the information you need!

I think that applies across the board. If you don't have the information you need, you can't do much that's productive.

Narue 5,707 Bad Cop Team Colleague

Could someone actually answer how to do this ourselves as I also want to change my username?

There are two ways:

  1. Ask an admin to change your name.
  2. Convince Dani to promote you to an admin, so you have the ability to change your own name.

The first one is quite a bit easier than the second. ;)

Narue 5,707 Bad Cop Team Colleague

It really depends on how thorough you want to be, but I've found that the following triple whammy is sufficient most of the time:

  1. Make sure that your images are registered so that you can identify yourself as the copyright owner in the case that someone steals them.
  2. Decrease the resolution of an image as much as possible without making it look bad. The best way to keep people from stealing your images is to make them not worth stealing. ;)
  3. Prevent direct downloads by displaying the image as the background to an empty table:
    <table style="background-image:url('image.jpg'); width:M; height:N">
        <tr>
            <td></td>
        </tr>
    </table>

A copyright watermark can still be added to make it obvious you don't want to share, and the watermark can be unobtrusive. However, an unobtrusive watermark tends to be easier to remove unless you go out of your way to work it into each image naturally. Steganography is another option for watermarking in an invisible way, if you're just looking for ways to prove that the image is yours, but it's more complicated.

Narue 5,707 Bad Cop Team Colleague

Why is using feof() (which is the equivalent of !fin.fail()) as the loop condition wrong?

I posted a link. Basically it's a timing issue. The error flags aren't set until after you try and fail to read from the stream. Unless the loop contains a further sanity check, you'll be working with data from the previous iteration. It's a "the last record is processed twice" situation.

Narue 5,707 Bad Cop Team Colleague

Hi, I just want to know is c++ or maybe java the programming language which is used by most programmers to write those software programs we seen on cnet or clickbank?

It might be neither. Learn a little bit about the advantages of each language and choose the one that's best suited to your project.

Moschops commented: So true, and needs repeating frequently. +7
Narue 5,707 Bad Cop Team Colleague

what is a _Bool variable?

A variable of boolean type. The keyword for a boolean type in C is _Bool. It holds only two values: 0 or 1, which correspond to false and true, respectively. C also provides a header called <stdbool.h> that defines more convenient macros: bool , false , and true :

#include <stdbool.h>
#include <stdio.h>

int main(void)
{
    _Bool a = 0; // Without stdbool.h macros
    bool b = false; // With stdbool.h macros

    if (a) {
        printf("True!\n");
    }
    else {
        printf("False!\n");
    }

    if (b) {
        printf("True!\n");
    }
    else {
        printf("False!\n");
    }
}

how is the if then statement written exactly in c?

if (/* boolean condition */) {
    // True case
}
Narue 5,707 Bad Cop Team Colleague

I suspect they use several. Can you be more specific about which feature of facebook you're referring to?

Narue 5,707 Bad Cop Team Colleague

So, can you see what is wrong with the program?

I'd wager that it has something to do with your math. You're using the size of the buffer rather than the number of extracted characters to calculate the seek offset. Compare and contrast:

char *a3_fgets_2(char *str, int num, int fd)
{
    int n = read(fd, str, num - 1);
    int i = 0;
    
    if (n <= 0)
        return NULL;

    while (i < n) {
        if (str[i++] == '\n')
            break;
    }
    
    lseek(fd, i - n, SEEK_CUR);
    str[i] = '\0';

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

So I don't think my do-while loop is right... I don't know how to keep shifting the structs down until the end though...

The idea is to pretend the record being deleted is a hole in the array and fill it in with everything after it:

// Find the record and store its index in i...

// Fill in the "hole" starting at i to delete stdRec[i]
for (int x = i; x < n - 1; x++)
    stdRec[x] = stdRec[x + 1];

// Decrement the length of the array to reflect the deletion
--n;
C++newbie chick commented: awesome! +1
Narue 5,707 Bad Cop Team Colleague

You forgot to add a comma between the parent name and age values:

cmdtext = "insert into tblSTUDENT(FULLNAME, PARENTNAME, AGE) VALUES('"
                + txtStudentName.Text + "',  '" + txtParentName.Text + "', " + txtAge.Text.ToString() +")";

Sometimes it helps to use string.Format() instead of concatenation because the formatting around placeholders is easier to see:

cmdtext = string.Format(
    "insert into tblSTUDENT(FULLNAME, PARENTNAME, AGE) VALUES ('{0}', '{1}', {2});",
    txtStudentName.Text,
    txtParentName.Text,
    txtAge.Text);
Narue 5,707 Bad Cop Team Colleague

You'll want to read a full line, then break it down into columns with something like stringstream:

#include <fstream>
#include <iostream>
#include <sstream>
#include <string>
#include <vector>

int main()
{
    std::ifstream in("test.txt");
    std::vector<std::vector<int> > v;
    
    if (in) {
        std::string line;
        
        while (std::getline(in, line)) {
            v.push_back(std::vector<int>());
            
            // Break down the row into column values
            std::stringstream split(line);
            int value;
            
            while (split >> value)
                v.back().push_back(value);
        }
    }
    
    for (int i = 0; i < v.size(); i++) {
        for (int j = 0; j < v[i].size(); j++)
            std::cout << v[i][j] << ' ';
            
        std::cout << '\n';
    }
}
Narue 5,707 Bad Cop Team Colleague

The very definition of an abstract method in C# is a function declaration without an implementation. Non-abstract derived classes are required to provide the implementation. If you want to provide a default implementation, the method should be virtual rather than abstract.

If you want to keep it abstract just replace the body with a semicolon. That makes it a declaration rather than a definition:

public abstract Graphics drawRectangle(Graphics drawarea);
Narue 5,707 Bad Cop Team Colleague

can some one please give me a brief introduction to pointer...

A pointer is a variable that holds the address of another object. A pointer can be dereferenced to access the object stored at the address.

cout<<i (mean to print i)

i is uninitialized, but yes.

cout<<*i (what does it mean)

It means nothing. i is not a pointer, so dereferencing is not a meaningful operation.

cout<<**i (what does this mean)

It means nothing. i is not a pointer to a pointer. If one level of indirection isn't valid, two is also invalid.

cout<<&i ( address of i)

Yes.

(int*())buffer (what does this mean).

It means you don't know what you're doing. ;) At a high level it's casting the buffer object to a function taking no arguments and returning a pointer to int. But since a function type cannot be the target of a cast, the entire expression is invalid. You can cast to a pointer to a function though, assuming buffer exists and the conversion is meaningful:

int (*fp)() = (int(*)())buffer;

fp();
Majestics commented: Extremely Helpful +8
Narue 5,707 Bad Cop Team Colleague

Your hand is generally the best tool for manipulating the mouse.

Nick Evan commented: No shit. +17
Narue 5,707 Bad Cop Team Colleague

The assignment operator doesn't play well with the insertion (<<) and extraction (>>) operators. Ideally you would break those expressions out and print the result:

meters = miles*YARDS_PER_MILE*INCHES_PER_YARD*METERS_PER_INCH;
meters2 = yards*INCHES_PER_YARD*METERS_PER_INCH;
meters3 = feet/FEET_PER_YARD*INCHES_PER_YARD*METERS_PER_INCH;
meters4 = inches*METERS_PER_INCH;
totalmeters=meters+meters2+meters3+meters4;
    
cout <<"Units\t\tValue\t\tMeters\n\n\n";
cout <<"Miles\t\t"<<miles<<"\t\t"<<meters<<"\n\n";
cout <<"Yards\t\t"<<yards<<"\t\t"<<meters2<<"\n\n";
cout <<"Feet\t\t"<<feet<<"\t\t"<<meters3<<"\n\n";
cout <<"Inches\t\t"<<inches<<"\t\t"<<meters4<<"\n\n\n";
cout <<"Total\t\t"<<"\t\t"<<totalmeters;

The simpler your individual statements are, the easier the code will be to read and understand. Alternatively you could remove the assignment entirely since you don't use the result object:

cout <<"Units\t\tValue\t\tMeters\n\n\n";
cout <<"Miles\t\t"<<miles<<"\t\t"<<miles*YARDS_PER_MILE*INCHES_PER_YARD*METERS_PER_INCH<<"\n\n";
cout <<"Yards\t\t"<<yards<<"\t\t"<<yards*INCHES_PER_YARD*METERS_PER_INCH<<"\n\n";
cout <<"Feet\t\t"<<feet<<"\t\t"<<feet/FEET_PER_YARD*INCHES_PER_YARD*METERS_PER_INCH<<"\n\n";
cout <<"Inches\t\t"<<inches<<"\t\t"<<inches*METERS_PER_INCH<<"\n\n\n";
cout <<"Total\t\t"<<"\t\t"<<meters+meters2+meters3+meters4;

Finally, you can correct the error by fixing the precedence with parentheses:

cout <<"Units\t\tValue\t\tMeters\n\n\n";
cout <<"Miles\t\t"<<miles<<"\t\t"<<(meters = miles*YARDS_PER_MILE*INCHES_PER_YARD*METERS_PER_INCH)<<"\n\n";
cout <<"Yards\t\t"<<yards<<"\t\t"<<(meters2 = yards*INCHES_PER_YARD*METERS_PER_INCH)<<"\n\n";
cout <<"Feet\t\t"<<feet<<"\t\t"<<(meters3 = feet/FEET_PER_YARD*INCHES_PER_YARD*METERS_PER_INCH)<<"\n\n";
cout <<"Inches\t\t"<<inches<<"\t\t"<<(meters4 = inches*METERS_PER_INCH)<<"\n\n\n";
cout <<"Total\t\t"<<"\t\t"<<(totalmeters=meters+meters2+meters3+meters4);
Aghtar commented: Thanks again Narue +1
Narue 5,707 Bad Cop Team Colleague

Im debating the fact that Narue claimed cleaning strings were excessive regardless of the method.

Well, if you mean populating all elements with a null character then that rather limits the number of methods, doesn't it? The best way in such a case for an array, and those cases do exist, would be to let the compiler do it:

char cstring1[ARR_SIZE] = {0};
char cstring2[ARR_SIZE] = {0};

But I still disagree that it's necessary, defensive or not.

Either shes just being harsh or doesn't know about defensive programming

I'm well aware of defensive programming. What you're doing is not defensive, it's offensive (the bad smell variety). See further quoted replies...

if you're on a large project a coder might come in later and write to a string using custom methods, forgets the null and eventually something may overflow and do some damage

Following that logic, it's impossible to write robust code because some idiot coder might follow you and break it. While your defensive programming technique is valid, this isn't the use case for it.

and besides whats 100 bytes going to slow down

I don't know, but neither do you. It's rather hypocritical that you're advocating defensive programming yet immediately turn around and make unwarranted assumptions.

if we want to get picky I wouldnt use a define for the fgets.

This we can agree on.

hkdani commented: Posts obviously intelligent answers. But lacks depth of soul. +5
Narue 5,707 Bad Cop Team Colleague

what's that extra byte? does anyone know?

Perhaps a sentinel, or some kind of bookkeeping data. It might even be part of the CRLF combination if you're on Windows and the implementation uses a move-to-rear strategy of removal.

Ultimately, the problem is that you're using implementation internals without understanding how they work. In my experience, a more reliable method for this kind of hack is with the _cnt member (or equivalent):

#include <stdio.h>

int main(void)
{
    int ch;
    
    printf("Type something: ");
    fflush(stdout);
    
    ch = getchar();
    
    if (ch != EOF)
        printf("First: '%c' -- %d\n", ch, ch);
    
    while (stdin->_cnt != 0) {
        ch = getchar();
        printf("Remaining: '%c' -- %d\n", ch, ch);
    }
    
    return 0;
}

That member is typically used internally for the same purpose, which means you can use it with relative confidence, unlike strlen(stdin->_ptr) .

D33wakar commented: thanks! +4
Narue 5,707 Bad Cop Team Colleague

Borland Builder has been primarily C++ (with C support) for many years. Another option is Microsoft's Visual C++ if you want a visual designer that's integrated into the IDE.

Narue 5,707 Bad Cop Team Colleague

It's not the callee's job to clean up after the caller. I think that mainmenu() should simply expect the stream to be in a usable state, and if the caller fails to meet that expectation, it will need to handle erroneous processing by mainmenu().

Narue 5,707 Bad Cop Team Colleague

You can switch the console text color at will quite easily. Just change it to the desired color before printing the character, then change it back after printing the character:

#include <iostream>
#include <windows.h>

class TextAttr {
    friend std::ostream& operator<<(std::ostream& out, TextAttr attr)
    {
        SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), attr.value);
        return out;
    }
public:
    explicit TextAttr(WORD attributes): value(attributes) {}
private:
    WORD value;
};

#define FOREGROUND_WHITE (FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE)

int main()
{
    std::cout << "Regular text\n"
              << TextAttr(FOREGROUND_INTENSITY | FOREGROUND_GREEN)
              << "Bright green text\n"
              << TextAttr(FOREGROUND_WHITE)
              << "Back to regular\n";
}
Narue 5,707 Bad Cop Team Colleague

is there any way to check that the standart input is empty or no.

There's no portable way to do this without actually blocking for input. What OS and compiler are you using, and why do you think you need that behavior?

vedro-compota commented: +++ +3
Narue 5,707 Bad Cop Team Colleague

What I mean is, show me the command you use to invoke gcc. I suspect you're doing something like this:

$ gcc main.c functions.c

This compiles both files to *.o files and then tries to link them, but during compilation the contents of functions.c are textually inserted into main.c, so you end up having two copies of functions.c when the linker takes over.

Narue 5,707 Bad Cop Team Colleague

You're printing the value with %d, which is limited to signed int. The C99 specifier for unsigned long long is %llu:

#include <stdio.h>

int main(void)
{
    unsigned long long int cnt;
    
    for (cnt = 0; cnt <= 4026531840; cnt++)
        printf("%llu\n", cnt);
}
hkdani commented: Demonstrates an amazing ability to quickly solve problems not easily solved by others. Shows great depth of knowledge and a solid background based on in depth studies. +5
Narue 5,707 Bad Cop Team Colleague

Looking at the code you've given, I can tell you straight away that you're not using malloc() correctly. However, I'm having difficulty figuring out exactly what you're trying to do. The variable names (eg. matrices, new_matrix) suggest you're storing multiple two-dimensional matrices of varying size. In that case your types are totally mismatched. Here's an example of the allocation, initialization, display, and release process for what I've described:

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

void Memory_Allocation(int ***new_matrix, int rows, int cols)
{
    int i;
    
    *new_matrix = malloc(rows * sizeof(int *));
    
    for (i = 0; i < rows; i++)
        (*new_matrix)[i] = malloc(cols * sizeof(int));
}

void release_matrix(int ***matrix, int rows)
{
    int i;
    
    for (i = 0; i < rows; i++)
        free((*matrix)[i]);
        
    free(*matrix);
    *matrix = NULL;
}

void initialize_matrix(int **matrix, int rows, int cols, int start)
{
    int i, j;
    
    for (i = 0; i < rows; i++) {
        for (j = 0; j < cols; j++)
            matrix[i][j] = start++;
    }
}

void display_matrix(int **matrix, int rows, int cols)
{
    int i, j;
    
    for (i = 0; i < rows; i++) {
        for (j = 0; j < cols; j++)
            printf("%3d", matrix[i][j]);
        puts("");
    }
}

#define MATRICES 4
#define ROWS 2
#define COLS 4

int main(void)
{
    int ***matrices = malloc(MATRICES * sizeof(int**));
    int i;
    
    for (i = 0; i < MATRICES; i++)
        Memory_Allocation(&matrices[i], ROWS, COLS);
        
    for (i = 0; i < MATRICES; i++)
        initialize_matrix(matrices[i], ROWS, COLS, i);
    
    for (i = 0; i < MATRICES; i++) {
        display_matrix(matrices[i], ROWS, COLS);
        puts("");
    } …
Narue 5,707 Bad Cop Team Colleague

but I have the const int Max = 7; isnt MAX 7? Thats what the teacher instructed to use:

const int MAX = 7;
float highs[MAX];
float lows[MAX];

You have an array of 7 elements indexed from 0 to 6. The 7th element (ie. highs[7] or lows[7]) does not exist. Aside from the two things I mentioned, your code is acceptable. Those are the two problems that are holding you back.

Narue 5,707 Bad Cop Team Colleague

Are you required to display the tree like that? Because if not, it's much easier to rotate the tree by 90 degrees:

public void TreeStructure(Node root)
{
    TreeStructure(root, 0);
}

private void TreeStructure(Node root, int depth)
{
    if (root == null) {
        for (int i = 0; i < depth; i++)
            Console.Write('\t');

        Console.WriteLine('~'); // I use ~ to mean null
    }
    else {
        TreeStructure(root.Right_Child, depth + 1);

        for (int i = 0; i < depth; i++)
            Console.Write('\t');

        Console.WriteLine(root.Node_Data);

        TreeStructure(root.Left_Child, depth + 1);
    }
}
Narue 5,707 Bad Cop Team Colleague

Your post makes no sense at all. When asking a question, please keep in mind that we're not psychic.

Narue 5,707 Bad Cop Team Colleague

I'm not entirely sure I see the point of these graphs aside from the initial novelty. Keep in mind that there needs to be some sort of justification for a new feature because there's a cost to both the implementation and maintenance going forward. Since I'm reasonably sure Dani has more important things on her plate than pretty pictures with questionable usefulness, I'd start by asking you how we would all benefit from providing more stats on the top members page?

Narue 5,707 Bad Cop Team Colleague

There's not really a comment feature for posts. You really have only two options at present:

  1. Give the post positive or negative rep with the up or down arrows, respectively. This gives you the option to include a reputation comment.
  2. Reply to the thread with a quote. The easiest way is to click the Post Reply button on the post you're replying to. This will start a new post with the full contents in quote tags.
mehmedean commented: so this is my first 'comment' then... :) +0
Narue 5,707 Bad Cop Team Colleague

So is this the thing that C can do that C++ can't?

Um, no? C still allows the auto keyword as a storage class specifier, but as Mike said, it's useless to anyone but a compiler writer. As far as C doing something that C++ can't, I'd say C++'s new interpretation of auto is vastly more awesome. So even though C can use auto as a totally redundant and pointless storage class specifier, C++ can use auto for real improvements to the code. Thus C++ wins by a large margin on the auto front. ;)

Even if it is worthless it is cool that you just found an answer to a question that almost every C programer has asked.

That question is only asked by insecure C programmers who are afraid of C++. Besides, there are many better answers to the question, such as implicit conversion of a pointer to void in both directions:

char *p = malloc(100); /* Valid C, invalid C++ */
char *p = (char*)malloc(100); /* Valid C and C++, but frowned upon in C */

By different things in my second post I ment like DIFFERENT things.

Aside from a few minor differences, C++03 is a superset of C95. However, C++11 and C99 have both evolved in different directions, so you can find more DIFFERENT things. Likewise, the C1x changes (not yet complete) will move the bar even further away.

Would the auto spesephyer thing work if I made the project under …

Narue 5,707 Bad Cop Team Colleague

Hello. I am wondering how to split a string lets say char *a="raining apples training away"
using a delimiter like "g a" and the result will be:
rainin
pples
trainin
way
I tried using strstr but I got stuck. Any hints will be greatly appreciated. Thank you in advance!

Assuming you want to use the whole string "g a" as a delimiter rather than any of the characters in that string, the output would be:

rainin
pples trainin
way

It's certainly possible to do this with strstr(), but you need to be careful of two things:

  1. Make sure to skip over the delimiter before testing again
  2. Make sure to account for the last token as strstr() will return NULL when there's one more left

Here's an example:

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

int main(void)
{
    const char *src = "raining apples training away";
    const char *next = src;
    
    while ((next = strstr(src, "g a")) != NULL) {
        while (src != next)
            putchar(*src++);
        
        putchar('\n');
        
        /* Skip the delimiter */
        src += 3;
    }
    
    /* Handle the last token */
    while (*src != '\0')
        putchar(*src++);
        
    putchar('\n');
    
    return 0;
}
Narue 5,707 Bad Cop Team Colleague

Everything you've posted in this thread is nonsensical.

Narue 5,707 Bad Cop Team Colleague

I'm not understanding why I would remove id %2 = 0

You wouldn't. My code isn't a solution to your exact problem, read the comment. :icon_rolleyes: To be exactly what you want, the condition would be if (info->birthYear > 1995) , and I kind of assumed you weren't so helpless as to be unable to figure that out.

Narue 5,707 Bad Cop Team Colleague

Bump...............?

Please don't bump your threads, it's inconsiderate to all of the other people who need help.

I can't figure out how to iterate through the LinkedList and delete all students whose birthYear is greater than 1995

I fail to see the problem. Your main() function has code to iterate through the list, so you clearly know how to do it, and the list library contains a deleteNode() function. All you need to do is iterate and delete at the correct time:

Node *tempNode = firstNode->pNextNode;

/* Delete nodes with an even ID */
while (tempNode->pNextNode != NULL) {
    StudentInfo *info = (StudentInfo *)tempNode->pData;
    Node *next = tempNode->pNextNode;
        
    if (info->id % 2 == 0)
        deleteNode(tempNode);
            
    tempNode = next;
}

The only slightly confusing part is making sure that you can safely get to the next node after deleting the current one, but that's a simple matter of a temporary node.

minimi commented: Thank you for the great help +2
Narue 5,707 Bad Cop Team Colleague

Your code is awful and I'm not terribly interested in making it better. Please read this tutorial and try to match your algorithms to the sample code.

vedro-compota commented: oh you chamge avatar ) +3
Narue 5,707 Bad Cop Team Colleague

Maybe the other choice is don't use inheritance if you don't need it?

That's like saying that careless drivers cause accidents, so we shouldn't use cars.

JasonHippy commented: Classic Narue wit. Brightened up my day! +9
Narue 5,707 Bad Cop Team Colleague

I tested it in practice and it worked...

It's not required to compile. toupper() is an overloaded function, and transform() cannot differentiate between the overloads. If it works for you then that means you're relying on behavior specific to your compiler.

However, even if you fix the problem by wrapping toupper(), it's still not a good solution:

#include <algorithm>
#include <cctype>
#include <iostream>
#include <string>

using namespace std;

struct to_upper_case {
    int operator()(int ch) {
        return toupper((unsigned char)ch);
    }
};

int main()
{
    string ch;

    cout << "Insert String: ";
    cin >> ch;

    string ch2 = ch;
    
    transform(ch2.begin(), ch2.end(), ch2.begin(), to_upper_case());

    if (ch == ch2)
        cout << "upper case '" << ch << "'\n";
    else
        cout << "lower case '" << ch << "'\n";
}

The problem is that you're duplicating the string when you don't need to. The test checks all characters in ch for matching case, which can be done in place quite easily given a minor change:

#include <algorithm>
#include <cctype>
#include <iostream>
#include <string>

using namespace std;

struct is_upper_case {
    int operator()(int ch) {
        return isupper((unsigned char)ch);
    }
};

int main()
{
    string ch;

    cout << "Insert String: ";
    cin >> ch;

    bool all_upper = all_of(ch.begin(), ch.end(), is_upper_case());

    if (all_upper)
        cout << "upper case '" << ch << "'\n";
    else
        cout << "lower case '" << ch << "'\n";
}

Or prior to C++0x (where std::all_of() was defined) you might choose an option such as find_if():

#include <algorithm>
#include <cctype>
#include <iostream> …
Eagletalon commented: Very explanatory and educational +2
Narue 5,707 Bad Cop Team Colleague

The best alternative is not to clear the screen. Most of the time when I see things like system("cls") or clrscr() , there's no legitimate reason for clearing the screen.

However, since you're using Windows you might consider the Win32 API as a reasonably portable (on Windows) solution. If you're dead set on clearing the screen, that is:

#include <windows.h>

void clear_screen()
{
    HANDLE h = GetStdHandle(STD_OUTPUT_HANDLE);
    CONSOLE_SCREEN_BUFFER_INFO buf;
    
    GetConsoleScreenBufferInfo(h, &buf);
    
    DWORD size = buf.dwSize.X * buf.dwSize.Y;
    COORD pos = {0};
    DWORD n;
    
    FillConsoleOutputCharacter(h, TEXT(' '), size, pos, &n);
    FillConsoleOutputAttribute(h, buf.wAttributes, size, pos, &n);
    SetConsoleCursorPosition(h, pos);
}
Narue 5,707 Bad Cop Team Colleague

default argument missing for parameter 6

Defaulted parameters cannot be followed by non-defaulted parameters because the compiler has no way of determining when you want the argument defaulted and when you're simply calling the function incorrectly:

foo(int x, int y = 0, int z); // Illegal, y is defaulted and z is not
foo(int x, int z, int y = 0); // OK, all defaulted parameters are at the end
Narue 5,707 Bad Cop Team Colleague

is this any better?

No.

or should i just follow the 'Starting C' section?

I'd suggest a good book.

  • Programming in C by Stephen G. Kochan is decent enough and accessible in my opinion.
  • C Programming: A Modern Approach by K. N. King is probably the most recommended beginner's book, but it's kind of heady.
  • Pointers on C by Kenneth A. Reek is my personal favorite, but it is out of date. Ideally you would get a book that covers C99.

Browsing Amazon I notice that there's a Head First C coming out early next year. That seems promising, but it won't help you right now. ;)