Im in the process of learning C and the basis of the class is C primer plus(6th edition). We use Eclipse as an IDE.
For an project we have to create to arrays. One array that takes numbers in a loop and another array that display the cumulative value. So if array 1 has values 1, 5 and 3(out of 10 inputs total) then the resulting input in array 2 should be 9(on the 3th input because of the 3 inputs in array 1).
Im having trouble getting started the right way - anyone here has ideas how I could proceed?
So far I have this for starters but forgive me for it it very weak:
#include <stdio.h>
#include <stdlib.h>
#define SIZE 10
void doublearrays (double usernumber);
int main(void)
{
double usernumbers = 0.0;
int loop1 = 1;
while(loop1)
{
printf("Type numbers as doubles. \n");
fflush(stdout);
loop1 = scanf("%lf", &usernumber);
if(loop1)
{
doublearrays(usernumber);
}
}
return 0;
}
All the text in a homework assignment shall be read:
For a project we have to create two arrays... 10 inputs total...
Why on earth do not you declare them?... You already have defined SIZE so
double usernumbers[SIZE];
double cumulnumbers[SIZE];
Next do yourself a favour and handle one problem at a time:
One array that takes numbers in a loop...
Ok, so write a loop up to 10 reading floats directly into the array and note how many numbers were received
int n;
for(n=0; n<SIZE; n++) {
if (scanf("%lf", &usernumbers[n]) != 1) break;
}
// ok we now have n number in the first array
Let us go on
and another array that display the cumulative value.
Ok cumul is initially 0. and is incremented on each value from the first array:
double cumul = 0.;
for(int i=0; i<n; i++) {
cumul += usernumbers[i];
cumulnumbers[i] = cumul;
}
(your current code isn't what you need... delete it and then...)
anyone here has ideas how I could proceed?
Well the first step would be to actually define some arrays.
double input[SIZE];
double cum[SIZE];
The next step would be a loop to read input.
for (int i = 0; i < SIZE; ++i)
{
if (scanf("%lf", &input[i]) != 1)
{
// Input error - add error handling - or just exit
exit(1);
}
}
The next step is to add code for calculating the the cumulative value.
I'll leave that for you as an exercise.
The last step is to print the array which I also will leave to you as an exercise.
The straight forward way of doing this, which would also use two arrays and a loop construct would be to create something like this.. I've changed the doubles to integers. (and i am also ignoring any errors from scanf()).
#include <stdio.h>
#include <stdlib.h>
#define SIZE 10
static void
print_array(int *arr, const char *arr_name)
{
int i;
printf("%s = [");
for (i = 0; i < SIZE; i++)
printf("%d%s", arr[i], i < SIZE -1 ? ",":"");
printf("]\n");
}
int main(int argc, char **argv)
{
int i;
int input[SIZE];
int cumsum[SIZE];
for (i = 0; i < SIZE; i++)
{
int _input;
printf("Give me numbers!\n");
fflush(stdout);
scanf("%d", &_input); /* assuming integer */
input[i] = _input;
cumsum[i] = i > 0 ? cumsum[i-1] + _input : _input;
}
print_array(input, "input");
print_array(cumsum, "cumulative");
return 0;
}
or If you'd like to play around with pointers and have a bit more compact version.. perhaps this could be something to study to help you understand pointers, it does the same thing as my code above
#include <stdio.h>
#include <stdlib.h>
#define SIZE 10
static int data[SIZE*2];
int main(int argc, char *argv[])
{
int *input_p = &data[0];
int *cumsum_p = &data[0] + SIZE;
for (; input_p != &data[0] + SIZE; input_p++, cumsum_p++)
{
printf("Give me numbers!\n");
scanf("%d", input_p);
*cumsum_p = input_p == &data[0] ? *input_p : *(cumsum_p-1) + *input_p;
}
}
Related
Given an integer n, write a C program to count the number of digits that are in the same position after forming an integer m with the digits in n but in ascending order of digits. For example, if the value of n is 351462987 then value of m will be 123456789 and digits 4 and 8 will be in the same position.
This is my code:
#include<stdio.h>
void bubble(int a[],int length)
{
for (int i=0;i<length;i++)
{
for (int j=0;j<length;j++)
{
if (a[j]>a[j+1])
{
int t=a[j];
a[j]=a[j+1];
a[j+1]=t;
}
}
}
}
int check(int a[],int b[],int length)
{
int count=0;
for (int i=0;i<length;i++)
{
if (a[i]==b[i])
{
count=i;
break;
}
}
return count;
}
int length(int n)
{
int l;
while (n!=0)
{
n=n/10;
l++;
}
return l;
}
void main()
{
int n,arrn[100],temp[100];
scanf("%d",&n);
int l=length(n);
for (int i=0;i<l;i++)
{
arrn[l-i-1]=n%10;
temp[l-i-1]=arrn[l-i-1];
n=n/10;
}
bubble(temp,l);
int c=check(arrn,temp,l);
printf("%d",c);
}
I am able to compile the code but when I execute it it takes a long time only to show segmentation fault.
Easy answer, use a debugger.
Here are some problem with your code:
In length function, l is not initialized and as such can have an arbitrary initial value. In your case, you probably want to start at 0.
int l = 0;
Your check function probably don't do what you want. As written count is not a count but the index of a position where numbers match. As there is a break statement in the block, the loop will exit after the first match so the return value would be the position of the first match or 0 if no match was found.
Your bubble function goes one item too far when i is equal to length - 1 as you access item a[j + 1] in the inner loop which is out of bound. In that case, it is simpler to start at 1 instead of 0 and compare item at index i - 1 with item at index i.
Some extra notes:
It is recommended to add whitespace around operators and after a comma separating multiple declarations to improve readability. Here are some example of lines with improved readability.
int n, arrn[100], temp[100];
int count = 0;
for (int i = 0; i < length; i++)…
if (a[i] == b[i])…
arrn[l - i - 1] =n % 10;
temp[l - i - 1] = arrn[l - i - 1];
int check(int a[], int b[], int length)
Instead of writing multiple functions at once, you should write one function and ensure it works properly. By the way, the loop that split a number into digits could also be a function.
Try the function with small number (ex. 12 or 21)
Use better name for your variable. arrn and temp are not very clear. original and sorted might be better.
Your length function has a very obvious bug in it. What value does l start with? You don't initialise it so it could start with any value and cause undefined behaviour. You should set it to 0.
int length(int n)
{
int l = 0;
while (n!=0)
{
n=n/10;
l++;
}
return l;
}
Personally, I wouldn't be sorting or reading it into an int - to enable handling leading zeros in the digit string. For example:
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#define MAXNUMLEN 200
int main(void)
{
int i, j, l, x=0;
char numin[MAXNUMLEN], numout[MAXNUMLEN];
int digits[10]={0};
printf("enter a string of digits: " );
fgets(numin, sizeof(numin), stdin);
printf("\nsaw : %s", numin );
// walk string once, counting num of each digit present
l=strlen(numin);
for(i=0; i<l; i++) {
if( isdigit(numin[i]) ) {
int d = numin[i] - '0'; // char digit to int digit
digits[d]++;
}
}
// for each digit present, write the number of instances of the digit to numout
for( i=0; i<10; i++ ) {
for(j=0; j<digits[i]; j++)
numout[x++] = '0'+i; // int digit back to char digit
}
numout[x]='\0'; // terminate string
printf("sorted: %s\n", numout );
}
Sample run:
watson:digsort john$ ./ds
enter a string of digits: 002342123492738234610
saw : 002342123492738234610
sorted: 000112222233334446789
watson:digsort john$
I am writing a code which will print 5 unique and random strings from an array of 10 strings. But my code doesn't print it uniquely, there are always some repetitions.
Here is my code, can anyone suggest how to make it print unique?
#include<stdio.h>
#include<stdlib.h>
#include<math.h>
void main(void){
char arr[10][10]={"abc","def","ghi","klm","nop","qrs","tuv","wxy","zab","cde"};
int i=0,j=0;
srand(time(0));
for(i=0;i<5;i++){
j=rand()%10;
printf("%d\n",j);
}
}
Just remember idices that have already been printed out:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
int main()
{
char arr[10][10] = {"abc","def","ghi","klm","nop","qrs","tuv","wxy","zab","cde"};
int i = 0, j = 0;
int done[10] = { 0 };
srand(time(0));
for (i = 0; i < 5; ++i)
{
do
{
j = rand()%10;
}
while (done[j] == 1);
done[j] = 1;
printf("%s\n", arr[j]);
}
return 0;
}
Your rand() function may evaluate to the same string index multiple times. There are different ways to resolve that. Most of them will be a take off on bit vector approach. You can create a Boolean array and initialize it to false. Whenever a number is printed, you can change the element in the Boolean array for that index to true. If an element is selected, you can check in the Boolean array if it has already been printed. If yes, you can regenerate the random number, or move to the next unprinted element, making sure that the corresponding Boolean entry is changed to true when you print that element.
Your random function gives the repetition, e.g. your dice throw '3' two time out of 4 throws.
What you could do to make it simple, create an array [0..9],
and let the random function swap a[i] with a[j].
Then you get a random permutation. Take the first 5 elements of the permutated array.
#include<stdio.h>
#include<stdlib.h>
#include<math.h>
#include <time.h>
int main(){
char arr[10][10]={"abc","def","ghi","klm","nop","qrs","tuv","wxy","zab","cde"};
int found[10] = { 0 };
int i = 0,j = 0;
srand(time(NULL));
for(i = 0; i < 5; i++){
j = rand() % 10;
while(1){
if(!found[j]) break;
j = rand() % 10;
}
found[j] = 1;
printf("%s\n", arr[j]);
}
return 0;
}
So all I'm trying to do is take an input from the user of how many cards to use and then randomly assign each card to a different index in an array. I'm having extensive issues getting the rand function to work properly. I've done enough reading to find multiple different ways of shuffling elements in an array to find this one to be the easiest in regards to avoiding duplicates. I'm using GCC and after I input the amount of cards I never get the values from the array back and if I do they're all obscenely large numbers. Any help would be appreciated.
#include <time.h>
#include <stdlib.h>
#include <stdio.h>
void main(){
srand(time(NULL));
int d, c, i, z, l, r;
printf("Enter the deck length: ");
scanf("%d\n ", &c);
int deck[c];
int swap[c];
z = c;
for(l=0; l<c; l++){
swap[l] = l;
}
for(i=z; i=0; i--){
r = rand() / i
deck[i] = swap[r];
for(r; r=(c-1); r++){
swap[r] = swap[(r+1)];
}
}
for(d = 0; d < c; d++){
printf("%d ", deck[d]);
}
return;
}
I can spot one major problem here:
for(i=z; i=0; i--)
^^^
This loop will never execute since you are using assignment(=) and setting i to 0 therefore the condition will always be false, although using equality(==) will still be false in this case, you probably want:
for(i=z; i!=0; i--)
This means you will be using deck unitialized which is undefined behavior. Once you fix that you have a similar problems here:
for(r; r=(c-1); r++){
main has to return int and your return at the end needs to provide a value.
Turning on warning should have allowed you to find most of these issues, for example using -Wall with gcc gives me the following warning for both for loops:
warning: suggest parentheses around assignment used as truth value [-Wparentheses]
Note, see How can I get random integers in a certain range? for guidelines on how to use rand properly.
You basically need to be able to generate 52 numbers pseudo-randomly, without repeating. Here is a way to do that...
First, loop a random number generator 52 times, with a method to ensure none of the random numbers repeat. Two functions in addition to the main() will help to do this:
#include <ansi_c.h>
int NotUsedRecently (int number);
int randomGenerator(int min, int max);
int main(void)
{
int i;
for(i=0;i<52;i++)
{
printf("Card %d :%d\n",i+1, randomGenerator(1, 52));
}
getchar();
return 0;
}
int randomGenerator(int min, int max)
{
int random=0, trying=0;
trying = 1;
while(trying)
{
srand(clock());
random = (rand()/32767.0)*(max+1);
((random >= min)&&(NotUsedRecently(random))) ? (trying = 0) : (trying = 1);
}
return random;
}
int NotUsedRecently (int number)
{
static int recent[1000];//make sure this index is at least > the number of values in array you are trying to fill
int i,j;
int notUsed = 1;
for(i=0;i<(sizeof(recent)/sizeof(recent[0]));i++) (number != recent[i]) ? (notUsed==notUsed) : (notUsed=0, i=(sizeof(recent)/sizeof(recent[0])));
if(notUsed)
{
for(j=(sizeof(recent)/sizeof(recent[0]));j>1;j--)
{
recent[j-1] = recent[j-2];
}
recent[j-1] = number;
}
return notUsed;
}
Here are two functions below that compile perfectly but I seem to be getting a weird error with the very first inputted integer. I have tried debugging in GDB but when it's only the first inputted value that is having this weird error, then it makes things complicated.
#include <stdio.h>
#include "Assg9.h"
#include <stdlib.h>
#include <assert.h>
#include <math.h>
void getPrimes(int usernum, int* count, int** array){
(*count) = (usernum - 1);
int sieve[usernum-1], primenums = 0, index, fillnum, multiple;
for(index = 0, fillnum = 2; fillnum <= usernum; index++, fillnum++){
sieve[index] = fillnum;
}
for (; primenums < sqrt(usernum); primenums++)
{
if (sieve[primenums] != 0){
for (multiple = primenums + (sieve[primenums]); multiple < usernum - 1; multiple += sieve[primenums])//If it is not crossed out it starts deleting its multiples.
{
if(sieve[multiple]) {
--(*count);
sieve[multiple] = 0;
}
}
}
}
int k;
for (k = 0; k < usernum; k++)
if (sieve[k] != 0)
{
printf("%d ", sieve[k]);
}
*array = malloc(sizeof(int) * (usernum +1));
assert(array);
(*array) = sieve;
}
void writeToOutputFile(FILE *fpout, const int *array, int n, int count){
int i;
fprintf(fpout, "There are %d prime numbers less than or equal to %d \n", count, n);
for(i = 0; i < count; i++)
{
if(*(array + i) != 0){
fprintf(fpout, "%d ", *(array + i));
}
}
}
Our Output:
Please enter an integer in the range 2 <-> 2000 both inclusive: 2
2 32664
Do you want to try again? Press Y for Yes and N for No: y
Please enter an integer in the range 2 <-> 2000 both inclusive: 2
2
Do you want to try again? Press Y for Yes and N for No: n
Good bye. Have a nice day
Expected output should obviously just display 2. This is the case for any integer from 2-2000 for the very first inputted integer. The very last, or last 2, prime numbers print very large numbers, sometimes even negative numbers. I have no clue why, but after the first inputted value everything works perfectly. Tried debugging this with GDB like crazy but with no luck. Would really appreciate someone's help for this bizarre error
You aren't initializing the sieves array to 0s. So you're looping from 0 to usernum-1, printing out every number that isn't a 0. Since you didn't initialize the array, the 2nd element is a random value and is being printed out
This code is a problem:
(*array) = sieve;
You are are assigning the address of sieve, a temporary local array, to *array. You need to copy the array contents instead.
Are you also this person who has asked three questions about identical code?
This question has been asked here on SO before with below code
find3missing(int* array)
{
int newarray[100] = {0};
For i = 0 to 99
++newarray[array[i]] ;
For i = 0 to 99
If newarray[i] != 1
Cout << “the missing number is ” << i+1 << endl ;
}
But when I checked this code, it doesn't seem to work. Suppose I have an array of {1,2,6}. The output should be 3,4,5 but with the code above I get 1,4,5,6 instead. Below is my implementation of pseudo code with array size 6.
main()
{
int a[6]={1,2,6};
int tmp[6]={0},i;
for(i=0;i<6;i++)
{
++tmp[a[i]];
}
for(i=0;i<6;i++)
{
if(tmp[i]!=1)
{
printf("%d",i+1);
}
}
}
Is this the right code?
This ++newarray[array[i]] should be ++newarray[array[i] - 1]. This because you are interested in a sequence of 1-100 numbers, so no 0, but C arrays are 0 based. If you then look at the cout: the missing number is ” << i+1 here you "unshift" the number by adding 1.
There is another problem: you should pass the number of elements of the array, something like:
find3missing(int* array, int length) {
int newarray[100] = {0};
for (int i = 0; i < length; i++) {
++newarray[array[i] - 1] ;
}
C/C++ arrays are zero based, as A[i] is equivalent to *(A+i). So change ++newarray[array[i]] to ++newarray[array[i]-1]. Also use malloc, free and memset to use an array of dynamic size.
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
void find3missing(int* pArray, size_t size, int min, int max){
int* newarray;
int i;
unsigned int j;
int range = max - min;
if(range < 0)
return;
newarray = (int*) malloc(range*sizeof(int)); // allocate enough memory
memset(newarray,0,range*sizeof(int)); // set that block to zero
for(j = 0; j < size; ++j){
++newarray[pArray[j]-min];
}
for(i = 0; i < range; ++i){
if(!newarray[i])
printf("%d is missing!\n",min+i);
}
free(newarray);
}
int main(){
int test[] = {1,3,6};
find3missing(test,sizeof(test)/sizeof(int),1,6);
return 0;
}
Please note that this solution is very inefficient if your array is sorted. In this case have a look at Jimmy Gustafsson's answer.
This algoritm will be quite simple, since you're using a sorted array. Simply check if the current value +1 equals the nextvalue like below:
find3missing(){
int array[arraySize]; // the array with integers
for(i=0;i<arraySize;i++)
if(array[i]+1 != array[i+1]) // if value array[i]+1 is not equal the next index
// value, then it's a missing number
printf("A missing number: %i", i+1);
}