Narue 5,707 Bad Cop Team Colleague

Convert the character to lower case before using it as an index:

num[tolower(userstring[c]) - 'a']++;

Note that you'll need to include <ctype.h> for tolower().

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

Use the disk you originally installed from. If you don't have it, upgrade to one of the Express versions (they're free).

Narue 5,707 Bad Cop Team Colleague

This is one of the worst programs I ever saw, and I am "taking it easy lol".

The code is just fine, though it's obvious the teacher wrote the majority of it and left comments for students to fill in the blanks. If this is one of the worst programs you've ever seen, I envy you. :D

Narue 5,707 Bad Cop Team Colleague

Given that you've had plenty of time to complete this and the code you posted suggests you've done nothing at all, I think it would be more productive if I taught you the importance of time management by watching you get a failing grade on the assignment. Sadly, many people need to be burned before the lesson hits home.

That's not to say that I won't help, provided you ask a smart question and don't expect me to write the program for you.

Narue 5,707 Bad Cop Team Colleague

I see. And when was the assignment first given to you?

Narue 5,707 Bad Cop Team Colleague

Here's a quote from the C standard:

Between the previous and next sequence point an object shall have its stored value
modified at most once by the evaluation of an expression. Furthermore, the prior value
shall be read only to determine the value to be stored.71)

Footnote 71 is as follows:

This paragraph renders undefined statement expressions such as

i = ++i + 1;
a[i++] = i;

while allowing

i = i + 1;
a = i;

Narue 5,707 Bad Cop Team Colleague

learning comes from the mistakes

Hopefully one day you'll learn that trying to define undefined behavior is a mistake. Good day.

Narue 5,707 Bad Cop Team Colleague

Two hours, eh? Just out of curiosity, how long have you been working on this assignment?

Narue 5,707 Bad Cop Team Colleague

that the thing i am asking why it is unpredictable..there should be some reason.

I didn't write the language specification, and I wasn't privy to the discussions that produced this particular rule. I suspect that even if you find someone who was part of the standards committee at the time and remembers the discussion, you wouldn't understand his explanation.

So, how about not obsessing over something that's flat out wrong anyway, and focus on learning to do things the right way. I can show you the rule that's in play here and I can show you how to recognize violations of that rule, but I'm sick and tired of seeing people waste their time trying to explain undefined behavior.

Narue 5,707 Bad Cop Team Colleague

can you explain me why..??

I did explain why: the expression is undefined, completely unpredictable, and there's no sense in trying to analyze whatever garbage results you get.

Narue 5,707 Bad Cop Team Colleague

The expression is undefined and can have any result, please stop trying to analyze it.

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

If that's the full code then you're missing definitions for all of the member functions.

Narue 5,707 Bad Cop Team Colleague

but next to it the black light indicating negative rep.

Negative rep is colored red, not gray. Gray boxes are used for the Community Center (where rep points don't count), and users who have too little rep power to affect you.

Narue 5,707 Bad Cop Team Colleague

im new here , so i dont know how to CODE effectively.. i just copied my c++ code frm my computer, pasted it here and pressed the

option.. is that right or wrong?[/QUOTE] 
Click Me. The most important part is that your code actually have formatting. If there's zero indentation, code tags won't help:

[code]

// This is farking hard to read!!!!!!
#include <iostream>

int main()
{
for (int i = 0; i < 10; i++)
{
std::cout << "Counting to " << i << '\n';
}
}

With properly formatted code, the code tags will preserve your indentation:

// This is easy to read
#include <iostream>

int main()
{
    for (int i = 0; i < 10; i++)
    {
        std::cout << "Counting to " << i << '\n';
    }
}

People will be far less inclined to help you if your code is difficult to read, so it's in your best interests to make it as clear as possible both in style and formatting. There's also a post preview feature that you should make use of to ensure that your posts will be displayed exactly as you want.

If you're using the quick post box at the bottom of the thread, simply click on the Use Advanced Editor button. This will take you to the advanced editor and automatically preview what you already have in the quick post box. From there you can use the Preview Post button to do the same thing.

Narue 5,707 Bad Cop Team Colleague
Narue 5,707 Bad Cop Team Colleague

can I write a chunk of code for this in a function for something, so yes.

You can write a function for it, yes. What you can't do is write a function that magically works on every possible platform. Console text color is inherently non-portable.

Is this why people love java?

Wide portability without losing functionality is one of Java's selling points.

Narue 5,707 Bad Cop Team Colleague

system("clear") is the equivalent to system("cls") on both Linux and OSX.

Narue 5,707 Bad Cop Team Colleague

By 'without using system("color hex")' do you still mean "works on all systems magically"?

Narue 5,707 Bad Cop Team Colleague

For ultimate portability you have two options:

  1. Don't use non-portable features
  2. Implement the non-portable feature for every target system

In other words, don't clear the screen and don't go full screen if you don't want to write a Windows-specific build, a Linux-specific, and a Mac-specific build.

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

You're not properly resetting between persistence iterations. For example, x doesn't get reset to 1.

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

i counted variables,consts,commas,references everything seems to be ok...

I see a missing const in your definition, but I think a bigger issue is that you're passing way too many parameters. If you find yourself passing more than three, there might be something wrong with your design.

Narue 5,707 Bad Cop Team Colleague

what do you mean by K?

He means that the iostream library takes up more space in the executable than the stdio library after compilation. It's not an unreasonable concern, but shouldn't be the only concern when choosing between iostream and stdio.

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. ;)

