I need my program to create two different text files (midinotes1 & midinotes2) and store two bits of data inside them to be read later on. is there an efficient way without copying the code? i understand i need to have filepointer1 writing to midinotes1 and filepointer2 writing to midinotes2 but i dont know how to make my program do that?
Thanks for any advice!
#include "aservelibs/aservelib.h"
#include <stdio.h>
#include <math.h>
#include <string.h>
float mtof(int note, float frequency);
int main()
{
FILE *textFilePointer;
FILE *textFilePointer2;
int note;
int velocity;
int program;
int counter = 0;
char user;
float frequency;
do
{
printf("Press R to Record (R) or (X) to Exit: \n");
scanf(" %c", &user);
if (user == 'r' || user == 'R')
{
textFilePointer = fopen("/Users/Luke/Desktop/midinotes1.txt", "w");
counter = 0;
if (textFilePointer == NULL)
{
printf("Error Opening file.\n");
}
else
{
do
{
note = aserveGetNote();
velocity = aserveGetVelocity();
if (velocity > 0)
{
fprintf(textFilePointer, "%d\n, %d\n", note, velocity);
counter++;
}
program = aserveGetProgram();
} while (counter < 16);
fclose(textFilePointer);
}
}
else if(user == 'x' || user == 'X')
break;
} while(user != 'x' || user != 'X');
return 0;
}
float mtof(int note, float frequency)
{
frequency = 440.0 * pow(2, (note-69) / 12.0);
printf("%d\n", note);
return frequency;
}
int index = 0;
char filename[128];
do
{
printf("Press R to Record (R) or (X) to Exit: \n");
scanf(" %c", &user);
if (user == 'r' || user == 'R')
{
snprintf(filename, 120, "notes%d.txt", (index+1));
textFilePointer = fopen(filename, "w");
counter = 0;
if (textFilePointer == NULL)
{
printf("Error Opening file.\n");
}
else
{
do
{
// your work
} while (counter < 16);
fclose(textFilePointer);
index++;
}
}
else if(user == 'x' || user == 'X')
break;
} while(user != 'x' || user != 'X');
return 0;
int main()
{
FILE *textFilePointer;
char filename[100];
int note;
int velocity;
int program;
int counter = 0;
char user;
float frequency;
int sample = 0;
do
{
printf("Press R to Record (R) or (X) to Exit: \n");
scanf(" %c", &user);
if (user == 'r' || user == 'R')
{
sample++;
sprintf(filename, "/Users/Luke/Desktop/midinotes%d.txt", sample);
textFilePointer = fopen(filename, "w");
counter = 0;
if (textFilePointer == NULL)
printf("Error Opening file.\n");
else
{
do
{
note = aserveGetNote();
velocity = aserveGetVelocity();
if (velocity > 0)
{
fprintf(textFilePointer, "%d\n, %d\n", note, velocity);
counter++;
}
program = aserveGetProgram();
} while (counter < 16);
fclose(textFilePointer);
}
}
else if(user == 'x' || user == 'X')
break;
} while(user != 'x' || user != 'X');
return 0;
}
Related
How do I keep re-asking the user to enter a valid input that is an integer? I know how to validate an integer range input, but I don't know how to validate a non-integer input when prompted to enter an integer in C.
#include <stdio.h>
int main() {
int menu;
while(true) {
printf("Choose a menu (1-4):\n");
do {
scanf("%d", &menu);
} while(menu < 1 || menu > 4);
if(menu == 1) {
printf("menu 1\n");
} else if(menu == 2) {
printf("menu 2\n");
} else if(menu == 3) {
printf("menu 3\n");
} else if(menu == 4) {
printf("menu 4, exit\n");
break;
}
}
return 0;
}
Any help would be appreciated, I'm sorry if this is a duplicate as everytime I try to search the solution, it's on another language or the thread is asking "how to validate integer input range" instead of non-integer input.
if you want to know when the user has given a non-integer input, a way of doing that is as follows:
char number; /* assuming you'll only need numbers 0-9 */
int menu;
while (true)
{
scanf("%c",&number);
if (number >= '0' && number <= '9')
break;
else
printf("The input is not an integer\n");
}
menu = number - '0' ;
/* write rest of the code here */
If the input is 1 - 999, you can use this:
char *s = malloc(sizeof(char)*4);
while (true)
{
scanf("%s", s);
is_int = true;
menu = 0;
if (s[3] != '\0')
{
printf("integer bigger than 999 not allowed, input again\n");
continue;
}
for (int itr = 0; s[itr] != '\0'; itr++)
if (s[itr] >= '0' && s[itr] <= '9')
{
menu = menu*10 + s[itr]-'0';
}
else
{
is_int = false;
printf("not a valid integer, input again\n");
break;
}
if (is_int && menu != 0)
break;
}
Separate input from parsing.
Consider a helper function. Use fgets() to read, then parse.
// return 0 on success, EOF on end of file
int read_int(const char *prompt, int min, int max, &val) {
#define LINE_N 100
while (1) {
fputs(prompt, stdout);
fflush(stdout);
char buf[LINE_N];
if (fgets(buf, sizeof buf, stdin) == NULL) {
return EOF;
}
char *endptr;
errno = 0;
long val = strtol(buf, &endptr, 0);
// Validate an integer was read and if it is in range
if (endptr > buf && errno==0 && val >= min && val <= max) {
return (int) val;
}
}
}
Usage
int menu;
if (get_int("Choose a menu (1-4):\n", 1, 4, &menu) == EOF) {
printf("Input closed\n");
return 0;
}
if(menu == 1) {
...
// Function push
void push(char x){
stack[++top] = x;
}
//Function pop
char pop(){
if(top == -1)
return -1;
else
return stack[top--];
}
//Arithmetic operator precedence
int priority(char x){
if(x == '(')
return 0;
if(x == '+' || x == '-')
return 1;
if(x == '*' || x == '/')
return 2;
else
return -1;
}
//Function to convert infix to postfix
char postfix(){
char *e, x = '\0';
char exps[20];
e = exps;
printf("\nEnter an expression: \n");
scanf("%s",exps);
while(*e != '\0') //While loop to arrange stack
{
if(isalnum(*e)) //isalnum convert character to ASCII code
printf("%c",*e);
else if(*e == '(')
push(*e);
else if(*e == ')')
{
while((x = pop()) != '(')
printf("%c", x);
}
else
{
while(priority(stack[top]) >= priority(*e))
printf("%c",pop());
push(*e);
}
e++;
}
while(top != -1)
{
printf("%c",pop());
}
exit(0);
return 0;
}
//Function to read file called default input
char read_file(){
char file_location[100];
int user_option=1;
FILE *fp;
character =ch;
while (user_option == 1) {
printf("Enter the location of the file:\n\n");
getchar();
gets(file_location);
fp = fopen(file_location,"r"); //read file
if( fp == NULL )
{
perror("Error while opening the file, \n\n");
exit(EXIT_FAILURE);
}
printf("The contents of the %s file are :\n\n" , file_location);
while( ( *ch = fgetc(fp) !=EOF))
printf("%s" ,ch);
fclose(fp);
postfix();
break;
}
return 0;
}
int manual_input() {
int choice=0;
while(choice == 0)
{
printf("\n\t\t\t\tMENU");
printf("\n\t------------------------------");
printf("\n\n\t 1. Postfix");
printf("\n\t 2. Prefix");
printf("\n\t 3. Both");
printf("\n\t 4. Exit");
printf("\n\tWould you like to convert it to: ");
scanf( "%d", &choice );
switch(choice)
{
case 1:
printf("\nYOU SELECTED OPTION 1 %c",1);
break;
case 2:
printf("\nYOU SELECTED OPTION 2 %c",2);
break;
case 3:
printf("\nYOU SELECTED OPTION 3 %c",3);
break;
default:
printf("\nYOU SELECTED OPTION 4 %c",4);
exit(0);
}
postfix();
}
return 0;
}
int main(){
printf("\nHi ,how would you like to input expression? \n");
printf("1.Get from file\n");
printf("2.Input own expression\n");
scanf("%d",&option);
if (option == 1) {
read_file();
} else {
manual_input();
}
}
Alright so I know my codes a little messy, had some problems indenting certain parts of code. Hopefully you can still understand. So my question is how do I get the characters from the file default.txt and pass it to my postfix function?
In my read_file function I manage to print the characters (ch) using a while loop. My goal here is to store the string so my postfix function can perform some calculation on it since I am trying to convert infix to postfix.
If you're wondering, this program gets user to choose whether to enter an expression through a file or manual input. The expression (which is an infix) is then converted to postfix.
Thanks
like this
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#define MAX_EXP_LEN 256
//Stringification
#define S_(n) #n
#define S(n) S_(n)
int top = -1;
char stack[MAX_EXP_LEN];
void push(char x){
stack[++top] = x;
}
char pop(void){
if(top == -1)
return -1;
else
return stack[top--];
}
int priority(char x){
if(x == '(')
return 0;
if(x == '+' || x == '-')
return 1;
if(x == '*' || x == '/')
return 2;
else
return -1;
}
void postfix(const char *exps){//Use the input expression as an argument
const char *e = exps;
char x = '\0';
while(*e != '\0'){
if(isalnum(*e))
printf("%c",*e);
else if(*e == '(')
push(*e);
else if(*e == ')'){
while((x = pop()) != '(')
printf("%c", x);
} else {
while(priority(stack[top]) >= priority(*e))
printf("%c", pop());
push(*e);
}
e++;
}
while(top != -1){
printf("%c", pop());
}
puts("");
}
void read_file(char exps[MAX_EXP_LEN + 1]){
char file_location[FILENAME_MAX+1] = "";
FILE *fp;
printf("Enter the location of the file:\n\n");
scanf("%" S(FILENAME_MAX) "[^\n]%*c", file_location);
fp = fopen(file_location, "r");
if( fp == NULL ){
perror("Error while opening the file.\n\n");
exit(EXIT_FAILURE);
}
fscanf(fp, "%" S(MAX_EXP_LEN) "s", exps);
fclose(fp);
}
void manual_input(char exps[MAX_EXP_LEN + 1]){
printf("Input expression\n");
scanf("%" S(MAX_EXP_LEN) "s", exps);
}
int main(void){
char exps[MAX_EXP_LEN + 1] = "";
int option;
printf("\nHi ,how would you like to input expression? \n");
printf("1.Get from file\n");
printf("2.Input own expression\n");
scanf("%d", &option);
scanf("%*[^\n]");scanf("%*c");//clear stdin
if (option == 1)
read_file(exps);//exps pass to function
else
manual_input(exps);
postfix(exps);
}
I am trying to write a program that loops asking the user to continuously input either a float, int, or char and echo it back to them until they enter 'q', then the loop ends. I do not understand how to decipher between an int, char, or float before entering the loop. I have tried if (scanf("%c", ch)) and so on for float and int and that works great, but once I added the loop in it's messing me up. I have tried several different combinations, but I have still not found my answer.
Here is one attempt to show you exactly what I am trying to do:
char ch;
int num = 0;
float fl = 0;
printf("Enter a value: ");
while(ch != 'q') {
if (scanf("%c", &ch) && !isdigit(ch)) {
printf("You entered a character %c\n", ch);
}
else if (scanf("%d", &num)) }
printf("You entered an integer %d\n", num);
}
else if (scanf("%d", &num)) {
printf("You entered a floating point number %f\n", fl);
}
printf("Enter another value: ");
}
}
This keeps doing something strange and I cannot pinpoint my problem. Thank you in advance!
You cannot accomplish that with your approach. You can scan a line and parse it accordingly:
char line[128]; /* Create a buffer to store the line */
char ch = 0;
int num;
float fl; /* Variables to store data in */
int r;
size_t n; /* For checking from `sscanf` */
/* A `do...while` loop is best for your case */
do {
printf("Enter a value: ");
if(fgets(line, sizeof(line), stdin) == NULL) /* If scanning a line failed */
{
fputs("`fgets` failed", stderr);
exit(1); /* Exits the program with a return value `1`; Requires `stdlib.h` */
}
line[strcspn(line, "\n")] = '\0'; /* Replace `\n` with `'\0'` */
r = sscanf(buffer, "%d%zn", &num, &n);
if(r == 1 && n == strlen(line)) { /* If true, entered data is an integer; `strlen` requires `string.h` */
printf("You entered an integer %d\n", num);
}
else{
r = sscanf(buffer, "%f%zn", &fl, &n);
if(r == 1 && n == strlen(line)) { /* If true, entered data is a float; `strlen` requires `string.h` */
printf("You entered a floating point number %f\n", fl);
}
else{
if(strlen(line) == 1) /* If true, entered data is a character; `strlen` requires `string.h` */
{
ch = line[0];
printf("You entered a character %c\n", ch);
}
else{ /* Entered data is something else */
printf("You entered \"%s\"\n", line);
}
}
}
}while(c != 'q');
Disclaimer: I wrote the above code using a mobile and I haven't tested it.
Update (did not test and wrote with my mobile):
#include <stdio.h>
#include <ctype.h>
#include <stdbool.h>
int main(void)
{
int c = 0;
bool random = false;
bool flag = true;
bool is_float = false, is_char = false, is_number = false;
do{
c = getchar();
if(c == EOF)
break;
if(!random)
{
if(isdigit(c))
{
is_number = true;
}
else if(c == '.')
{
if(is_number)
{
if(is_float)
{
random = true;
}
else
{
is_float = true;
}
}
else if(!is_number && !is_float && !is_char)
{
is_float = true;
}
}
else if(c == '-' && !is_float && !is_number && !is_char);
else if(isalpha(c))
{
if(is_char)
random = true;
else
{
is_char = true;
if(c == 'q')
flag = false;
}
}
else
{
random = true;
}
if((is_char && is_float) || (is_char && is_number))
random = true;
if(c == '\n' && !is_char && !is_float && !is_number)
random = true;
}
if(c == '\n')
{
if(random)
/* puts("You entered a random string!"); */
puts("Invalid input!");
else if(is_float)
puts("You entered a float!");
else if(is_number)
puts("You entered a number!");
else if(is_char)
puts("You entered a character!");
else
puts("Error!");
if(!flag && !is_number && !is_float && !random)
flag = false;
else
flag = true;
is_char = is_float = is_number = random = false;
}
}while(flag);
puts("Done");
return 0;
}
This is what the items.txt contains:
275,Fresh Fish,12.34,0
386,Soft kleenex,45.67,1
240,Ultra Tide,24.34,1
916,Red Apples,123.45,0
385,Magic Broom,456.78,1
495,Liquid Soap,546.02,1
316,Chocolate Cookies,78.34,1
355,Organic Milk,24.34,0
846,Dark Chocolate,123.45,1
359,Organic Banana,99.99,0
How can I rewind the file when user enters "Y"? It works if I enter the right value the first time.
#include <stdio.h>
#define TAX (0.13)
void keybFlush(){
while(getchar() != '\n');
}
int getInt(){
int val;
char nl = 'x';
while (nl != '\n'){
scanf("%d%c", &val, &nl);
if (nl != '\n'){
keybFlush();
printf("Invalid Integer, please try again: ");
}
}
return val;
}
int yes(){
char ch = 'x';
int res;
do{
ch = getchar();
res = (ch == 'Y' || ch == 'y');
keybFlush();
} while (ch != 'y' && ch != 'Y' && ch != 'n' && ch != 'N' && printf("Only (Y)es or (N)o are acceptable: "));
return res;
}
int main(){
int upc, userUpc, found = 0;
double price;
int isTaxed, i;
char item[21], ch, x, y;
FILE* fptr = fopen("items.txt", "r");
if (fptr){
do {
userUpc=getInt();
printf(" UPC | Name | Price | Tax | Total\n"
" -----+--------------------+-----------+---------+-----------\n");
printf("its : %d\n", userUpc);
while (!feof(fptr)){
fscanf(fptr, "%d,%[^,],%lf,%d", &upc, item, &price, &isTaxed);
if ( upc == userUpc){
if(!feof(fptr)){
printf("%-6d|%-20s|%11.2lf|", upc, item, price);
if (isTaxed)
printf("%9.2lf|%11.2lf\n", price * TAX, price * (1+TAX));
else
printf("%9.2lf|%11.2lf\n", 0.0, price);
found = 1;
}
}
}
if (!found){
printf("Can't find any matched records\n");
}
printf("Do you want to continue: ");
i=yes(); // if yes, rewind the file
} while (!userUpc || (i == 1));
fclose(fptr);
}
else{
printf("could not open the file\n");
}
return 0;
}
If I enter "y" to continue and the right value, it doesn't seem to output correctly.
To change the position of your file cursor to the beginning of the file:
fseek(filePtr, 0, SEEK_SET);
more on file manipulation :
http://www.gnu.org/software/libc/manual/html_node/File-Positioning.html
I am trying have a program end when the user hits the Enter key. For some reason it doesn't seem to work. When I use "char c is not equal to enter key" it takes in an extra integer in c (the last inputted integer). What is the problem with this code?
#include <stdio.h>
#include <stdlib.h>
#define framenumber 4
int test1 =0;
int test2=1;
int main(void)
{
int mainarray[framenumber][2] = {0}, nHP = 3, takein, iPT;
char c = getchar();
printf("Enter: ");
while(1)
{
char c = getchar();
if(c == '\n') {
printf("here");
}
else
{
printf("not enter\n");
takein = atoi(&c);
for (iPT = 0; mainarray[iPT][test2] != takein && iPT < framenumber; iPT++);
if (mainarray[iPT][test2] != takein)
{
//search for a victim
do {
nHP = (nHP + 1) % framenumber;
} while ( !( mainarray[nHP][test1] == 1 ? mainarray[nHP][test1] = 0 : 1 ) );
//update the page table
mainarray[nHP][test1] = 1;
mainarray[nHP][test2] = takein;
}
else
{
mainarray[iPT][test1] = 1;
}
puts("page table:");
for (iPT = 0; iPT < framenumber; iPT++)
{
printf("%s %d, %d.\n", iPT == (nHP + 1) % 4 ? ">": " ", mainarray[iPT][test1], mainarray[iPT][test2]);
}
putchar('\n');
printf("Enter: ");
}
}
return 0;
}
Do not create block variable. (In while loop).
char c='\0'; /* initialize with 0 */
printf("Enter: ");
while(c!='\n') /* loop terminate condition */
{
c= getchar(); /* remove declaration */
if(c =='\n')
{
printf("here");
}
else
{
getchar(); /* read (eat) an extra input */
printf("not enter\n");
....