This question already has an answer here:
Trouble implementing isalpha
(1 answer)
Closed 2 years ago.
Addmitedly and obviously I am new to this coding thing. I'm enjoying working it out but I feel stuck on this problem. Any guidance would be appreciated!
I am attempting to count all of the letters of a particular text from the user, but my counter (i) comes out as 1 when I run the program regardless of input. Below is my code.
#include <stdio.h>
#include <cs50.h>
#include <string.h>
#include <ctype.h>
int main(void)
{
string a = get_string("Text: \n"); // Get input
for (int i = 0, n = strlen(a); i < 1; i++) //Set counter for number of letters
{
if isalpha(a[i]). // Count only if character is a letter
{i++;}
printf("%i\n", i); // print counter
}
}
Again, any guidance (in as simple of terms as possible!) is appreciated as I've been trying to figure this out for two days.
So i've edited your code a bit to where it would make sense and I'll try to explain why I changed some stuff. I'm a bit rusty with c/c++ so I'd appreciate if anyone can point out what I'm wrong with.
so here's a snippet of code that would count the number of letters.
#include <stdio.h>
#include <string.h>
#include <ctype.h>
int main(void)
{
char a[] = "test";
int n = strlen(a);
int i = 0;
for (i = 0; i < n; i++) //Set counter for number of letters
{
}
printf("%i\n", i); // print counter
}
So with your code a couple things.
(1) for (int i = 0, n = strlen(a); i < 1; i++)
A for loop looks like this
for(where you start your loop at ; where you stop; count up or down)
so with your code I did this:
for (i = 0; i < n; i++) //Set counter for number of letters
where we start i with 0, we go till i hits n and we count up
now you can do this if it makes more sense:
for (i = 0; i < n; i++) //Set counter for number of letters
{
i++;
}
but they'll both do the same thing (I think) since we are iterating i, but I do think this is better due to readability.
(2) printf("%i\n", i); // print counter
As you probably know this prints out the number of letters and you had this in your for loop and that's fine when you're doing something like a countdown. So if we put it in the for loop it would look like this:
for (i = 0; i < n; i++) //Set counter for number of letters
{
printf("%i\n", i); // print counter
}
where it would print out 0 1 2 3 (Remember arrays always start at 0), so by keeping it outside of the for loop, you just have a counter for how many times 'i' was iterated in the for loop, so you get 4.
in your for loop, the i < 1 part means you will loop while i is smaller than 1, it is initialised to 0 on the first loop, so it runs (and counts to 1), and then at the end of the loop, i increments to 1, and therefore the loop will not run again. You need to put i < n instead of i < 1. and you also need to change the counter to j (or another variable), as mentioned in the comments.
Related
I'm currently going through CS50 through edx and doing problem set 1, Mario.
The objective is to create a print out using pound signs. With the help of some videos I got the code for the first one but I don't understand fundamentally how the math works/ what the computer is understanding.
So I figure if I don't learn I'm crippling myself later.
if n= 5
Then i has 1 added to it until it is not less than 5 which means 5 times yes?
Take a look at this line for the space loop >
for (int j = 0; j < n -1 - i; j++)
If n is 5, then it ends up being j(0) < 3...
So why on the first line are there four spaces and not three spaces?
#include <cs50.h>
#include <stdio.h>
int main(void)
{
int n;
do
{
n = get_int("Pyramid Height: ");
}
while (n < 0 || n >= 24);
//print out this many rows
for (int i = 0; i < n; i++)
{
for (int j = 0; j < n -1 - i; j++)
{
printf(" ");
}
// print out this many columns
for (int j = 0; j < i + 2; j++)
{
printf("#");
}
printf("\n");
}
}
I get the correct pyramid yet i don't understand the logic behind the spacing and prints
if n=5 then n-1-j would be equal 5-1-0 i.e. 4 for the first time executing the loop that is the reason why you are seeing four spaces. The first loop condition should be n-2-j if you want the number of spaces to be three because total no of columns is 5 and the pounds expected in the first row are 2, therefore you should be subtracting 2 from n.
That looks way too complicated.
Here's a simple version I whipped up:
#include <stdio.h>
int main(void) {
int height = 5;
char blocks[height];
memset(blocks,'#',height);
for(int i=0; i<height; ++i)
{
printf("%*.*s\n", height, i+1, blocks );
}
return 0;
}
Output:
Success #stdin #stdout 0s 9424KB
#
##
###
####
#####
Let us try to figure out the pattern here. Like for the left pyramid if the height of the pyramid is 8, check the pattern of spaces and hashes from top to bottom. In this case we need 8 lines, every line has same characters and no of spaces decreases and no of hashes increases from top to bottom.
Now we have the pattern for the left half, the right half is the same, mirror image. So now we can write down the loop as we know the no of spaces and hashes from top to bottom. In programming we need to understand the underlying principle. Plug in the code afterwards becomes easy.
#include <cs50.h>
#include <stdio.h>
int main(void)
{
int h;
do
{
h = get_int("Pyramid height: ");
}
while (h<1 || h>8);
int n = 8, i, j;
for (i=0; i<h;++i)
{
// left half
for (j=0;j<h-1-i;++j)
printf(" ");
for (j=0;j<i+1;++j)
printf("#");
// two spaces in middle
printf(" ");
// right half, we have omitted the space code as it is not required.
for (j=0;j<i+1;++j)
printf("#");
printf("\n");
}
return 0;
// What I mean by this is shown by my example:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int i;
int a;
for (a = 0;a <10;a ++) {
i = (rand()%10)+1; // generates a number from 1-10
printf("%d\n", i);
}
// I would like for the loop to generate a number that gives a number that was not generated before. For example, an output such as:
1,3,6,2,8,9,4,10,5,7
instead of:
3,9,10,3,7,9,2,7,10,1
In other words, I would like no copies.
You obviously don't just want no copies, but you want every number in a given set exactly once. This is, as commented by Robert, similar to shuffling a deck of cards. You don't have "decks" in C, but you can model one as an array:
int deck[] = {1,1,1,1,1,1,1,1,1,1};
This should represent 10 different "cards" (identified by their index in the array), each available one time. Now, just write code that "draws" cards:
int i = 0; // starting point for searching for the next card to draw
for (int n = 10; n > 0; --n) // how many cards are left
{
int skip = rand() % n; // randomly skip 0 .. n cards
while (1)
{
if (deck[i]) // card still available?
{
if (!skip) break; // none more to skip -> done
--skip; // else one less to skip
}
if (++i > 9) i = 0; // advance index, wrapping around to 0
}
deck[i] = 0; // draw the card
printf("%d\n", i+1); // and print it out
}
of course, seed the PRNG (e.g. srand(time(0))) first, so you don't get the same sequence every time.
The idea shown in the question is to print numbers within a range, without repetition. Here is one way to do that, by putting each value into an array and swapping its elements around.
A variation could be that you don't want to use all the possible numbers, in that case just change PICKED.
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define ARRLEN 10
#define PICKED 10
int main(void) {
int array[ARRLEN];
srand((unsigned)time(NULL)); // seed the PRNG
for(int i = 0; i < ARRLEN; i++) { // generate the numbers
array[i] = i + 1;
}
for(int i = 0; i < ARRLEN; i++) { // shuffle the array
int index = rand() % ARRLEN;
int temp = array[i];
array[i] = array[index]; // by randomly swapping
array[index] = temp;
}
for(int i = 0; i < PICKED; i++) { // output the numbers
printf("%d ", array[i]);
}
printf("\n");
}
Program output:
9 8 4 5 1 10 7 3 6 2
The library's PRNG is not very random, but for many cases that is not important. If it is, better algorithms are available.
I apologize in advance for the length of the code and how tedious it may be to follow. I am trying to break a number down into individual digits and get the factorial of each one. I have successfully done that (with the help of paxdiablo) but I want to do this all the way from 99999 to 0. In order to do that I have placed all of the code in a loop starting indx at 99999 and decreasing value until it reaches 1. The reason I am trying to do this is because I need to compare the sum of the factorial of each individual digit to the number and if they are equal then I have a match. The program runs and the first run for the number 99999 works perfectly fine but the next loop SHOULD be 99998 and do the exact same thing but instead the next number is 4. I have no idea why it would do this. Any help would be appreciated.
#include <stdio.h>
#include <stdlib.h>
int main()
{
int num;
int indx;
int fact = 1;
int individualDigit[50];
int length;
for(indx = 99999; indx > 0; indx--)
{
num = indx;
for (length = 0; num > 0; length++, num /= 10)
{
individualDigit[length] = num % 10;
}
printf ("Digit count = %d, digits =", length);
for (indx = length - 1; indx >= 0; indx--)
{
printf (" %d", individualDigit[indx]);
}
for (indx = 0; indx < length; indx++)
{
while (individualDigit[indx] > 0)
{
fact = fact * individualDigit[indx];
individualDigit[indx]--;
}
printf("\n%d ", fact);
fact = 1;
}
printf("\n");
}
return 0;
}
The value in "indx" is being used by multiple for loops. The line
for (indx = 0; indx < length; indx++)
increments indx back up to 4, which is the value used by your outer loop. Just use some new variables to count the different loops
This seems like a homework question and your code quality seems to confirm that so I'm hesitant to write you actual code but I'll give you a few pointers.
As #Cody Braun said above your index variable is getting overwritten in line 23 where you calculate the factorial.
There is a much more efficient way to calculate factorials using dynamic programming
I don't know if you just didn't want to do it in the post but learning how to properly format your code will help you catch these errors quicker and keep yourself form making them. As well as make it easier for others to read your code.
Cheers
My program should take a number from the user, and find the two numbers in an array such that the sum of their squares equals the user input squared. However, I'm having trouble doing this, as well as understanding all the errors I'm getting.
Here's my current attempt:
#include <stdio.h>
int numberaa;
scanf("%d",&numberaa);
int main()
{
int i,j;
int array[9] = {2,-4,6,3,9,0,-1,-9};
for (i = 0; i <= 8; i++)
for (j = 0; j <= 8; J++0)
firstone==i*i
secondone==j*j
if {
firstone+secondone=numberaa;
printf("The Numbers are %d and %d",j,i,numberaa);
return 0
};
Change
firstone+secondone=numberaa;
to
numberaa = firstone + secondone;
Ah! You need to grab a basic C book. For this time I am posting a correct code for you. Hope you will learn something.
#include <stdio.h>
int main()
{
int i,j;
int array[9] = {2,-4,6,3,9,0,-1,-9};
int numberaa;
scanf("%d",&numberaa);
for (i = 0; i <= 8; i++){
for (j = 0; j <= 8; J++0){
firstone = i*i
secondone = j*j
if(numberaa == firstone + secondone)
printf("The Numbers are %d and %d",j,i,numberaa);
}
}
return 0
}
You need to read through at least the introductory chapter of a book on C and work through the examples. That means typing them out (no, don't copy and paste), compiling them, and running them to understand what makes them work and what breaks them.
When you write your own code, always compile with warnings enabled, e.g. gcc -Wall -o my_executable_name my_code.c, and pay attention to the line numbers referenced in compiler errors and warnings.
I'll point out some locations of errors in your code below:
#include <stdio.h>
int numberaa; // Currently you're declaring this as a global. NO! not what you want.
scanf("%d",&numberaa); // This isn't going to happen out here. NO! NO NO NO!
int main() // Specify your parameters. int main(void)
{
int i,j;
int array[9] = {2,-4,6,3,9,0,-1,-9}; // why specify an array of 9 but store just 8 elements??
for (i = 0; i <= 8; i++) // These are the correct limits for array[9].
for (j = 0; j <= 8; J++0) // j and J are not the same. What is J++0 ????!! Also, read about "blocks" and try a for-loop example with more than one line.
firstone==i*i // WTF?? Have you even tried to compile this?
secondone==j*j // See line above.
if { // Likewise
firstone+secondone=numberaa; // Likewise again.
printf("The Numbers are %d and %d",j,i,numberaa); // How many formatting flags does your first argument have, and how many are to be inserted?
return 0 }; // again, have you tried to compile this?
Short version:
Semicolons
Assignment vs. equality
Scope of variables
Blocks, brace usage
syntax of if statements
You also aren't squaring the user input.
Efficiency: you only need to calculate firstone = i * i once for each i value, so take it outside the j loop.
Hello friends I need your help.
My program is such an array size 1000 where the numbers should be between 0-999. These numbers should be determined randomly (rand loop) and the number must not be repeated. Would be considered the main part, I have to count how many times I used rand().
My idea is that: one loop where it initializes all the 1000 numbers, and if in this loop they check whether the number appears twice, if the number appears twice is set it again until that not appear twice (maybe this is not the best way but ...)
It is my exercise (Here I need your help)-
#include <stdio.h>
#include <stdlib.h>
int main()
{
int const arr_size = 1000;
int i, j, c;
int arr[arr_size];
int loop = 0;
for(i = 0; i<arr_size; i++)
{
arr[i] = rand() % 1000;
loop++;
if (arr[i] == arr[i - 1])
{
arr[i] = rand() % 1000;
loop++;
}
}
printf("%d\n",loop);
}
So if anyone can give me advice on how I can make it work I appreciate your help.
Thanks.
As suggested, shuffling the set will work but other indirect statistical quantities might be of interest, such as the distribution of the loop variable as a function of the array index.
This seemed interesting so I went ahead and plotted the distribution of the loop as a function of the array index, which generally increases as i increases. Indeed, as we get near the end of the array, the chance of getting a new random number that is not already in the set decreases (and hence, the value of the loop variable increases; see the code below).
Specifically, for an array size = 1000, I recorded the non-zero values generated for loop (there were around 500 duplicates) and then made a plot vs the index.
The plot looks like this:
The code below will produce an array with the unique random values, and then calculate the value for loop. The loop values could be stored in another array and then saved for later analysis, but I didn't include that in the code below.
Again, I'm not exactly sure this fits the application, but it does return information that would not necessarily be available from an approach using a shuffle algorithm.
NOTE: some folks expressed concerns about how long this might take but it runs pretty quick, on my 2011 Macbook Pro it took a about a second for an array size of 1000. I didn't do a big-O analysis as a function of the array size, but that would be interesting too.
NOTE 2: its more elegant to use recursion for the numberInSet() function but it seemed best to keep simple.
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <stdbool.h> /* If C99 */
const int ARR_SIZE = 1000;
/* Check if the number is in the set up to the given position: */
bool numberInSet(int number, int* theSet, int position);
int main()
{
int* arr = malloc(sizeof(int)*ARR_SIZE);
srand((unsigned int)time(NULL));
/* Intialize array with rand entries, possibly duplicates: */
for(int i = 0; i < ARR_SIZE; i++)
arr[i] = rand() % ARR_SIZE;
/* Scan the array, look for duplicate values, replace if needed: */
for(int i = 0; i < ARR_SIZE; i++) {
int loop = 0;
while ( numberInSet(arr[i], arr, i-1) ) {
arr[i] = rand() % ARR_SIZE;
loop++;
}
/* could save the loop values here, e.g., loopVals[i] = loop; */
}
for(int i = 0; i < ARR_SIZE; i++)
printf("i = %d, %d\n",i,arr[i]);
/* Free the heap memory */
free(arr);
}
bool numberInSet(int number, int* theSet, int position) {
if (position < 0)
return false;
for(int i = 0; i <= position; i++)
if (number == theSet[i])
return true;
return false;
}
To make sure all random number you get in the same program are different, you must seed once the random generator:
srand (time(NULL)); //seed the random generator
//in the loop, rand will use the seeded value
rand() % 1000