I am taking different transistor data from a file. The program stores that in a structure. It then prompts for an input from the user. User enters 5 different values, eg 12 0.03 100 320 65 and then the program takes these values and compares it to the data from the file and sees if any transistors would be suitable for the parameters you have entered.
The program then prompts the user again, and this repeats until the letter q is entered, which ends the program.
The problem I'm having - and I've been trawling the internet for hours trying to find a solution but none of them have worked - is that any input after the first set isn't accepted. So it looks like this.
Please input: Voltage Current Power Frequency Gain
15 0.1 200 100 80
15 0.1 200 100 80
ALL RELEVANT TRANSISTORS
Please input: Voltage Current Power Frequency Gain
20 0.3 100 150 40
?1 2 3 4 5
The question mark is always a strange character. In the past few hours it has been a ? in a diamond, the letter P, and a small square with 0010 in it. Everything I have found on the internet says this should work. What am I missing?
Here's my input function
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <stdlib.h>
#define MAX 15
struct input{
int volt, power, freq, gain;
float amp;
};
struct input inputs[MAX_IN];
int CHK =1, number=0;
int input_function1()
{
const char check[3] = {'\0'};
int i;
const char inp[30] = {'\0'};
printf("Please input: Voltage Current Power Frequency Gain\n");
fgets(inp, 30, stdin);
puts(inp); //Prints out the string to see if the input has been correctly accepted
ungetc(inp, stdin);
sscanf(inp, "%s", &check);
if(check[0]!='q' && check[1]!='q' && check[2]!='q')
{
sscanf(inp, "%d %f %d %d %d", &inputs[number].volt, &inputs[number].amp,
&inputs[number].power, &inputs[number].freq, &inputs[number].gain);
}
}
Below is how I am calling the function. check_function is the function which checks the input transistor against the database.
while(CHK==1)
{
input_function1();
check_function();
++number;
}
You are declaring a const char array like this:
const char test[30] = {'\0'};
and that actually creates a string/array that is not editable and the terminating 0 that should mark the end of a string is the only character in this array. Also this zero is being set at the test[0].
Here's a little example which fixes some stuff of your current snippet:
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <stdlib.h>
#include <conio.h>
#define MAX 15
struct input {
int volt, power, freq, gain;
float amp;
};
struct input inputs[MAX];
int fill_input(int index) {
char check[4];
char inp[30];
printf("Please input: Voltage Current Power Frequency Gain\n");
fgets(inp, 30, stdin);
puts(inp);
sscanf(inp, "%s", &check);
if (strcmp(check, "qqq") == 0) {
return 0;
}
sscanf(inp, "%d %f %d %d %d", &inputs[index].volt, &inputs[index].amp,
&inputs[index].power, &inputs[index].freq, &inputs[index].gain);
return 1;
}
int main(int argc, char *argv[]) {
int index = 0;
while (1 && index < MAX) {
if (!fill_input(index)) break;
index++;
}
printf("End");
getch();
}
The goal of the above snippet is to help you to move on.
Few notes for you to consider though:
Try to avoid global variables as much as possible
The current provided version is far away from being optimal, think why is that and don't just copy paste other's code, try to figure out what a good function is all about. The most important lesson for you here should be how to code proper functions
The errors in your snippet are related to arguments not matching properly the datatypes, for instance, take a look to the fgets docs, you can see the first argument is char*, you were using const char*, datatypes should match
Try to refactor the function till is good one and learn as much as possible from each refactoring
Have fun coding! <--- most important one
Related
I need to code a program that takes input from a given register (sending bytes) to a printer and the first sentence has to be the student name in uppercase which I tried with toupper() by converting the register to a given variable (char ch;), though the given result was not met.
The next one is for the faculty number (it says in "condensed" font? Not sure what that is supposed to mean, please correct me if I'm wrong but I take it as it's supposed to be all lowercase?)
Finally, the last given sentence should print the date on the screen as well but unfortunately it doesn't say whether it should take the system date or whatever. (I've done it using printf and written the current date)
Here is the code I've written so far:
(the toupper() function does not work)
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include <dos.h>
#include <bios.h>
#include <string.h>
#include <ctype.h>
void main()
{
int i; char ch; char row[1000];
union REGS r;
clrscr();
memset(row,0,sizeof(row));
r.h.ah=0; // function 0h
int86(0x16,&r,&r);
for(i=0; i<1;i++)
{
ch = row[i];
printf("student name", toupper(ch));
ch = r.h.al;
r.h.ah=0;
int86(0x17,&r,&r);
r.x.dx=0;
printf("\n");
printf("16630960",row[i]);
row[i]=r.h.al;
r.h.ah=0;
int86(0x17,&r,&r);
r.x.dx=0;
printf("\n");
printf("10-04-2022",row[i]);
row[i]=r.h.al;
r.h.ah=0;
int86(0x17,&r,&r);
r.x.dx=0;
}
r.h.ah=0;
r.h.al=0x0A;
r.x.dx=0;
int86(0x17,&r,&r);
getch();
delay(100);
}
I am not sure what all that DOS interrupt thing is doing but I can at least fix the 'uppercase is broken' complaint
printf("student name", toupper(ch));
You are attempting to print one character of the name (thats probably not correct, but lets at least get that one character printed)
printf("student name %c", toupper(ch));
Now you need to fix all the other printfs
to convert whole string to upper case, assuming 'row' contains the string
int len = strlen(row);
for(int i = 0; i < len; i++){
row[i] = toupper(row[i]);
}
What I have till now is this. I am not able to figure out how to take the input as mentioned and solve this problem?
#include<stdio.h>
#include <stdlib.h>
#include<float.h>
int main()
{
char s[50];
float mil,min=FLT_MAX;
while(scanf("%s#%f",s,&mil)!=-1)
{
printf("%s\n",s);
if(mil<min)
min=mil;
}
}
EDIT: My problem is that when I print the string s inside the loop, "Zantro#16.15" is printed whereas I want only "Zantro" to be stored in s and 16.15 to be stored in mil
%s scans up until a whitespace. Scan up until a # instead.
while (scanf("%[^#]#%f", s, &mil) == 2)
Remember to specify the maximum buffer size in the scanning format to protect against overflows:
while (scanf("%49[^#]#%f", s, &mil) == 2)
Well the scanf function can not easily determine, that you want the # sign to be a delimiter. Therefore you need to add an extra step to split up the strings into proper parts and store them for later comparison.
Have a look at strtok function in c.
http://www.c-howto.de/tutorial/strings-zeichenketten/string-funktionen/string-zerteilen/
Here is a solution that prints the requested string:
#include <stdio.h>
#include <stdlib.h>
#include <float.h>
#include <string.h>
int main()
{
char s[50];
char mins[50];
float mil,min=FLT_MAX;
int rc;
int done=0;
while (done == 0)
{
rc = scanf("%49[^#]#%f", s, &mil);
if (rc != 2)
{
done = 1;
continue;
}
if (mil < min)
{
min = mil;
strcpy(mins, s);
}
}
printf("%s\n", mins);
return 0;
}
Execution:
./sc
Zantro#16.15
Zirty#12.5
Gamry#9.8
Gamry
#include<stdio.h>
#include <stdlib.h>
#include<float.h>
int main()
{
char s[50];
float mil, min = FLT_MAX;
while (scanf("%[^#]#%f", s, &mil) == 2)
{
printf("%s\n", s);
if (mil < min)
min = mil;
}
}
Input:Zantro#16.15Zity#12.5Gamry#9.8
OutPut:
Zantro
Zity
Gamry
If you want to split your input in the scanf to string and float, you have to write those two types separately. For example, ("%s %f"). This string tells the function, what will be the arguments types. Therefore, if you write it like this ("%s#%f") the scanf function has a problem to understand, what will be the inputs types. In addition, if you write ("%s #%f") it will get two inputs like this " #". Your problem here is the space between the two arguments. Because, I didnt find how to get the input without this space. I'm recommending you to try splitting the input in another way.
For example, take one string that holds the intaier input to string buffer-> scanf("%s",sBuffer).
and split that to different variables after that.
Quite new to C so apologies for the long read and no doubt rubbish programming.
So my program is reading in a CSV file, containing the specification of 15 different transistors. It then compares an input to the data from the CSV file. After the data is input, the program determines which transistors are most suitable. This is meant to loop until the letter q is entered, which is when the program is meant to stop.
The input is entered as eg.
10 0.05 120 5000 20
for volt, amp, power, freq and gain respectively. The program doesn't care about type, company or price.
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <stdlib.h>
#define MAX 15
#define MAX_IN 10000
struct data{
char type[10], company[10];
int volt, power, freq, gain;
float amp, price;
};
struct input{
int volt, power, freq, gain;
float amp;
};
struct input inputs[MAX_IN];
struct data datas[MAX];
main()
{
int chk = 1, num=0;
while(chk == 1)
{
chk = input_function(&num);
}
}
int input_function(int *number)
{
int j=0;
char check=0;
scanf("%c%d %f %d %d %d", &check, &inputs[j].volt, &inputs[j].amp, inputs[j].power, &inputs[j].freq, &inputs[j].gain);
if(check!='q')
{
check_function(j);
++*number;
++j;
return 1;
}
else
{
return 0;
}
}
num is an integer used to determine how many inputs I have put in so that the check function compares the correct input for the input structure.
In a previously similar problem, using %c%d let it check for both a character and an integer at the same time, but this isn't working.
Previously I had it almost working, but it took q as the first input to voltage - so every input after was off by one. Anyone have any ideas?
scanf, fscanf, and sscanf are broken-as-specified and shouldn't ever be used for anything. Forget you ever heard of them.
Use fgets (or getline if available) to read the entire line. Examine its first character manually. If it is q, exit. Otherwise, use a chain of calls to strtol and strtod to parse the line and convert text to machine numbers. (Pay close attention to the part of the strtol/strtod manpages where they explain how to check for errors; it's a little tricky.)
So as the title suggests for the life of me I cannot get one string to equal the contents of another and then print correctly. I just get gibberish for the string. Here is the code:
#include <stdio.h>
#include <math.h>
#include <string.h>
#include <strings.h>
#define MAX_STRING_LEN 4
int main(void)
{
int opselect, mhour, mminute, rhour, rminute, exit;
char ampm[3];
char am[3] = "AM";
char pm[3] = "PM";
printf("Please enter the military time in following format HH:MM \n");
printf("(Example 13:25)\n");
rhour = 12;
rminute = 30;
mhour = 13;
mminute = 30;
strcpy(am, ampm);
printf("If the military time is %d:%d than the regular time is %d:%d %s.\n\n", mhour, mminute, rhour, rminute, ampm);
return 0;
}
The program returns
If the military time is 13:30 than the regular time is 12:30 gibbersh.
Two random characters in the place of gibbersh. For the life of me I can't see what I am doing wrong. Any help would be much appreciated.
Thank you
You probably wanted to do this:
strcpy(ampm, am); and not strcpy(am, ampm); goes from right to left. right is source, left is dest.
read as:
copy string into first, from second
Looks to me that ampm is not initialized so it just printing whatever is in the memory at the time.
Syntax:
strcpy(destination, source);
In your case source is ampm which have some garbage value. So you are getting unexpected result.
Do like this :- strcpy(ampm,am):
Its been a while now and im still trying to get a certain code to work. I asked some question about different commands etc. before, but now I hope this is the final one (combining all questions in one code).
I basically want to :
*Scan an input (should be character ? )
*Check if its a number
*If not, return error
*Convert that character into a float number
*Copy the value to another variable ( I called it imp here)
Here is what I came up with :
EDITED CODE*
#include<stdio.h>
#include<stdlib.h>
#include<ctype.h>
main(){
int digits;
float imp=0;
char* alpha;
do{
printf("Enter input\n\n");
scanf("\n%c",alpha);
digits=isdigit(alpha);
if(digits==0){
printf("error\n\n");
}
imp=atof(alpha);
}while(digits==0);
}
The problem is this code does not work at all ... It gives me that atof must be of a const char and whenever I try changing it around, it just keeps failing. I am frustrated and forced to ask here, because I believe I have tried alot and I keep failing, but I wont be relieved until I get it to work xD So I really need your help guys.
Please tell me why isnt this code working, what am I doing wrong ? I am still learning C and really appreciate your help :)
EDIT
Error given atm is :
Argument no 1 of 'isdigit' must be of type 'const int', not '<ptr>char'
EDIT
This code compiles fine, but crashes when an input is entered.
#include<stdio.h>
#include<stdlib.h>
#include<ctype.h>
main(){
int digits;
float imp=0;
char* alpha=0;
do{
printf("Enter input\n\n");
scanf("\n%s",alpha);
digits=(isdigit(alpha[0]));
imp=atof(alpha);
}while(digits==0);
}
Why not have scanf do the atof conversion for you?
#include <stdio.h>
int main()
{
float imp=0;
while (1)
{
printf("Enter input\n\n");
if (scanf("%f", &imp) < 1) break;
}
return 0;
}
Your most recent example is failing because alpha is a NULL pointer. Declare it as char alpha[40]; to allocate space for it. You'll probably want to use %40s in your format string to prevent scanf from overflowing alpha.
Also, use strtod instead of atof and you'll know whether the conversion was successful (better than your method of using isdigit which will fail on a negative integer).
You probably need to use %s instead of %c and to put it in char array (char*). You also probably get an error that you need to use const char* and not const char.
You don't want to read just one character - you want to read an entire string...
EDIT:
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
main(){
int digits,i;
float imp=0;
char* alpha = malloc(100); /* 100 is for example */
do{
printf("Enter input\n\n");
scanf("\n%s",&alpha);
for (i = 0; i != 100; ++i)
{
if (alpha[i] == '\0')
break;
if (!isdigit(alpha[i]))
{
printf("error\n\n");
return ...;
}
}
imp=atof(alpha);
}while(true);
}