How to read 2 lines of integer input in C? - c

I'm doing a project for my algorithms class and I'm having a lot of trouble with inputs. I'm trying to read an input like this:
6 0 2 3 1 3
5 9 2 1 3
The integers will need to go to
int num1; // num1 = 6
int num2; // num2 = 5
int array1[100]; // array1 = {0, 2, 3, 1, 3, 0, 0, ...}
int array2[100]; // array2 = {9, 2, 1, 3, 0, 0, ...}
The input will come from standard input, in the form of a file. So in terminal running the program would look like this:
cat input.txt | ./a.out
Where input.txt contains the two lines of integers.
Here is my flawed attempt so far:
while(scanf("%d%c", &temp, &ch) > 1){
if (ch != '\n'){
one[count] = temp;
}
else if (ch == '\n'){
count = 0;
two[count] = temp;
}
one[count] = temp;
count++;
if (ch != ' ')
{
printf("Invalid input. Please do int + space.\n");
return -1;
}
if ((temp >= 100) || (temp <= -100))
{
printf("Input is too big, must be between -100, 100.\n");
return -1;
}
if (one[0] < 1){
printf("Input for n cannot be smaller than one!");
return -1;
}
}
I think the main issue is that I'm just not sure how to deal with multiple lines of input. One line of input is fine by me but multiple lines is what trips me over.

You could fetch an entire line of input using the getline function and then iterate over that line, scanning one number at a time using the strtol function.
From the example in your question I assume that you want all remaining entries in the two arrays to be zero so don't forget to zero them out (either manually or using the memset function.).
And also don't forget to free() the buffer getline gave you.

Actually I ended up using scanf, here is the working code below. It really helped to read some of these comments and also refer to K&R
#include <stdio.h>
#include <string.h>
#define ARRAY_SIZE 100
void shiftArrayBackByOne(int a[]){
for(int i = 1; i <= ARRAY_SIZE; i++){
a[i - 1] = a[i];
}
}
void printArray(int a[], int n){
for(int i = 0; i < n; i++){
printf("%d ", a[i]);
}
putchar('\n');
}
int main(){
int isLineTwo = 0;
int countOne = 0;
int countTwo = 0;
int inputNum;
int num1;
int num2;
int array1[ARRAY_SIZE];
int array2[ARRAY_SIZE];
char ch;
while(scanf("%d%c", &inputNum, &ch) > 0){
//Puts the input into different arrays depeding
//on value of isLineTwo
if (isLineTwo){
array2[countOne] = inputNum;
countOne++;
} else {
array1[countTwo] = inputNum;
countTwo++;
}
//Increment isLineTwo if ch is a 'newline'
if (ch == '\n')
{
isLineTwo++;
}
//Check if user inputs more than 2 lines
if (isLineTwo > 1){
printf("Hey, no more than 2 input lines!\n");
}
}
printArray(array1, countOne);
printArray(array2, countTwo);
num1 = array1[0];
num2 = array2[0];
shiftArrayBackByOne(array1);
shiftArrayBackByOne(array2);
printf("num1 = %d\n", num1);
printf("num2 = %d\n", num2);
printArray(array1, countOne);
printArray(array2, countTwo);
}

Look at my code below. Maybe it helps you.
Generally, if you know how many numbers will be inputted, you can read numbers one by one using scanf("%d", ...) and use fflush() when the expected amount is met to clear any other numbers in the buffer. This example assumes that the first two numbers are the respective lengths of each line. The input could look like:
// example input:
// 4
// 3
// 1 2 3 4
// 5 6 7
int main()
{
int it;
int it1 = 0;
int it2 = 0;
int line1[100];
int line2[100];
scanf("%d", &it1); // amount of line 1 numbers
scanf("%d", &it2); // amount of line 2 numbers
it = 0;
do
{
scanf("%d", &line1[it]);
} while (++it < it1);
fflush(stdin); // clear input buffer
it = 0;
do
{
scanf("%d", &line2[it]);
} while (++it < it2);
return 0;
}

Related

Counting the number of zero in an integer

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

How to fix infinite printing of random number?

