I had this working a second ago but accidentally broke it. Can anyone help me fix it? I'm getting a Segmentation Fault so I assume I messed up the pointers at some point. It's supposed to generate a bunch of random numbers depending on user input.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, char *argv[])
{
unsigned int mySeed; // creates our variables
unsigned int taps[2];
unsigned int temp[2];
unsigned int myToggle;
FILE *fp;//opens the file
fp = fopen("random.txt", "w");//sets the file to open equal to this file
int TapInputs = 1;
int count = 0;
int tap;
int myNewNumber = 0;
mySeed = atoi(argv[1]);
if(atoi(argv[1]) > 0) //Error checking for negative inputs.
{
printf("Please enter the taps you'd like to use : ");//prompts user to input the taps and then makes sure theyre in range
while(TapInputs)
{
scanf("%d",&tap);
if((tap > 0)&&(tap < 33))
{
*(taps+count)=tap;
}
else if(tap == -1) // when we find -1 we do this
{
TapInputs = 0;
}
else if(tap > 32)
{
exit(0);
}
count++;
}
printf("How many numbers do you want to generate: "); //prompts user to input the number of numbers to use
scanf("%d", &myNewNumber);
while (myNewNumber < 0)// error checking for positive inputs
{
printf("How many numbers do you want to generate: ");
scanf("%d", &myNewNumber);
}
printf("\nRandom Numbers:");
while(myNewNumber)//creates number equal to the user input number in the previous step
{
temp[0] = mySeed; // makes temp1 the seed
temp[1] = mySeed; // makes temp2 the seed
temp[0] = (temp[0] >> taps[0]) & 1; // checks and sets the bit
temp[1] = (temp[1] >> taps[1]) & 1; // checks and sets the bit
myToggle = (temp[0] ^ temp[1]); // here we xor the temp1 and 2
mySeed = (mySeed << 1) ^ myToggle; // use bittoggle to shift the seed and generate a new number
fprintf(fp, "%d\r\n", mySeed); // wrties the generated number into the file
printf("\n%d", mySeed); // prints the number
myNewNumber -= 1;
}
fclose(fp); // closes file, creates a new line and returns 0 to the fucntion
printf("\n");
return 0;
}
else
{ // if the number the user input was 0 we will end our program
exit(0);
}
}
The fault happens immediately upon execution.
This piece of code :
while(TapInputs)
{
scanf("%d",&tap);
if((tap > 0)&&(tap < 33))
{
*(taps+count)=tap;
}
else if(tap == -1) // when we find -1 we do this
{
TapInputs = 0;
}
else if(tap > 32)
{
exit(0);
}
count++;
}
is executed until you find TapInputs to be false, or in other words 0. This will happen only if you give -1 as an input to scanf("%d", &tap). Until then, you will keep reading and also incrementing count.
But some lines above, you have declared
unsigned int taps[2];
and in your while loop you do
*(taps+count)=tap;
So, if you have read tap enough times and keep finding it between 0 and 33, until you find it -1, count will have increased enough to get your array out of bounds.
I think problem is in this line , mySeed = atoi(argv[1]);
you have to do something like this,
you can put the code from that in an if condition ,
if(agrc>1)
{
mySeed = atoi(argv[1]);
---------------------
--------------------
}
I have tested...it is working
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, char *argv[])
{
unsigned int mySeed; // creates our variables
unsigned int taps[2];
unsigned int temp[2];
unsigned int myToggle;
FILE *fp;//opens the file
fp = fopen("random.txt", "w");//sets the file to open equal to this file
int TapInputs = 1;
int count = 0;
int tap;
int myNewNumber = 0;
if(agrc>1)
{
mySeed = atoi(argv[1]);
if(atoi(argv[1]) > 0) //Error checking for negative inputs.
{
printf("Please enter the taps you'd like to use : ");//prompts user to input the taps and then makes sure theyre in range
while(TapInputs)
{
scanf("%d",&tap);
if((tap > 0)&&(tap < 33))
{
*(taps+count)=tap;
}
else if(tap == -1) // when we find -1 we do this
{
TapInputs = 0;
}
else if(tap > 32)
{
exit(0);
}
count++;
}
printf("How many numbers do you want to generate: "); //prompts user to input the number of numbers to use
scanf("%d", &myNewNumber);
while (myNewNumber < 0)// error checking for positive inputs
{
printf("How many numbers do you want to generate: ");
scanf("%d", &myNewNumber);
}
printf("\nRandom Numbers:");
while(myNewNumber)//creates number equal to the user input number in the previous step
{
temp[0] = mySeed; // makes temp1 the seed
temp[1] = mySeed; // makes temp2 the seed
temp[0] = (temp[0] >> taps[0]) & 1; // checks and sets the bit
temp[1] = (temp[1] >> taps[1]) & 1; // checks and sets the bit
myToggle = (temp[0] ^ temp[1]); // here we xor the temp1 and 2
mySeed = (mySeed << 1) ^ myToggle; // use bittoggle to shift the seed and generate a new number
fprintf(fp, "%d\r\n", mySeed); // wrties the generated number into the file
printf("\n%d", mySeed); // prints the number
myNewNumber -= 1;
}
fclose(fp); // closes file, creates a new line and returns 0 to the fucntion
printf("\n");
return 0;
}
else
{ // if the number the user input was 0 we will end our program
exit(0);
}
}
}
Related
I want my code to print "YES" if there is digit 7 in the entered number, and otherwise print "NO".
When I use while(T != 0) for test cases, my code prints "YES" for all the numbers - even for number 45. Without while(T != 0) my code runs perfectly.
Where is my mistake?
#include <stdio.h>
int main() {
int T;
scanf("%d", &T);
while (T != 0) {
int X;
scanf("%d", &X);
int flag, result;
while (X != 0) {
result = X % 10;
if (result == 7) {
flag = 1;
}
X = X / 10;
}
if (flag == 1) {
puts("YES");
} else {
puts("NO");
}
T--;
}
return 0;
}
After trying out your code, the main issue was not with the "while" test. Rather, in the code your test flag was not being reset so once the a value was found to have the digit "7" in it, all subsequent tests were noted as being "YES". With that, following is a refactored version of your code.
#include <stdio.h>
#include <stdlib.h>
int main()
{
int T;
printf("How many numbers to test: "); /* Clarifies what the user is being asked for */
scanf("%d", &T);
while (T != 0)
{
int X;
printf("Enter a number to be tested: "); /* Again, lets the user know what to enter */
scanf("%d", &X);
int flag = 0, result;
while (X != 0)
{
result = X % 10;
if (result == 7)
{
flag = 1;
}
X = X / 10;
}
if (flag == 1)
{
puts("YES");
}
else
{
puts("NO");
}
flag = 0; /* Needs to be reset after being set and before next check */
T--;
}
return 0;
}
Some things to note.
Although not really needed, verbiage was added as prompts to clarify to the user what needed to be entered for values.
Most importantly, the flag variable gets initialized to zero and then subsequently gets reset to zero after each test has been completed.
With those bits addressed, following is some sample terminal output.
#Vera:~/C_Programs/Console/Seven/bin/Release$ ./Seven
How many numbers to test: 4
Enter a number to be tested: 3987
YES
Enter a number to be tested: 893445
NO
Enter a number to be tested: 8445
NO
Enter a number to be tested: 58047
YES
Give that a try and see if it meets the spirit of your project.
The program would ask the user an integer input.
and it counts how many zero the int has.
constraints: use while loop
ex:
input: 2400
count: 2
now I have no problem in that part, only when the user would input a zero.
supposed it counts 1.
ex:
input 0
count: 1
but then the program returns count 0.
here's the code:
int main(){
int n, counter = 0;
printf("Enter the number: ");
scanf("%d", &n);
while(n != 0){
if(n % 10 == 0){
counter ++;
n=n/10;
}else{
break;
}
}
printf("%d", counter);
return 0;
}
Use functions.
int countZeroes(int x)
{
int result = !x; // if x == 0 then result = 1
while(x)
{
result += !(x % 10);
x /= 10;
}
return result;
}
int main(void)
{
printf("%d\n", countZeroes(0));
printf("%d\n", countZeroes(1000));
printf("%d\n", countZeroes(-202020));
}
https://godbolt.org/z/91hKr46eo
You have while(n != 0) this does so when you enter just 0 it doesn't run. So the counter that you have set to 0 at the beginning is still 0
Here is what I would have done :
int main()
{
int num, count = 0;
scanf("%d",&num);
if (num == 0) {
printf("1");
return 0;
}
while(num != 0) //do till num greater than 0
{
int mod = num % 10; //split last digit from number
num = num / 10; //divide num by 10. num /= 10 also a valid one
if(mod == 0) count ++;
}
printf("%d\n",count);
return 0;
}
Just don't forget to consider everything that can happen with a condition that you set
**Fixed it
A different version that prints the integer as a string, and looks for '0' characters in it. Tested.
#include <stdio.h>
#include <string.h>
int main(void)
{
int input = 0;
int zeroes = 0;
char *foundpos, teststring[100];
scanf("%d", &input);
sprintf(teststring, "%d", input);
foundpos = strchr(teststring, '0');
while (foundpos != NULL) {
++zeroes;
foundpos = strchr(foundpos + 1, '0');
}
printf("%d contains %d zeroes", input, zeroes);
}
Just count the zero digits you get between \n chars.
#include <stdio.h>
int main()
{
int ndigs = 0, c;
while ((c = getchar()) != EOF) {
switch (c) {
case '0': ndigs++;
break;
case '\n': printf(" => %d zero digs", ndigs);
ndigs = 0;
break;
}
putchar(c);
}
}
sample output:
$ ./a.out
123001202010
123001202010 => 5 zero digs
^D
$ _
No need to convert digits to a number, to convert it back to decimal digits. You can improve the program counting digits until a nondigit is detected, then output. But there's no need to convert a decimal representation of a number (in base 10) to internal representation to then get the digits you have destroyed (in the conversion) back again to count them.
As earlier mentioned, the problem is with the loop:
while(n != 0){
if(n % 10 == 0){
counter ++;
n=n/10;
}else{
break;
}
}
It doesnt do anything in case n == 0. But replacing it with n > 0 is not a good solution because ints can be negative too.
You should use do{}while() construction instead, it will always do one iteration of loop no matter what condition you put there. Notice that no matter what you get as a number, it is still a number so you can do one iteration of loop either way.
Just do as follows:
do{
if(n % 10 == 0){
counter ++;
n=n/10;
}else{
break;
}
} while( n != 0 );
This should work(if i didnt mess up the braces/semicolumns).
The question is that show the digits which were repeated in C.
So I wrote this:
#include<stdio.h>
#include<stdbool.h>
int main(void){
bool number[10] = { false };
int digit;
long n;
printf("Enter a number: ");
scanf("%ld", &n);
printf("Repeated digit(s): ");
while (n > 0)
{
digit = n % 10;
if (number[digit] == true)
{
printf("%d ", digit);
}
number[digit] = true;
n /= 10;
}
return 0;
}
But it will show the repeated digits again and again
(ex. input: 55544 output: 455)
I revised it:
#include<stdio.h>
int main(void){
int number[10] = { 0 };
int digit;
long n;
printf("Enter a number: ");
scanf("%ld", &n);
printf("Repeated digit(s): ");
while (n > 0)
{
digit = n % 10;
if (number[digit] == 1)
{
printf("%d ", digit);
number[digit] = 2;
}
else if (number[digit] == 2)
break;
else number[digit] = 1;
n /= 10;
}
return 0;
}
It works!
However, I want to know how to do if I need to use boolean (true false), or some more efficient way?
To make your first version work, you'll need to keep track of two things:
Have you already seen this digit? (To detect duplicates)
Have you already printed it out? (To only output duplicates once)
So something like:
bool seen[10] = { false };
bool output[10] = { false };
// [...]
digit = ...;
if (seen[digit]) {
if (output[digit])) {
// duplicate, but we already printed it
} else {
// need to print it and set output to true
}
} else {
// set seen to true
}
(Once you've got that working, you can simplify the ifs. Only one is needed if you combine the two tests.)
Your second version is nearly there, but too complex. All you need to do is:
Add one to the counter for that digit every time you see it
Print the number only if the counter is exactly two.
digit = ...;
counter[digit]++;
if (counter[digit] == 2) {
// this is the second time we see this digit
// so print it out
}
n = ...;
Side benefit is that you get the count for each digit at the end.
Your second version code is not correct. You should yourself figured it out where are you wrong. You can try the below code to print the repeated elements.
#include<stdio.h>
int main(void){
int number[10] = { 0 };
int digit;
long n;
printf("Enter a number: ");
scanf("%ld", &n);
printf("Repeated digit(s): ");
while (n > 0)
{
digit = n % 10;
if (number[digit] > 0)
{
number[digit]++;;
}
else if (number[digit] ==0 )
number[digit] = 1;
n /= 10;
}
int i=0;
for(;i<10; i++){
if(number[i]>0)
printf("%d ", i);
}
return 0;
}
In case you want to print the repeated element using bool array (first version) then it will print the elements number of times elements occur-1 times and in reverse order because you are detaching the digits from the end of number , as you are seeing in your first version code output. In case you want to print only once then you have to use int array as in above code.
It is probably much easier to handle all the input as strings:
#include <stdio.h>
#include <string.h>
int main (void) {
char str[256] = { 0 }; /* string to read */
char rep[256] = { 0 }; /* string to hold repeated digits */
int ri = 0; /* repeated digit index */
char *p = str; /* pointer to use with str */
printf ("\nEnter a number: ");
scanf ("%[^\n]s", str);
while (*p) /* for every character in string */
{
if (*(p + 1) && strchr (p + 1, *p)) /* test if remaining chars match */
if (!strchr(rep, *p)) /* test if already marked as dup */
rep[ri++] = *p; /* if not add it to string */
p++; /* increment pointer to next char */
}
printf ("\n Repeated digit(s): %s\n\n", rep);
return 0;
}
Note: you can also add a further test to limit to digits only with if (*p >= '0' && *p <= '9')
output:
$./bin/dupdigits
Enter a number: 1112223334566
Repeated digit(s): 1236
Error is here
if (number[digit] == true)
should be
if (number[digit] == false)
Eclipse + CDT plugin + stepping debug - help you next time
As everyone has given the solution: You can achieve this using the counting sort see here. Time complexity of solution will be O(n) and space complexity will be O(n+k) where k is the range in number.
However you can achieve the same by taking the XOR operation of each element with other and in case you got a XOR b as zero then its means the repeated number. But, the time complexity will be: O(n^2).
#include <stdio.h>
#define SIZE 10
main()
{
int num[SIZE] = {2,1,5,4,7,1,4,2,8,0};
int i=0, j=0;
for (i=0; i< SIZE; i++ ){
for (j=i+1; j< SIZE; j++){
if((num[i]^num[j]) == 0){
printf("Repeated element: %d\n", num[i]);
break;
}
}
}
}
I got a data file which consists of a single column with the header name with temperature and the following rows are just a series of recorded temperature. I can read it successfully(perhaps) into the C program using the following command:
#include <stdio.h>
#include <cstdlib>
int main()
{
FILE *fpt; /*define a pointer to predefined structure type FILE*/
fpt = fopen("temperature.dat","r");
char temp[10];
float t[7];
int i;
fscanf(fpt, "%s",temp);
printf("%s",temp);
for(i=0;i<7;++i)
{
fscanf(fpt, "%f",&t[i]);
printf("%.2f",t[i]);
}
printf("%f",t[3]); /*just testing whether the program is reading correctly*/
fclose(fpt);
system("pause");
}
But the problem is how could I detect when there is a series of temperature, for instance 6 temperature values are increasing continuously. I need something like IF total of 6 values of temperature is increased continuously, then it will generate some error message using printf function. Assume that the total input number of data is not fixed, how could I program it.
There is no need to use an extra loop. You can just do
totalInc = 0;
for(i=0;i<7;++i) {
fscanf(fpt, "%f",&t[i]);
printf("%.2f",t[i]);
if (i > 0) {
if (t[i] > t[i-1]) totalInc += 1;
else totalInc -= 1;
}
}
The totalInc will tell you the number of times the current value is greater than the previous value. For your case, you can then just check for totalInc == 6 but really, you can just check for any number of increments. A positive number will indicate a general incremental trend, while a negative number will indicate a general decreasing trend.
To detect whether a file of floats has at least 6 increasing values in a row, you could do something like this:
#include <stdio.h>
#define IN_A_ROW 6
int main() {
FILE *f = fopen("temps.txt", "r");
float x, last_x;
int inc = 0;
fscanf(f, "%f", &last_x);
while (fscanf(f, "%f", &x) == 1) {
if (x > last_x) { // or maybe >=
if (++inc >= IN_A_ROW) {
printf("Found %d increases in a row\n", IN_A_ROW);
return -1;
}
}else
inc = 0;
last_x = x;
}
fclose(f);
return 0;
}
Add a variable (say, inctemp) to count seeing increases in a row, and increment it in your loop if there is an increase. Reset it to 0 if there is not an increase. At the end of your loop, you know how many in a row there were (at least at the end of the data set)
Modified for arbitrary number of reads
int inctemp = 0;
float curtemp, prevtemp;
...
if ( fscanf(fpt, "%f",&prevtemp) == 1)
printf("%.2f",prevtemp);
while( fscanf(fpt, "%f",&curtemp) == 1)
{
printf("%.2f",curtemp);
if( curtemp > prevtemp ) {
inctemp++;
}
else {
inctemp = 0;
}
if( inctemp == 6 ) {
printf("Six increases in a row!\n");
}
prevtemp = curtemp;
}
}
Finding a delta between the temperatures will help you.
#include <stdio.h>
#include <cstdlib>
int main()
{
FILE *fpt; /*define a pointer to predefined structure type FILE*/
fpt = fopen("temperature.dat","r");
char temp[10];
float t[7];
int i, loweringdelta;
fscanf(fpt, "%s",temp);
printf("%s",temp);
loweringdelta = 1;
for (i=0; i<7; ++i)
{
fscanf(fpt, "%f", &t[i]);
printf("%.2f", t[i]);
if (i > 0 && (t[i]-t[i-1]<= 0))
{
loweringdelta = t[i]-t[i-1];
}
}
if (loweringdelta > 0)
{
// Your error message here
}
printf("%f", t[3]); /*just testing whether the program is reading correctly*/
fclose(fpt);
system("pause");
}
You will need some kind of counter to see how many times you have seen incrementing temperatures. Also, read the file in a while loop:
#include <stdio.h>
int main()
{
FILE *fpt; /*define a pointer to predefined structure type FILE*/
fpt = fopen("temperature.dat","r");
char temp[10];
int count = 0;
int i;
float prev_temp = -999.00;
float current_temp;
int threshold = 6;
fscanf(fpt, "%s",temp); // header?
printf("Header: %s\n",temp);
while(!feof(fpt)) {
fscanf(fpt, "%f", ¤t_temp);
if (current_temp > prev_temp) count++;
else count = 0;
prev_temp = current_temp;
if (count > threshold) printf("Saw %d consecutive increases\n", count);
}
fclose(fpt);
}
my binary conversion doesn't work after it recurs a second time, it seems to work only during the first time through. The purpose of the is have a user input a number to convert to Hex, Octal, and brinary from a integer and keep on asking and converting until the user inputs 0. Please help!
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
long toBinary(int);
int main(void) {
int number = 0;
long bnum;
int zero = 0;
while(number != zero) {
puts("\nPlease enter a number you would like to convert to");
puts("\nHexadecimal, octal, and binary: ");
scanf("%d", &number);
if(number != zero) {
printf("\nThe Hexadecimal format is: %x", number);
printf("\nThe Octal format is: %o", number);
bnum = toBinary(number);
printf("\nThe binary format is: %ld\n", bnum);
}
else {
puts("\nI'm sorry you have to enter a number greater than 0.\n");
puts("\nOr have enter an invalid entry.");
}
}
return 0;
}
long toBinary(int number) {
static long bnum, remainder, factor = 1;
int long two = 2;
int ten = 10;
if(number != 0) {
remainder = number % two;
bnum = bnum + remainder * factor;
factor = factor * ten;
toBinary(number / 2);
}
return bnum;
}
You just need a function to convert an integer to its binary representation.
Assuming the int is 32 bits then this should work:
#include <stdio.h>
int main()
{
char str[33];
str[32] = 0;
int x = 13, loop;
for (loop = 31; loop >= 0; --loop) {
str[loop] = (x & 1) ? '1' : '0';
x = x >> 1;
}
printf("As %s\n", str);
return 0;
}
You can make this into a function, read x etc...
EDIT
For octal/hex - printf will do this for you
EDIT
Here goes recursively
#include <stdio.h>
void PrintBinary(int n, int x) {
if (n > 0) {
PrintBinary(n - 1, x >> 1);
}
printf("%c",(x & 1) ? '1' : '0');
}
int main()
{
PrintBinary(32,12);
return 0;
}
First of all I am surprised it even works once. Firstly, your while condition is while number does not equal zero. But right off the bat, number equals 0 and zero equals 0. Therefore the while should never run. If you want to keep this condition for the main loop, change it to a do-while loop: do { //code } while (number != zero);. This will run the code at least once, then check if the inputted number doesn't equal zero. That brings me to the next issue; your scanf for number is scanning for a double and placing it in a regular integer memory spot. Quick fix: scanf("%i",&number);. Also I am finding some functions called puts.. I find it best to keep with one printing function, printf. Now, I am finding afew errors in your toBinary function, but if it works than I guess it works. These are all the errors i could find, I hope this helped. But for future reference there is no need to declare a variable for a const number like 2 or 10 at this level.
#include <stdint.h>
char* toBinary(int32_t number, int index){
static char bin[32+1] = {0}, *ret;
if(index == 32){
memset(bin, '0', 32);
return toBinary(number, 31);
} else if(number & (1<<index))
bin[31-index] = '1';
if(index)
(void)toBinary(number, index-1);
else
for(ret = bin; *ret == '0';++ret);
return ret;
}
...
int number = -1;
...
printf("\nThe binary format is: %s\n", toBinary(number, 32));