I'm trying to write a program in C where the user inputs a defined number of ints (in this case 5 ints) separated by whitespaces. Then, the input is stored in an int array so, lastly, it can be stored in a char array.
As an example of how the program is intended to work, when it asks for an input:
Input: 20 5 63 4 127
The output of the program should be:
Output: 20 5 63 4 127
This is what I've written so far, but I don't know how to get the input transformed into an int array. Note that I know the length of the input beforehand (in this case, as said above, 5 ints).
// Input: 20 5 63 4 127
// Ask for user input.
// Store the input in this int array.
int input_int_array[5];
unsigned char char_array[5];
for(int i=0;i<5;i++)
{
char_array[i]=input_int_array[i];
printf("%d ", char_array[i]);
}
// Should print: 20 5 63 4 127
You are probably expected to use scanf() to read user input as integers into an array of int:
#include <stdio.h>
int main() {
int input_int_array[5];
// Ask for user input.
printf("input 5 numbers: ");
for (int i = 0; i < 5; i++) {
// Store the input into the array.
if (scanf("%d", &input_int_array[i]) != 1)
return 1;
}
// Output the contents of the array:
for (int i = 0; i < 5; i++) {
printf("%d ", input_int_array[i]);
}
printf("\n");
return 0;
}
Related
I'd like to store input from keypad in array, but my for loop doesn't seem to work properly. Instead of reading an input from keypad, adding it to the array, and then incrementing the index, the program keep printing weird indexes.
Code
void loop(){
char arr[3];
for (int i = 0; i<3; i++){
char input = customKeypad.getKey();
if (input != NO_KEY){
do{
arr[i] = input;
Serial.println("Index");
Serial.println(i);
Serial.println("Value");
Serial.println(arr[i]);
} while(input == NO_KEY);
}
}
}
Console output
Index
2
Value
1
Index
1
Value
2
Index
1
Value
3
Index
1
Value
4
Index
2
Value
5
Index
2
Value
6
This is the dataflow of your program. This probably could be a comment but I needed the visualization to make it more understandable. It is not really clear what you want to do:
For instance, if you enter, in this order:
input==NO_KEY
input!=NO_KEY
input!=NO_KEY
You update the indexes #1 and #2, then the iteration (arduino loop) restarts and you can overwrite the values of the array. Is this what you want?
Also notice that the while loop never gets repeated, this is very clear from the dataflow.
I have rewritten you program to be tested outside of Arduino:
#include "stdio.h"
#define NO_KEY 'a'
int main(){
while(1){
char arr[3];
for (int i = 0; i<3; i++){
char input;
printf("%d -> ", i);
scanf(" %c",&input);
if (input != NO_KEY){
do{
arr[i] = input;
} while(input == NO_KEY );
}
}
for (int i = 0; i <3; i++){ printf("Value %d\n",arr[i]); }
printf("\n Reset\n");
}
}
And this is the output, as expected from your code
0 -> a
1 -> b
2 -> c
Value 127
Value 98
Value 99
Reset
0 -> b
1 -> a
2 -> a
Value 98
Value 98
Value 99
The program below asks the user to input 10 integer numbers and stores the user inputs in a corresponding array of 10 ints. When an input is done it should iterate through the already existing user inputs and print them out. I want to iterate through the stored values in storedinputs by using a function like strlen(), however the stored values are not strings but are integers. How could i do such a thing.
int main(void) {
int storedinputs[10] = {0};
int input;
for(int i = 0; i < 10; i++) {
printf("\nPlayer input:");
scanf("%d", &input);
storedinputs[i] = input;
for(int s = 0; s < strlen(storedinputs); s++) {
printf("Inputs %d", storedinputs);
}
}
return 0;
}
Expected Output:
Player input: 1
Inputs: 1
Player input: 3
Inputs: 1 3
Player input: 60
Inputs: 1 3 60
You cannot use the function strlen() because storedinputs is an array of integers. If you want to print the stored values every time you insert a new one you should edit the for loop condition, as suggested by Weather Vane in the comments, as follows:
for(int s = 0; s <= i; s++)
The variable i indicates the number of the cell containing the last number added.
Here is the fixed code including error checking.
Superfluous input needs to be skipped over (while(fgetc(stdin) != '\n');)
scanf has insufficient error checking capabilities. Use combination of fgets and strtol.
In the internal loop you need to terminate when outer loop counter is reached
You should not count invalid input (Therefore, I replaced outer for loop by a while loop)
You should not store invalid inputs in your array
You need to index your stored inputs when printing them out
--
#include <stdlib.h>
#include <stdio.h>
#include <limits.h>
#include <errno.h>
#include <string.h>
// In contrast to #define this provides a nice means for grouping constants
// and it can be changed into a typedef, later on
// Furthermore, it's a compiler aware constant
enum {INPUT_COUNT = 10, MAX_INPUT_LENGTH = 20};
int main(void) {
int input_count = 0; // The count of valid inputs
char input[MAX_INPUT_LENGTH + 1] = {0}; // The string buf for one input
int converted_input; // Result of integer conversion
int storedinputs[INPUT_COUNT] = {0}; // Array with valid results
char *endptr; // Needed for strtol error checking
while(input_count < 10) { // Loop over 10 valid inputs
printf("\nPlayer input (Enter single integer value):");
fgets(input, sizeof(input), stdin);
printf("Got input: %s\n", input); // input contains '\n', already
// If input was longer than MAX_INPUT_LENGTH, get rid of remains
if (input[strlen(input) - 1] != '\n') {
while(fgetc(stdin) != '\n');
}
// Reset errno, so strtol returns a fresh value
errno = 0;
converted_input = strtol(input, &endptr, 10);
// The errno is set if input is out of range
if (errno) {
perror("Conversion error");
continue;
}
// Here we have invalid characters present in the input
if ( (endptr == input) || (*endptr != '\n') ) {
printf("Please enter single integer!\n");
continue;
}
// Everything fine, so we can store result
storedinputs[input_count] = converted_input;
// Now we output all valid inputs, up to now
printf("Inputs: ");
for(int s = 0; s <= input_count; s++) {
printf("%d ", storedinputs[s]);
}
printf("\n");
++input_count;
}
return 0;
}
Output:
Player input (Enter single integer value):12
Got input: 12
Inputs: 12
Player input (Enter single integer value):13
Got input: 13
Inputs: 12 13
Player input (Enter single integer value):14
Got input: 14
Inputs: 12 13 14
Player input (Enter single integer value):1324567543245678654324567
Got input: 13245675432456786543
Conversion error: Numerical result out of range
Player input (Enter single integer value):asdc
Got input: asdc
Please enter single integer!
Player input (Enter single integer value):
Got input:
Please enter single integer!
Player input (Enter single integer value):12 12 12
Got input: 12 12 12
Please enter single integer!
Player input (Enter single integer value):1
Got input: 1
Inputs: 12 13 14 1
Player input (Enter single integer value):2
Got input: 2
Inputs: 12 13 14 1 2
Player input (Enter single integer value):3
Got input: 3
Inputs: 12 13 14 1 2 3
Player input (Enter single integer value):4
Got input: 4
Inputs: 12 13 14 1 2 3 4
Player input (Enter single integer value):5
Got input: 5
Inputs: 12 13 14 1 2 3 4 5
Player input (Enter single integer value):67
Got input: 67
Inputs: 12 13 14 1 2 3 4 5 67
Player input (Enter single integer value):7
Got input: 7
Inputs: 12 13 14 1 2 3 4 5 67 7
OK, 10 inputs have been made
My C Code is as so:
#include <stdio.h>
int main( int argc, char ** argv){
FILE *myFile;
myFile = fopen("numbers.txt", "r");
//read file into array
int numberArray[16];
for (int i = 0; i < 16; i++){
fscanf(myFile, "%1d", &numberArray[i]);
}
for (int i = 0; i < 16; i++){
printf("Number is: %d\n", numberArray[i]);
}
}
My numbers.txt file contains the follow values:
5
6
70
80
50
43
But for some reason my output
Number is: 5
Number is: 6
Number is: 7
Number is: 0
Number is: 8
Number is: 0
Number is: 5
Number is: 0
Number is: 4
Number is: 3
Number is: 0
Number is: 0
Number is: 4195904
Number is: 0
Number is: 4195520
Number is: 0
However I'm expecting it to print out numberArray to print out the identical contents of the text file. I'm not exactly sure why it's doing this, does anyone happen to know the reason? I'm aware that I'm making an array bigger than the amount of values that I can store, but I'm still confused as to why it can't store 70, 80, etc into one index?
It is because you are reading only 1 digit at a time.
Hence change the below.
fscanf(myFile, "%1d", &numberArray[i]);
to
fscanf(myFile, "%d", &numberArray[i]);
And your array should be of size number of integers in the file.
int numberArray[6];
for (int i = 0; i < 6; i++)
or
while (fscanf(myFile, "%d", &numberArray[i++]) == 1);
#include <stdio.h>
#include <stdlib.h>
int main(void) {
FILE *myFile = fopen("numbers.txt", "r"); // just init your variable directly
if (!myFile) { // Always check if there is no error
return EXIT_FAILURE; // handle it as you like
}
#define SIZE 16 // Avoid magic number
int numberArray[SIZE];
size_t n = 0; // n will represent the size of valid values inside the array
// Always check if scanf family has parsed your input also "%1d" ask to only parse
// one digit, so use %d if you want parse an integer
while (n < SIZE && fscanf(myFile, "%d", numberArray + n) == 1) {
n++;
}
for (size_t i = 0; i < n; i++) {
printf("Number is: %d\n", numberArray[i]);
}
}
I have this c program where I am inputing a number N followed by N more numbers. For example, I'll enter 100 followed by 100 more numbers. For some reason, after so many inputs the scanf function will stop working properly. It's as if it has stopped taking input and will just continue one with whatever value is in size.
The use case I came up with is 100 1 2 3 4 5 6 7 8 9 10... (repeated ten times). then after three or four times of that I'll type in 100 10 9 8 7 6 5 4 3 2 1... (repeated ten times) and then there will be an infinite loop of print statements.
int main(int argc, const char * argv[]) {
int histogram[10000];
int i;
while (1) {
int *rectPtr = histogram;
int size;
scanf("%d", &size);
if (!size) return 0;
for (i = 0; i < size; ++i) {
scanf("%d", rectPtr);
rectPtr++;
}
printf("%d", 1);
printf("\n");
}
return 0;
}
Distrust infinite loops.
In a series of comments, I said:
You're not testing the return value from scanf(), so you don't know whether it is working. The pair of printf() statements is odd; why not write printf("%d\n", 1); or even puts("1");?
Your code does not test or capture the return value from scanf(), so you do not know whether scanf() is reporting a problem. As a general rule, test the return value of input functions to make sure what you thought happened did in fact happen. You could also print out the values read just after you read them:
if (scanf("%d", rectPtr) != 1)
{
fprintf(stderr, "scanf() failed\n");
return 1;
}
printf("--> %d\n", *rectPtr);
rectPtr++;
Similarly when inputting size. Also consider if (size <= 0) return 0;. And using fgets() plus `sscanf() can make reporting errors easier.
j.will commented:
It is great to know if scanf fails, but I want to know why it fails and prevent it from failing. How do I do that?
I responded:
I understand you'd like to know. With scanf(), the best you can do after a failure is usually to read all the characters that follow up to a newline or EOF, and if you want to know what went wrong, then you print those characters too, because scanf() leaves the last character that it read in the input buffer ready for the next input operation.
void gobble(void)
{
printf("Error at: <<");
int c;
while ((c = getchar()) != EOF && c != '\n')
putchar(c);
puts(">>");
if (c == EOF)
puts("<<EOF>>");
}
The first character in the output is what caused the failure.
See also How to use sscanf() in loops?
Hacking your code to match this:
#include <stdio.h>
static void gobble(void)
{
printf("Error at: <<");
int c;
while ((c = getchar()) != EOF && c != '\n')
putchar(c);
puts(">>");
if (c == EOF)
puts("<<EOF>>");
}
int main(void)
{
enum { MAX_VALUES = 10000 };
int histogram[MAX_VALUES];
int size;
while (printf("Number of items: ") > 0 && scanf("%d", &size) == 1 &&
size > 0 && size <= MAX_VALUES)
{
int *rectPtr = histogram;
for (int i = 0; i < size; ++i)
{
if (scanf("%d", rectPtr) != 1)
{
gobble();
return 1;
}
rectPtr++;
}
printf("size %d items read\n", size);
}
return 0;
}
IMO, you need to check the return value of scanf() for proper operation. Please check the below code. I have added some modifications.
To exit from the program, you need to press CTRL+ D which will generate the EOF. Alternatively, upon entering some invalid input [like a char instead of int] wiil also cause the program to beak out of while() llop and terminate.
I have put the sequence to check first scanf(). All others need to be checked, too.
#include <stdio.h>
#include <stdlib.h>
int main(int argc, const char * argv[]) {
int histogram[10000] = {0};
int i;
int *rectPtr = histogram;
int size = 0;
int retval = 0;
printf("Enter the number of elements \n");
while ( (retval = scanf("%d", &size)) != EOF && (retval == 1)) {
rectPtr = histogram;
if (!size) return 0;
printf("Enter %d elements\n", size);
for (i = 0; i < size; ++i) {
scanf("%d", rectPtr); //check in a simmilar way to above
rectPtr++;
}
printf("%d\n", 1111111);
printf("Enter the number of elements: \n");
}
return 0;
}
The output of a sample run
[sourav#broadsword temp]$ ./a.out
Enter the number of elements: 2
Enter 2 elements
1
2
1111111
Enter the number of elements: 3
Enter 3 elements
1
2
3
1111111
Enter the number of elements: 9
Enter 9 elements
0
9
8
7
6
5
4
3
2
1111111
Enter the number of elements: r
[sourav#broadsword temp]$
histogram is declared to have size 10000. You say you do 100 1 2 3 ... repeated 10 times. If I correctly understand that uses 1000 slots in histogram.
If you repeat the test more than 10 times, you exhaust histogram and begin to write past the end of array causing undefined behaviour.
So you must either :
reset recPtr = histogram at each iteration
control recPtr - histogram + size <= sizeof(histogram) after reading size (IMHO better)
And as other said, you should always control input operations : anything can happen outside of your program ...
I'm a programming noob so please bear with me.
I'm trying to read numbers from a text file into an array. The text file, "somenumbers.txt" simply holds 16 numbers as so "5623125698541159".
#include <stdio.h>
main()
{
FILE *myFile;
myFile = fopen("somenumbers.txt", "r");
//read file into array
int numberArray[16];
int i;
for (i = 0; i < 16; i++)
{
fscanf(myFile, "%d", &numberArray[i]);
}
for (i = 0; i < 16; i++)
{
printf("Number is: %d\n\n", numberArray[i]);
}
}
The program doesn't work. It compiles but outputs:
Number is: -104204697
Number is: 0
Number is: 4200704
Number is: 2686672
Number is: 2686728
Number is: 2686916
Number is: 2004716757
Number is: 1321049414
Number is: -2
Number is: 2004619618
Number is: 2004966340
Number is: 4200704
Number is: 2686868
Number is: 4200798
Number is: 4200704
Number is: 8727656
Process returned 20 (0x14) execution time : 0.118 s
Press any key to continue.
change to
fscanf(myFile, "%1d", &numberArray[i]);
5623125698541159 is treated as a single number (out of range of int on most architecture). You need to write numbers in your file as
5 6 2 3 1 2 5 6 9 8 5 4 1 1 5 9
for 16 numbers.
If your file has input
5,6,2,3,1,2,5,6,9,8,5,4,1,1,5,9
then change %d specifier in your fscanf to %d,.
fscanf(myFile, "%d,", &numberArray[i] );
Here is your full code after few modifications:
#include <stdio.h>
#include <stdlib.h>
int main(){
FILE *myFile;
myFile = fopen("somenumbers.txt", "r");
//read file into array
int numberArray[16];
int i;
if (myFile == NULL){
printf("Error Reading File\n");
exit (0);
}
for (i = 0; i < 16; i++){
fscanf(myFile, "%d,", &numberArray[i] );
}
for (i = 0; i < 16; i++){
printf("Number is: %d\n\n", numberArray[i]);
}
fclose(myFile);
return 0;
}
for (i = 0; i < 16; i++)
{
fscanf(myFile, "%d", &numberArray[i]);
}
This is attempting to read the whole string, "5623125698541159" into &numArray[0]. You need spaces between the numbers:
5 6 2 3 ...
Loop with %c to read the stream character by character instead of %d.
There are two problems in your code:
the return value of scanf must be checked
the %d conversion does not take overflows into account (blindly applying *10 + newdigit for each consecutive numeric character)
The first value you got (-104204697) is equals to 5623125698541159 modulo 2^32; it is thus the result of an overflow (if int where 64 bits wide, no overflow would happen). The next values are uninitialized (garbage from the stack) and thus unpredictable.
The code you need could be (similar to the answer of BLUEPIXY above, with the illustration how to check the return value of scanf, the number of items successfully matched):
#include <stdio.h>
int main(int argc, char *argv[]) {
int i, j;
short unsigned digitArray[16];
i = 0;
while (
i != sizeof(digitArray) / sizeof(digitArray[0])
&& 1 == scanf("%1hu", digitArray + i)
) {
i++;
}
for (j = 0; j != i; j++) {
printf("%hu\n", digitArray[j]);
}
return 0;
}
enter your file input like this
ex:
12
13
22
45
(after every number hit enter)
then run your programm it will run properly