I wrote a program that scans an unknown amount of integers into an array but when I run it, it print the last value it has gotten an infinite amount of times.
For example for the input: 1 2 3 4 5
The output would be 55555555555555555555555...
Why does this happen and how can I fix that?
My goal here is to create a array, for an instance {1, 2, 3, 4, 5} and then print what it scanned into the array, ONLY ONCE...
int *pSet = (int*) malloc(sizeof(int)); int i; int c;
printf("Please enter a stream of numbers to make a set out of them: ");
printf("\n");
scanf("%d", &c);
pSet[0] = c;
printf("%d ", c);
for(i = 1; c != EOF; i++) {
pSet = (int*) realloc(pSet, sizeof(int)*(i+1));
if(pSet == NULL) {
return FAIL;
}
scanf("%d", &c);
pSet[i] = c;
printf("%d ", c);
}
free(pSet);
Why does this happen (?) (print ... an infinite amount of times.)
Look at the loop terminating conditions c != EOF.
int c;
scanf("%d", &c);
for(i = 1; c != EOF; i++) { // Not good code
scanf("%d", &c);
}
EOF is some negative value, often -1. scanf("%d", &c) attempts to read user input and convert to an int. scanf() returns a 1,0,EOF depending on if it 1) succeeded, 2) failed to find numeric text or 3) end-of-file or input error occurred. Unfortunately code does not use that return value. Instead code used the number read, c and checked if that number read was the same as EOF.
how can I fix that?
Only loop when the return value of scanf() is as expected (1).
for(i = 1; scanf("%d", &c) == 1; i++) {
...
}
Putting this together with some other ideas
#include <stdio.h>
#include <stdio.h>
int main(void) {
printf("Please enter a stream of numbers to make a set out of them:\n");
int *pSet = NULL; // Start with no allocation
size_t i = 0;
int c;
for (i = 0; scanf("%d", &c) == 1; i++) {
// +--------------------------- No cast needed.
// v v----------v Use sizeof de-referenced pointer
void *p = realloc(pSet, sizeof *pSet * (i + 1));
if (p == NULL) {
free(pSet);
return EXIT_FAILURE;
}
pSet = p;
pSet[i] = c;
}
for (size_t j = 0; j < i; j++) {
printf("%d ", pSet[j]);
}
free(pSet);
return 0;
}
There are a number of problems.
1) Terminate the loop when scanf fails instead of using EOF. Do that by checking that the return value is 1 (i.e. the number of input items
successfully matched)
2) Don't allocate memory until it's needed
3) Never do realloc directly into the target pointer - always use a temp variable.
Fixing this your code could be:
#include <stdio.h>
int main(void) {
int *pSet = NULL;
printf("Please enter a stream of numbers to make a set out of them: ");
printf("\n");
int i = 0;
int c;
while (1) {
if (scanf("%d", &c) != 1)
{
printf("Terminating input loop\n");
break;
}
int* tmp = realloc(pSet, sizeof(int)*(i+1));
if(tmp == NULL) {
printf("oh dear...\n");
break;
}
pSet = tmp;
pSet[i++] = c;
printf("%d ", c);
}
for (int j=0; j < i; ++j) printf("%d\n", pSet[j]);
free(pSet);
return 0;
}
Input:
1 2 3 4 5 6 7 stop
Output:
Please enter a stream of numbers to make a set out of them:
1 2 3 4 5 6 7
Terminating input loop
1
2
3
4
5
6
7
You should stop your loop when scanf fails. According to the manual:
On success, [scanf] return[s] the number of input items successfully matched and assigned; this can be fewer than provided for, or even zero, in the event of an early matching failure.
The value EOF is returned if the end of input is reached before either the first successful conversion or a matching failure occurs. EOF is also returned if a read error occurs. [...]
So you can turn your for loop into a while one.
#include <stdio.h>
#include <stdlib.h>
#define FAIL 0
int main() {
int *pSet = (int*) malloc(sizeof(int));
int c;
int i=0;
printf("Please enter a stream of numbers to make a set out of them: ");
while(scanf("%d", &c) == 1) {
pSet[i] = c;
pSetNew = (int*) realloc(pSet, sizeof(int)*(i+1));
if(pSetNew == NULL) {
free(pSet);
return FAIL;
} else {
pSet = pSetNew;
}
printf("%d ", c);
i++;
}
free(pSet);
}
But if you want a more robust piece of code, I suggest you to retrieve the answer as a string (NULL-terminated array of char), and then parse it with dedicated functions like strtol which let you check if the whole string is a valid entry, and not only the first characters.
Note: HengLi fixed a potential memory leak in the code sample above

how to store values elements of datasets into different arrays in c