Narue 5,707 Bad Cop Team Colleague

a code in 'Let Us C' by Y.Kanetkar confused me since i am only a beginner

A lot of people mistakenly use %u to print the value of a pointer. The correct method is using %p and casting non-void pointers to void:

printf("Original address in x = %p\n", (void*)x);
printf("Original address in y = %p\n", (void*)y);
printf("Original address in z = %p\n", (void*)z);

there seem to be a lot of errors in the book

From a cursory reading of that book, it's total crap. You'll probably learn more bad habits than good ones.

Narue 5,707 Bad Cop Team Colleague

What is the use of (void *)?

The %p specifier expects a pointer to void (the generic pointer type in C). In cases where the address you want to print isn't already a pointer to void, a cast is used to make it so.

And why are the results in hexadecimal form? can we get them in decimal form too?

The display representation of addresses for %p is implementation-defined, you can't change it. If you really want decimal representation and don't mind breaking portability, you might use a decimal specifier and cast the pointer to a suitable type:

#include <stdio.h>

int main(void)
{
    int arr[] = {10,20,30,40,50,60};
    int i;
    
    for (i = 0; i < 6; i++)
        printf("%u\n", (unsigned)&arr[i]);
    
    return 0;
}

That's not likely to fail.

Narue 5,707 Bad Cop Team Colleague

Can you please RTFM?

Moschops commented: Harsh but fair :) +7
Narue 5,707 Bad Cop Team Colleague

i really need a GOOD socket tutorial

The #1 recommended tutorial is Beej's guide.

Narue 5,707 Bad Cop Team Colleague

Thanks but i can't install Linux on that machine.

GCC isn't restricted to Linux. Try the nuwen build of MinGW if you're on Windows, it's up to GCC 4.6.1. If you're on OSX, macports offers a recent build of GCC as well.

How about Visual Studio Express 2008?

True C++0x support starts with 2010 (stuff like long long was supported as an extension before), but the list of features is relatively short compared to GCC. Unfortunately, it doesn't seem like 2011 will be much better (still no variadic templates, for example).

Narue 5,707 Bad Cop Team Colleague

because Narue said "where an array is not converted to a pointer to its first element."..

It was a side note only. The general rule is that when an array is used, it's converted to a pointer to the first element. That's why things such as the following are allowed:

int a[10];
int *p = a; // No need to explicitly say &a[0]
void foo(int *p);

int a[10];

foo(a); // Fine, a and p are compatible types here
int a[] = {1,2,3,4,5};

cout << *(a + 2) << '\n'; // Non-modifying pointer arithmetic is OK

These are all value contexts, you're interested in the elements rather than the array object as a whole. Most uses of arrays fall under value context, which is why you'll occasionally hear confused programmers say that arrays and pointers are the same. That's because most of the time they can be used as if they were the same. However, there are three object contexts, where you truly do want to work with the array object rather than its elements (cases where arrays and pointers are not the same):

  • As an operand to the address-of operator (&). You want a pointer to an array, not a pointer to a pointer to the first element:
    int a[10];
    int (*p)[10] = &a; // Correct
    int **p = &a; // Incorrect, incompatible types
  • As an operand to the sizeof operator. You want the size of the array in bytes, not the size of a pointer:
    
           
NP-complete commented: useful info...:) +5
Narue 5,707 Bad Cop Team Colleague

There isn't a single compiler that supports all of C++0x at this point. I believe GCC (starting at 4.6 or 4.7) is the closest though, if you want to play with C++0x I'd go with GCC.

Narue 5,707 Bad Cop Team Colleague

malloc() and free() are declared in <stdlib.h>, you failed to include that header.

Narue 5,707 Bad Cop Team Colleague

Pointer arithmetic is not illegal. What is illegal is to perform arithmetic on unrelated pieces of memory. The pointer arithmetic was not a mistake; however I could have been more careful to code it as:

Go read the standard, dude. Addition of two pointers is not legal. Here, let me quote it for you: "For addition, either both operands shall have arithmetic type, or one operand shall be a pointer to an object type and the other shall have integer type." The code as originally posted attempts to add two pointers ( ok + block ), and thus is wrong.

