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().
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().
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:
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;
}
Use the disk you originally installed from. If you don't have it, upgrade to one of the Express versions (they're free).
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
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.
I see. And when was the assignment first given to you?
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;
learning comes from the mistakes
Hopefully one day you'll learn that trying to define undefined behavior is a mistake. Good day.
Two hours, eh? Just out of curiosity, how long have you been working on this assignment?
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.
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.
The expression is undefined and can have any result, please stop trying to analyze it.
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.
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.
If that's the full code then you're missing definitions for all of the member functions.
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.
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.
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.
system("clear")
is the equivalent to system("cls")
on both Linux and OSX.
By 'without using system("color hex")' do you still mean "works on all systems magically"?
For ultimate portability you have two options:
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.
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);
}
You're not properly resetting between persistence iterations. For example, x doesn't get reset to 1.
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
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.
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.
is this any better?
No.
or should i just follow the 'Starting C' section?
I'd suggest a good book.
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. ;)
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.
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.
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).
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):
int a[10];
int (*p)[10] = &a; // Correct
int **p = &a; // Incorrect, incompatible types
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.
malloc() and free() are declared in <stdlib.h>, you failed to include that header.
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.
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().
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 …
so will unused memory contain null characters?
Not when allocated by malloc(). The unused memory will remain uninitialized.
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.
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:
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.
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.
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.
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.
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));
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 …
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.
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.
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.