I have a convoluted plan for a program.
I would like to have datasets of three values be stored in different arrays, i.e the first value be stored in the first array, the second value in the second array and the third in the third array.
For example:
"How often would you like to repeat the program"
2
"Enter the first value:"
1
"Enter the second value:"
2
"Enter the third value:"
3
"Enter the first value:"
4
"Enter the second value:"
5
"Enter the third value:"
6
The output should be something like this
a_arr = [1 4]
b_arr = [2 5]
c_arr = [3 6]
I have come up with this code but I can't seem to get it to work.
#include <stdio.h>
#include <stdlib.h>
#define MAX_SIZE 255
//validation function
int a_arr[MAX_SIZE]; // Declare an array of MAX_SIZE
int b_arr[MAX_SIZE]; // Declare an array of MAX_SIZE
int c_arr[MAX_SIZE]; // Declare an array of MAX_SIZE
int i;
int checkInput0(void);
float checkInput1(void);
float checkInput2(void);
float checkInput3(void);
a_arr[] = checkInput1;
b_arr[] = checkInput2;
c_arr[] = checkInput3;
int main()
{
int repeats = 0, counter = 0;
//Amount of triangles
repeats = checkInput0();
// create arrays for all values
do {
i = counter;
for(i=0; i<repeats; i++)
{
scanf("%f", &a_arr[i]);
}
for(i=0; i<repeats; i++)
{
scanf("%f", &b_arr[i]);
}
for(i=0; i<repeats; i++)
{
scanf("%f", &c_arr[i]);
}
counter++;
}while(counter < repeats);
do {
printf("%f\n",a_arr );
printf("%f\n",b_arr );
printf("%f\n",c_arr );
counter++;
}while(counter < repeats);
return 0;
}
// Validate Value of a
float checkInput1(void){
float option1,check1;
char c;
do{
printf("Enter the first side of the triangle");
if(scanf("%f%c",&option1,&c) == 0 || c != '\n') {
while((check1 = getchar()) != 0 && check1 != '\n' && check1 != EOF);
printf("\t[ERR] Invalid number for the triplet.\n");
}else {
break;
}
}while(1);
// printf("returning the value of option, which is %f", option);
return option1;
}
// Validate Value of b
float checkInput2(void){
float option2,check2;
char c;
do{
printf("Enter the second side of the triangle");
if(scanf("%f%c",&option2,&c) == 0 || c != '\n'){
while((check2 = getchar()) != 0 && check2 != '\n' && check2 != EOF);
printf("\t[ERR] Invalid number for the triplet.\n");
}else{
break;
}
}while(1);
//printf("returning the value of option, which is %f", option2);
return option2;
}
// Validate Value of c
float checkInput3(void){
float option3,check3;
char c;
do{
printf("Enter the third side of the triangle");
if(scanf("%f%c",&option3,&c) == 0 || c != '\n'){
while((check3 = getchar()) != 0 && check3 != '\n' && check3 != EOF);
printf("\t[ERR] Invalid number for the triplet.\n");
}else{
break;
}
}while(1);
// printf("returning the value of option, which is %f", option);
return option3;
}
Note: the functions are there for validation such that the input is a number.
All help is greatly appreciated
I think you may have complicated this.
You can do something like this.
printf("How many...");
scanf("%d", &num); //num is the user input
int i;
for(i=0; i<num; i++)
{
printf("enter first number");
a_arr[i] = checkInput1();
printf("enter first number");
b_arr[i] = checkInput2();
printf("enter first number");
c_arr[i] = checkInput3();
}
The last 3 declarations before main have no sense.
Answering the question, the pseudocode is simple. You have 3 arrays, so when the iterator of scans reach i = 3n-1, being n= 0,1,2,3,4..., then the index is increased.
E.g., scanf 0, 1 and 2 are all saved in index 0 of the respective array (2 = 3n-1, n being 1); scanf 3,4 and 5 are all saved in index 1 of the respective array (5 = 3n-1, n being 2) and so on...
I think you are wasting lot of memory doing this statically, simple malloc can save lot of memory and time(speed of execution i meant)
printf("How many...");
scanf("%d", &num); //num is the user input
int * a_arr = (int *)malloc( num * sizeof(int));
int * b_arr = (int *)malloc( num * sizeof(int));
int * c_arr = (int *)malloc( num * sizeof(int));
int count;
for(count=0; count<num; count++)
{
printf("enter first number");
scanf("%d",a_arr[count]);
printf("enter first number");
scanf("%d",b_arr[count]);
printf("enter first number");
scanf("%d",c_arr[count]);
}
//print or whatever you wanna do processing on it