If you wrote something different and it was translated incorrectly, that's not my problem; I'm commenting only on the code in this thread.

That is waaay beyond a simple readline.

Bullshit. That's about as basic as it gets for reading arbitrary length strings. Don't flatter yourself; any programmer with half a brain and marginal experience in C could easily write such a function, and probably has more than once. You're not special because you managed to resize a dynamic block of memory in the least imaginative way possible.

It's fine to boast an ego for fun, but don't let it get in the way of progress. Your post reeks of a bruised ego and childish behavior in the face of criticism. Nobody will think less of you if you make a mistake, but they most certainly will if you act like a brat after it's pointed out.

Narue 5,707 Bad Cop Team Colleague

It's no different from if you used an array. Say the array has 10 characters and you type "abcd". The array will contain those four characters, plus a newline and a null character, which means the last four elements will be garbage unless you went out of your way to initialize them:

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

int main(void)
{
    char buf[10];
    size_t i;
    
    /* Initialize to predictable garbage */
    for (i = 0; i < 10; i++)
        buf[i] = '~';
    
    printf("Enter 4 characters: ");
    fflush(stdout);
    
    if (fgets(buf, sizeof buf, stdin) != NULL) {
        for (i = 0; i < sizeof buf; i++) {
            if (isprint(buf[i]))
                printf("'%c'\n", buf[i]);
            else
                printf("[%d]\n", buf[i]);
        }
    }
    
    return 0;
}

Your memory will work the same way with malloc().

Narue 5,707 Bad Cop Team Colleague

if you check the ASCII table, '\0' is called NUL and has been named so because it has no resemblance with the NULL pointer.

This is a sticky area. Technically, '\0' has a numeric value of 0, which means it's valid as a null pointer constant, and thus equivalent to NULL. The difference is NULL may be cast as a pointer to void, which means the equivalency isn't mutual:

void *p = '\0'; /* Confusing, but valid */
char ch = NULL; /* Also confusing, but may not compile cleanly */

As far as naming, '\0' has been called NUL historically in an unofficial capacity, but as far as official terminology goes it's a representation for the "null character". NUL is mentioned in the standard only once in reference to the ASCII character set, and that reference is in a note unrelated to the null character. The correct name is "null character", but realistically you can call it whatever you want as long as the meaning is understood. ;)

Having said that, where I think Greywolf333 was wrong is that the compiler doesn't automatically appends a NUL at the end of the char array, if it isn't explicitly mentioned.

Correct. If you use an initializer list on an array of char, there's no implicit assumption that the array is being used as a string. That particular magic only happens if you initialize the array with a string literal:

