I'm trying to get input in an array, I expect input like the following.
5 (Number of the second dimensions in the array)
2 (Number of the first dimensions in the array)
So we get an array deeln[2][5] in this example. I try to get it with the following code:
#include <stdio.h>
#include <string.h>
#include <stdbool.h>
bool isinarray(int val, int *arr, int size){
int countimp;
for (countimp=0; countimp < size; countimp++) {
if (arr[countimp] == val)
return true;
}
return false;
}
int main(void){
int k, d, ci, cj, ck, ta;
//get input
scanf("%i", &k);
scanf("%i", &d);
int deeln[d][k], temp[k];
for(ci = 0; ci < d; ci++){
printf("d= %i, ci= %i \n", d, ci);
scanf("%s", temp);
for(cj = 0; cj < k; cj++){
deeln[ci][cj] = temp[cj*2]-'0';
}
}
//loop while.
}
But i've got a problem, whenever i try to input, the program runs automaticly without getting any input when it loops around the third scanf for the 2nd or 3rd time. So then i'm not able to input anything.
What to do? Has it something to do with pointers or am i using scanf wrong?
UPDATE:
If I enter a printf after printf("cj is nu %i \n", cj); then the output also just came after the loop was going its own way. and not before i should give more input, using the third scanf.
The solution of my question was quite easy. I found it after thinking of my input. The problem was that in the input, as described, there were spaces. Somehow scanf can't handle with spaces, unless you use some other syntax. But my solution is to just use fgets instead of scanf where I wanted to get the input. So the new and working code is as follows:
#include <stdio.h>
#include <string.h>
#include <stdbool.h>
bool isinarray(int val, int *arr, int size){
int countimp = 0;
for (countimp=0; countimp < size; countimp++) {
if (arr[countimp] == val)
return true;
}
return false;
}
int main(void){
int t, k = 0, d = 0, ci = 0, cj = 0, ta = 0;
//get input
scanf("%i", &k);
scanf("%i", &d);
char temp[20];
int deeln[d][k];
memset(deeln, 0 , sizeof(deeln));
memset(temp, 0 , sizeof(temp));
for(ci = 0; ci < d; ci++){
fgets(temp, 20, stdin);
for(cj = 0; cj < k; cj++){
ta = cj*2;
deeln[ci][cj] = temp[ta]-'0';
}
}
//loop while.
return 1;
}
Thanks for helping everbody, even though we all didn't came to this. But I hope it will help others!
Two places to look:
1)
cj = 0;//initialize cj before using here
scanf("%i", &temp[cj]);//temp is both an array, and an int. Fix your format specifier,
//and use an index operator - temp[?] (not sure I am using the right index)
2)
deeln[ci][cj] = temp[cj*2]-'0'; //fix your logic here (array index will be exceeded)
An example of working code...
int main(void){
int k, d, ci, cj, ck, ta;
//get input
scanf("%i", &k);
scanf("%i", &d);
int deeln[d][k], temp[k];
for(ci = 0; ci < d; ci++){
printf("d= %i, ci= %i \n", d, ci);
for(cj = 0; cj < k; cj++){
if(scanf("%i", &temp[cj]) != EOF)
{
deeln[ci][cj] = temp[cj]-'0';
}
else deeln[ci][cj] = -1;
}
}
getchar();
//loop while.
}
you can play with the index of temp[cj] to make it what you actually want, but I assume you are intending to read from stdin, then populate deeln[][] with that value, for each scanf.
If you want to parse a string containing spaces and digets, "1 3 8 5 3", you could use strtok()
But your code as it is is not reading a string in, it is reading integers.
This is not perfect, you will have to do some debug, but will illustrate strtok(). You have to enter spaces between each digit after indices are selected: i.e.:
3
3
4 6 8
2 4 7
1 2 8
int main(void){
int k, d, ci, cj, ck, ta;
//get input
scanf("%i", &k);
scanf("%i", &d);
char inStr[d][k*5]; //space for up to k 3 digit numbers with 1 space each
char *buf=0;
int deeln[d][k], temp[k];
for(ci = 0; ci < d; ci++){
printf("d= %i, ci= %i \n", d, ci);
if(scanf("%s ", inStr[ci]) != EOF)
{
buf = strtok(inStr[ci], " ");
cj = 0;
while(buf && (cj < k))
{
deeln[ci][cj] = atoi(buf);
cj++;
}
}
}
//getchar();waits for user input, pauses execution
}
Related
I've searched for solutions to that problem and couldn't find any that match mine.
I wrote a program that gets two arrays of integers and return the scalar product between them. It works fine when I'm submitting the input manually, but when I try to read the input from a text file, I encounter that Segmentation fault.
Edit: I'm talking about stdin redirection
I would be grateful for some help.
The code is:
#include <stdio.h>
#define MAXLIMIT 100
int scalar_product(int[], int[], int);
void set_array(int[]);
int main(){
int arr1[MAXLIMIT], arr2[MAXLIMIT];
int size, result;
set_array(arr1);
set_array(arr2);
printf("Enter the vectors' dimension: ");
scanf("%d", &size);
result = scalar_product(arr1, arr2, size);
printf("The scalar product is: %d \n", result);
return 0;
}
void set_array(int a[]){
int i;
printf("Please enter a vector with up to %d elements: \n", MAXLIMIT);
for (i = 0; i < MAXLIMIT - 1 && (scanf("%d", &a[i]) != EOF); i++);
}
int scalar_product(int a1[], int a2[], int size){
int product = 0, i;
for (i = 0; i < size; i++){
product += a1[i] * a2[i];
}
return product;
}
and the text file contains:
1 -2 3 -4
6 7 1 -2
4
HEre
void set_array(int a[]) {
int i;
printf("Please enter a vector with up to %d elements: \n", MAXLIMIT);
for (i = 0; i < MAXLIMIT - 1 && (scanf("%d", &a[i]) != EOF); i++);
}
When reading from the console you will never hit EOF (unless you enter ctrl-D which I guess you didnt) so your set_array loops just keep going, reading from the file. You read all the data in the first set_array and read nothing in the second one because you have finished the input file
the actualk failure was that you ran off the end of the file, so the scanf of size failed and you were trying to read a random sized array in the function scalar_product.
Test the return from scanf always
What you need to do is put a count in the file before the first array so you know how many items to read into arr1 and I suggest a count before the second lot too.
ie
void set_array(int a[]) {
int i;
int count = 0;
printf("Please enter how many elements you want to enter, max = %d \n", MAXLIMIT);
scanf("%d", &count);
if(count > MAXLIMIT) count = MAXLIMIT;
for (i = 0; i < count && (scanf("%d", &a[i]) != EOF); i++);
}
I know this question has been asked before and I am sorry but I cannot find a solution for my code. I am a new student to the C language and my problem is that I am trying to create a while loop that continually asks the user to update the data if they enter non integers. I have looked into the isdigit() function and I think that would work. I just can't seem to make it work for my code, as in whenever I try creating a while loop with isdigit as its condition, I either get a infinite loop, or my isdigit returns values that I was not expecting. I think the problem could be that my scanf() is scanning three integers separated by '/' but I am not sure if that is where the problem is. Any help would be appreciated.
Here is the code in question
#include <stdio.h>
#include <ctype.h>
int calcAge(int a, int b, int c, int d, int e, int f);
int maxHeart(int a);
int heartRangeLow(int a);
int heartRangeHigh(int a);
int main(void) {
int birthMonth = 0, birthDay = 0, birthYear = 0, targetRangeLow = 0;
int month = 0, day = 0, year = 0, age = 0, heartRate = 0, targetRangeHigh = 0;
printf("What is your birthday?(written in MM/DD/YYYY)"
"\nHit Enter after you type it in.\n");
scanf_s("%d/%d/%d", &birthMonth, &birthDay, &birthYear);
printf("What is the date today?(written as MM/DD/YYYY)"
"\nHit Enter after you type it in.\n");
scanf_s("%d/%d/%d", &month, &day, &year);
age = calcAge(birthMonth, birthYear, birthDay, month, day, year);
heartRate = maxHeart(age);
targetRangeLow = heartRangeLow(heartRate);
targetRangeHigh = heartRangeHigh(heartRate);
printf("You are %d years old.\n", age);
printf("Your maximum heart rate is %d beats per minute.\n", heartRate);
printf("Your target-heart-range is %d"
" to %d beats per minute.\n", targetRangeLow, targetRangeHigh);
system("pause");
return 0;
}
int calcAge(int a, int b, int c, int d, int e, int f)
{
int age;
age = ((f * 10000 + d * 100 + e) - (b * 10000 + a * 100 + c)) * .0001;
return age;
}
int maxHeart(int a)
{
int heartRateMax;
heartRateMax = 220 - a;
return heartRateMax;
}
int heartRangeLow(int a)
{
int lowTarget = a * .5;
return lowTarget;
}
int heartRangeHigh(int a)
{
int highTarget = a * .85;
return highTarget;
}
to create a while loop that continually asks the user to update the data if they enter non integers.
Make a helper function.
Read user input with fgets() into a buffer and then parse it for valid input with strtol() or sscanf(), is...(), etc. Return 1, 0, EOF depending on input.
// Untested code
// 1 success
// 0 bad input
// EOF end of file
#define DATE_STR_SIZE 80
int enter_date_mdy(char *prompt, int *m, int *d, int *y) {
if (prompt) {
fputs(prompt, stdout);
fflush(stdout);
}
char buffer[DATE_STR_SIZE];
if (fgets(buffer, sizeof buffer, stdin) == NULL) {
return EOF;
}
int n = 0;
sscanf(buffer, "%d /%d /%d %n", m, d, y, &n);
// If scan incomplete or extra junk at the end ....
if (n == 0 || buffer[n]) {
return 0;
}
// Additional tests as desired ....
if (*m < 1 || *m > 12 || *d < 1 || *d > 31) {
return 0;
}
return 1;
}
Sample use
int count;
do {
count = enter_date_mdy("What is your birthday?(written in MM/DD/YYYY)",
&birthMonth, &birthDay, &birthYear);
if (count == EOF) return(EXIT_FAILURE);
} while (count < 1);
do {
count = enter_date_mdy("What is the date today?(written as MM/DD/YYYY)",
&month, &day, &year);
if (count == EOF) return(EXIT_FAILURE);
} while (count < 1);
Tip: instead of "What is the date today?", research time(), mktime().
With the code below, I'd always run into "Stack around the variable 'UserCode' was corrupted.
If I'm not mistaken, when I do userCode = (char*)malloc(sizeof(char)*N);, shouldn't it create an "array" with size of char*n ? I'm guessing my issue is either with my declaration of an array, or my pointer arithmetic.
Any help would be highly appreciated.
#include "stdafx.h"
#include <math.h>
int userPrompt1() {
int numOfAlphabets = 0;
printf("Please enter a number from 1 to 8 to choose how many alphabets you want\n");
scanf_s(" %d", &numOfAlphabets);
if (numOfAlphabets > 8 || numOfAlphabets < 0) {
printf("Sorry! Invalid number entered. Try again. \n");
numOfAlphabets = userPrompt1();
}
return numOfAlphabets;
}
int userPrompt2() {
int numOfLetters = 0;
printf("Please enter the number of letters you want to guess\n");
scanf_s(" %d", &numOfLetters);
if (numOfLetters < 0) {
printf("Sorry! Invalid number entered. Try again. \n");
numOfLetters = userPrompt2;
}
return numOfLetters;
}
int tryCalculator(int K, int N) {
int tries = 0;
tries = 1 + ceil(N * log2(K));
return tries;
}
void codeGenerator(char codeGuessIn[], char letters[], int size) {
for (int i = 0; i < size; i++) {
int rando = rand() % size;
codeGuessIn[i] = letters[rando];
printf(" %c", codeGuessIn[i]);
}
printf("\n");
}
void codeChecker(char codeGuessIn[], char generatedCode[], int size) {
int correctAlphabets = 0;
for (int i = 0; i < size; i++) {
if (codeGuessIn[i] == generatedCode[i]) {
correctAlphabets++;
}
}
printf(" %d in correct place \n", correctAlphabets);
}
void getUserCode(int size, char *userCode[]) {
for (int i = 0; i < size; i++) {
printf("Please enter letter #%d \n", i+1);
getchar();
scanf_s(" %c", &userCode[i]);
}
}
int main(void)
{
char letters[8] = { 'A','B','C','D','E','F','G','H' };
char *generatedCode; //array to hold generated code
char *userCode; // array to hold generated code.
int K = userPrompt1(); //how many different alphabets in code
int N = userPrompt2(); //how many letters in code
int tries = tryCalculator(K, N);
//int gameEnd = 1;
userCode = (char*)malloc(sizeof(char)*N);
generatedCode = (char*)malloc(sizeof(char)*N);
codeGenerator(generatedCode, letters, N);
getUserCode(N, &userCode);
//codeChecker(userCode, generatedCode, N);
return 0;
}
void getUserCode(int size, char *userCode[]) {
scanf_s(" %c", &userCode[i]);
Here, userCode[i] is a char * (pointer-to-char), &userCode[i] is a char ** (pointer-to-pointer-to-char), and scanf("%c") expects a char *. A good compiler would warn about that.
I think what you meant to do here is something like:
void getUserCode(int size, char *userCode) {
scanf_s(" %c", &userCode[i]);
}
int main(void) {
char *userCode = malloc(N);
getUserCode(N, userCode);
}
The printf(), getchar(), scanf() combination here reeks of the bad habits created by scanf: you're discarding the first character entered by the user because you're relying on an extra character in the input buffer.
See http://c-faq.com/stdio/scanfprobs.html and read full lines of input with fgets() instead of using scanf().
Also,
int userPrompt2() {
int numOfLetters = 0;
...
numOfLetters = userPrompt2;
}
You're assigning a function pointer to an int. (A normal compiler should warn about this.) If the idea here is to call the function again to repeat the prompt in case the user enters something silly, it's probably a better idea to use a loop instead of a recursive call anyway.
I wrote a program in C which takes as an input a value and an ordered Array of integers and performs a ternary search to find the value(if it exists) inside the Array.
I have seen all the possible problems with the usage of scanf and the related topics here in Stackoverflow.
I have noticed that there is a difference if I call the 2 scanf functions in reverse order.
If I use the code as it is below. First read the value and after the array from the user, the program and scanf functions as expected.
printf("Enter the value to be searched in the Array: ");
int k;
scanf(" %d", &k);
printf("Type elements of A(sorted) separated by spaces (type 'end' to stop): ");
i = 0;
while(scanf("%d", &A[i]) == 1) {
i++;
}//while
Although if I use the scanf inputs in the reverse order the second scanf never stops to get user input and read values left in the buffer.
printf("Type elements of A(sorted) separated by spaces (type 'end' to stop): ");
i = 0;
while(scanf("%d", &A[i]) == 1) {
i++;
}//while
printf("Enter the value to be searched in the Array: ");
int k;
scanf(" %d", &k);
I cannot understand what is the difference in the calling order.
I have tried the solutions mentioned in the other threads but none worked.
Just as a reference here is the whole code(working as expected):
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
int ternarySearch(int A[], int l, int r, int k){
int i;
int first,second;
if(l>r){
return -1;
}
i= (r - l)/3;
if(i==0){
i++;
}
first = i+l-1;
second = i*2+l-1;
if(A[first]==k){
return first;
}
else if(A[first]>k){
ternarySearch(A, l, first-1, k);
}
else
{
if(A[second]==k)
return second;
else
if(A[second]>k)
ternarySearch(A, first+1,second-1, k);
else
ternarySearch(A, second+1,r, k);
}
}
int main(){
const int maxarraylen = 1000;
int i;
int n;
int A[maxarraylen];
char string[250];
printf("Enter the value to be searched in the Array: ");
int k;
scanf(" %d", &k);
printf("Type elements of A(sorted) separated by spaces (type 'end' to stop): ");
i = 0;
while(scanf("%d", &A[i]) == 1) {
i++;
}//while
n=i-1;
//We assume the array is sorted otherwise we can use any sorting algorithm e.g. code from task1
scanf(" %d", &k);
int result;
result=ternarySearch(A, 0, n, k);
if(result==-1){
printf("The value was not found in the Array.\n");
}
else{
printf("The value was found in position no. %d.\n", result);
}
return 0;
}
Your problem is that you are not 'stepping over' your end input.
We can see this by doing an experiment using the following program:
#include <stdio.h>
#include <stdlib.h>
void main(void) {
FILE *f;
long f_pos;
int ret;
int i;
int data[5];
int data_last;
int search;
f = fopen("./input.txt", "r");
if (f == NULL) {
perror("fopen()");
return;
}
/* read in the values for the array */
data_last = -1;
for (i = 0; i < 5; i++) {
ret = fscanf(f, "%d", &(data[i]));
printf("fscanf(data[%d]): ret: %d\n", i, ret);
f_pos = ftell(f);
printf("ftell(): %ld\n", f_pos);
if (ret != 1) {
break;
}
data_last = i;
}
/* check that we read in at least one value */
if (data_last == -1) {
printf("no input data!\n");
return;
}
/* insert 'fix' here */
/* pre-load the 'search' with known garbage */
search = 987;
/* now read in the search value */
ret = fscanf(f, "%d", &search);
printf("fscanf(search): ret: %d\n", ret);
f_pos = ftell(f);
printf("ftell(): %ld\n", f_pos);
/* print out our info */
for (i = 0; i <= data_last; i++) {
printf("data[%d]: %d\n", i, data[i]);
}
printf("search for: %d\n", search);
return;
}
With the following data in input.txt:
123
456
end
456
The output is as follows:
fscanf(data[0]): ret: 1
ftell(): 3
fscanf(data[1]): ret: 1
ftell(): 7
fscanf(data[2]): ret: 0
ftell(): 8
fscanf(search): ret: 0
ftell(): 8
data[0]: 123
data[1]: 456
search for: 987
ftell() tells us where the file's cursor is, and in this case we can see that it is at byte 8... the e of the input line end.
It doesn't get past it, and thus the next attempt to read a number (%d) will fail too!
It's also a good idea to check the return values! We can see that the fscanf(&search) call has failed to read a number!
The solution is to insert this snippet just after we check that we recieved array values:
/* this is the 'fix' */
ret = fscanf(f, "end");
printf("fscanf(end): ret: %d\n", ret);
f_pos = ftell(f);
printf("ftell(): %ld\n", f_pos);
I'm wondering how to make the compiler repeat itself if the user presses a random button at the end. But if the user presses "0" the compiler exits.
My code:
#include<stdio.h>
#include<stdlib.h>
#include <math.h>
#include <float.h>
struct mystruct
{
float startnummer;
float hoppnummer;
float svarighetsgrad;
float domarpoangs[7];
};
int main(void)
{
struct mystruct data;
float max = 0;
float min = FLT_MAX;
float sum = 0;
float avg = 0;
int i = 0;
float resultat = 0;
printf("Startnummer: \n");
scanf_s("%f", &data.startnummer);
printf("Hoppnummer:\n");
scanf_s("%f", &data.hoppnummer);
printf("Svarighetsgrad:\n");
scanf_s("%f", &data.svarighetsgrad);
for (i = 0; i < 7; i++)
{
printf("domarpoang %d\n", i + 1);
float f;
if (scanf_s("%f", &f) == 1)
{
if (f < min) min = f;
if (f > max) max = f;
data.domarpoangs[i] = f;
}
else
{
printf("error parsing float\n");
exit(0);
}
}
system("cls");
printf("Startnummer: %.1f \n", data.startnummer);
printf("Hoppnummer: %.1f\n", data.hoppnummer);
printf("Svarighetsgrad: %.1f\n", data.svarighetsgrad);
for (i = 0; i < 7; i++)
{
printf("Domarpoang %d: %.1f\n", (i + 1), data.domarpoangs[i]);
}
for (i = 0; i < 7; i++)
{
sum += data.domarpoangs[i];
}
sum = sum - (max + min);
avg = sum/5;
resultat = avg * 3 * data.svarighetsgrad;
printf("Hoppoang:%.2f \n", resultat);
printf("Tryck tangent for nytt hopp!");
getchar();
getchar();
return 0;
}
*If the user presses random button, the compiler repeat itself from the beginning
*If the user presses 0, the compiler exits.
Any help is appreciated, thank you.
This answer puts a loop around the body of your main() code, taking care to re-initialise some of the variables for the next iteration.
There are many SO questions about getting keyboard input and clearing the debris. I know of no simple standard ways of testing for keyboard input such as kbhit(), for taking a single key input such as getch() or for flushing the input. Even getchar() is horrible - it won't return until you have pressed "Enter" which it leaves in the input buffer. This has resulted in many SO answers with impenetrable (to me) formats for scanf() to flush the input, or testing if (getchar() == EOF) - which does not respond to the "Enter" key.
So I have put a simple wrapper around the main() code, which terminates when '0' is entered followed by a control char (because fgets() appends the newline) or terminator. This removes the need to clean up the input - except in the case where the user inputs some silly typing. GIGO!
#include <stdio.h>
#include <float.h>
#define BUFFSIZE 10
struct mystruct {
float startnummer;
float hoppnummer;
float svarighetsgrad;
float domarpoangs[7];
};
int main(void)
{
char kbuff [BUFFSIZE+1];
struct mystruct data;
float max;
float min;
float sum;
float avg;
int i;
float resultat;
do {
max = 0; // initialise for each loop
min = FLT_MAX;
sum = 0;
printf ("Body of your main loop\n");
fgets(kbuff, BUFFSIZE, stdin);
} while (kbuff[0] != '0' || kbuff[1] >= ' ');
return 0;
}