Comparing digits of two inputs to see if they are the same

I am currently trying to finish a code where a user inputs two 5 digit long numbers. The code then checks to see if there are any identical numbers in the same spot for the two numbers and displays how many identical numbers there are in the same spot of the two inputs. (ex. comparing 56789 and 94712 there would be one similar digit, the 7 in the 3rd digit place.) As of now I have been able to break down the inputs into the digits in each spot, I just need help comparing them. Originally I thought I could just create an int that would serve as a counter and use modulus or division to output a 1 whenever the digits were the same, but I have been unable to put together a formula that outputs a 1 or 0 depending on if the digits are alike or not.
suppose you know the length of strings n (as a condition you would need them to be equal, if they differ in length other validation is needed)
//n is the length of string
for(int i=0;i<n;i++)
{
if(string1[i]==string2[i])
{
//do something, make a counter that increments here...
//also save index i, so you can tell the position when a match occured
}else
{
//do something else if you need to do something when chars didnt match
}
}
Here you when i=0, you are comparing string1[0] with string2[0], when i=1, you compare string1[1] with string2[1] and so on.....
I'd recommend reading the two in as strings or converting to strings if you have the ability to. From there it's a simple string compare with a counter. Something like this:
#include <stdio.h>
#include <ctype.h>
#include <string.h>
int is_numeric(char *str)
{
while (*str)
if (!isdigit(*str++))
return (0);
return (1);
}
int main(void)
{
char num1[32];
char num2[32];
int count = 0;
printf("Digit 1\n>> ");
if (scanf("%5s", num1) != 1 || !is_numeric(num1))
return (0);
printf("Digit 2\n>> ");
if (scanf("%5s", num2) != 1 || !is_numeric(num2))
return (0);
if (strlen(num1) != 5 || strlen(num2) != 5)
return (0);
for (int i=0; i<5; ++i)
if (num1[i] == num2[i])
++count;
printf("%d\n", count);
return (0);
}
You can do it very easy using modulo (%) and divide (/). First you do % 10 to get the least significant digit and do the compare. Then you do / 10 to remove the least significant digit. Like:
#include <stdio.h>
#include <string.h>
int main(void) {
unsigned int i1, i2;
int i;
int cnt = 0;
printf("Input first 5 digit number:\n");
if (scanf(" %u", &i1) != 1 || i1 < 10000 || i1 > 99999) // Get integer input and check the range
{
printf("input error\n");
return 0;
}
printf("Input second 5 digit number:\n");
if (scanf(" %u", &i2) != 1 || i2 < 10000 || i2 > 99999) // Get integer input and check the range
{
printf("input error\n");
return 0;
}
for (i=0; i<5; ++i)
{
if ((i1 % 10) == (i2 % 10)) ++cnt; // Compare the digits
i1 = i1 / 10;
i2 = i2 / 10;
}
printf("Matching digits %d\n", cnt); // Print the result
return 0;
}
It can also be done using strings. Read the input as unsigned int and then convert the value to a string using snprintf and finally compare the two strings character by character.
Something like:
#include <stdio.h>
#include <string.h>
int main(void) {
char str1[32];
char str2[32];
unsigned int i1, i2;
int i;
int cnt = 0;
printf("Input first 5 digit number:\n");
if (scanf(" %u", &i1) != 1) // Get integer input
{
printf("input error\n");
return 0;
}
snprintf(str1, 32, "%u", i1);
if (strlen(str1) != 5) // Convert to string
{
printf("input error - not 5 digits\n");
return 0;
}
printf("Input second 5 digit number:\n");
if (scanf(" %u", &i2) != 1) // Get integer input
{
printf("input error\n");
return 0;
}
snprintf(str2, 32, "%u", i2); // Convert to string
if (strlen(str2) != 5)
{
printf("input error - not 5 digits\n");
return 0;
}
for (i=0; i<5; ++i)
{
if (str1[i] == str2[i]) ++cnt; // Compare the characters
}
printf("Matching digits %d\n", cnt); // Print the result
return 0;
}
The reason for taking the input into a unsigned int instead of directly to a string is that by doing that I don't have to check that the string are actually valid numbers (e.g. the user type 12W34). scanf did that for me.

How to show the digits which were repeated in c?

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;
}
}
}
}

Resources