char a[] = {'a','b','c'}; /* What you see is …
Narue 5,707 Bad Cop Team Colleague

so will unused memory contain null characters?

Not when allocated by malloc(). The unused memory will remain uninitialized.

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

Basically all you need the time.h library for is slowing things down enough to produce the effect of animation:

#include <iostream>
#include <ctime>

void pause_execution(double seconds)
{
    std::time_t start = std::time(0);
    
    while (std::difftime(std::time(0), start) < seconds)
        ;
}

int main()
{
    std::cout << "Paused" << std::flush;
    
    for (int i = 0; i < 10; i++) {
        pause_execution(1);
        std::cout << ". " << std::flush;
    }
    
    std::cout << "\nDone\n";
}

Note that a busy loop as shown in pause_execution() is an exceptionally bad design, but standard C++ doesn't presently offer a way of putting the current thread of execution to sleep such that other threads can make use of the downtime. However, for educational purposes, a busy loop is fine. Just be aware that it's very antisocial in a multitasking system.

Narue 5,707 Bad Cop Team Colleague

Use fgets instead , since scanf is not considered safe.

scanf() is perfectly safe when used correctly. The problem is things like %s without a field width where the programmer has no clue that it's a buffer overflow waiting to happen.

If scanf() is so unsafe, then why is the recommended alternative a combination of fgets() and sscanf()? The only major difference between scanf() and sscanf() is the source of characters. Further, if you read those links, you'll find that the "problems" with scanf() have to do with variations of the following:

  • Not understanding how scanf() manages whitespace
  • Not understanding how the %s specifier works

While I agree that an intuitive interface and semantics are both important, ignorance of scanf() isn't the fault of scanf(). Were I in a perverse mood, I'd argue that fgets() also has problems because beginners are often confused about how newlines are managed.

Narue 5,707 Bad Cop Team Colleague

so it makes sense to send a block_size as parameter into the function

In my opinion, no. The block size is an implementation detail that shouldn't affect the interface. Rather, simple_getline() should choose one of the several automatic growth methods commonly used in string libraries.

but if we allocated memory for next 10 character , but had read only 5 ones - what will we have in memory for last 5 characters in *result after returning to the main() func or we won't have this not occupied memory at all in *result ?

The memory will still be there, just unused because fgets() properly terminates the string with '\0'. It's no different from typing 5 characters where the buffer is an array of 10.

Narue 5,707 Bad Cop Team Colleague

as i see the dimension of block_size doesn't influence on function execution speed. am i right?

The block size determines how many allocations are made. If the block size is too small, you'll call realloc() an excessive number of times. If the block size is too big, you'll waste memory. The idea is to choose a block size that minimizes both realloc() calls and memory usage. Since dynamic allocation is a relatively expensive operation, block size most certainly influences the performance of the function.

Narue 5,707 Bad Cop Team Colleague

as i see - this original auther code won't work at all (even without bug about which line we spoke earlier =

You're correct. While addition of pointers is illegal, even if you fixed it, there's still a logic error in that line.

Narue 5,707 Bad Cop Team Colleague

I'm getting a error msg: 'cannot convert sprites* to sprite_data** in assignment'

Your name choices are confusing you. blocks is defined as being a pointer to sprite , which the error suggests is a typedef for a pointer to sprite_data . This is very different from the sprites typedef, which is a synonym for the structure that owns the blocks member.

What you need to do is allocate memory for the correct type:

sprite *temp_ = (sprite*)realloc(game_data.blocks, game_data.numb_brick_sprites * sizeof(sprite));
Narue 5,707 Bad Cop Team Colleague

especially this (may be it's bug) =

block  = ok +block -result -1;

Looks like a bug to me. Addition of pointers is both nonsensical and illegal in C. I see what the author was going for, but it seems especially awkward. I'd rather just keep a running count of the string length and set block to the current null character on each iteration. It's much simpler that way:

char *simple_readline(void)
{
    const size_t block_size = 5;
    
    char *result, *block, *temp;
    size_t size = block_size;
    size_t n = 0;

    result = block = (char*)malloc(size);
    
    if (!result)
        return NULL;
    
    *result = '\0';

    for (;;) {
        if (fgets(block, block_size, stdin) == NULL)
            break;

        n += strlen(block);
        
        if (result[n - 1] == '\n')
            break;

        size += block_size;
        temp = (char*)realloc(result, size);
        
        if (temp == NULL)
            break;

        result = temp;
        block = result + n;
    }

    if (result[0] == '\0') {
        free(result);
        result = NULL;
    }

    return result;
}

If the result is null

result will never be null on the bolded lines. Prior to the loop, result is initialized using malloc(), and there's a test for failure which returns from the function. Inside the loop, result is never reset if realloc() fails.

(why do we need
next piece ) =

if (!(*result))
{
    free( result );
    result = NULL;
}

If result[0] is '\0' then that means the first call to fgets() failed. Rather than risk that case being mistaken as any kind of success (a successful call will …

vedro-compota commented: you're > than "great man" Narue) so many help/// +3
Narue 5,707 Bad Cop Team Colleague

Links in your signature do not by themselves count as spam. It's only if you post with the sole intention of promoting your signature that they count as spam. This is a difficult pattern to nail down accurately, so if you have links in your signature, you might find otherwise innocent posts deleted as spam.

Narue 5,707 Bad Cop Team Colleague

Forgive me if I'm confused, but from the look of your code, you should be well aware of how to calculate the mean from an array (I assume you're talking about the arithmetic mean):

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

#define N 50

double mean(int a[], int n)
{
    int sum = 0;
    
    for (int i = 0; i < n; i++)
        sum += a[i];
        
    return (double)sum / n;
}

double standard_deviation(int a[], int n, double mean)
{
    double variance = 0;
    
    for (int i = 0; i < n; i++) {
        int diff = a[i] - mean;
        
        variance += (diff * diff);
    }
    
    variance /= n;
    
    return sqrt(variance);
}

int main(void)
{
    int a[N];
    
    srand((unsigned)time(NULL));
    
    for (int i = 0; i < N; i++)
        a[i] = rand() % N;
    
    double avg = mean(a, N);

    printf("Mean:               %f\n", avg);
    printf("Standard Deviation: %f\n", standard_deviation(a, N, avg));
}

I also threw in the standard deviation, because that tends to go hand in hand with the mean.

Narue 5,707 Bad Cop Team Colleague

This forum was designed to let lots of people of many different abilities and backgrounds gain advice and experience from other people who are either more advanced or work in different fields.

Funny, I thought the Geeks' Lounge was for chatting about anything. :icon_rolleyes:

It was not designed for people who may or may not be more advanced in programming and development to try and make people feel bad about themselves whilst simultaneously boosting a pathetic forum posters shattered ego from a complete lack of social credibility. I would suggest you take a while to reflect on the sort of person you are and whether you are actually an asset to this forum.

The hypocrisy is strong with this one.

Netcode commented: me too +0