Can't seem to match input with values in a text file - c

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

Related

How to ignore the ctrl+z, when checking the most common letter in a file (not case sensitive)

The function needs to find the most common character in a file and also get the data from the user. I used ctrl+z to terminate.
The problem is when I enter big character like: A + ctrl+Z, then it counts the Z as the most common one.
(If there is the same amount of character, it will return the biggest alphabetically. Empty file will return '\0').
char commonestLetter(){
char ch;
int count[26] = {0}, max = 0, index, i;
FILE* f = fopen("input.txt","w");
if (f == NULL){
printf("Failed to open the file \n");
return;
}
printf("Please enter the characters one by one, followed by enter\n");
printf("Ctrl + z and enter to finish\n");
while((ch = getchar()) != EOF){
fprintf(f,"%c",ch);
_flushall();
if (isalpha(ch))
count[ch - 'a']++;
}
fseek(f, 0, SEEK_END);
if (ftell(f) == 0){
ch = '\0';
return ch;
}
for (i = 0; i < 26; i++){
if (count[i] >= max){
max = count[i];
index = i;
}
}
fclose(f);
return index + 'A';
}
int main(){
char ch;
ch = commonestLetter();
if(ch)
printf("The commonest letter is %c", ch);
else
printf("No letters in the file");
printf("\n");
system("pause");
return 0;
}
You declared that the function should find the most common letter IN A FILE, but you read letters from stdin.
To get the most common letter ignoring case, you have to use letter-elevating function like tolower().
Try this:
#include <stdio.h>
#include <ctype.h>
char commonestLetter(char *file_name)
{
char ch, max_char = '\0';
int count[26] = {0}, max_count = 0;
FILE *f = fopen(file_name, "r");
if (f == NULL) {
printf("Failed to open the file %s\n", file_name);
return '\0';
}
while (fread(&ch, 1, 1, f) > 0) {
if (isalpha(ch) &&
(++count[tolower(ch) - 'a']) > max_count)
max_char = ch;
}
fclose(f);
return max_char;
}
int main(int argv, char *argc[])
{
char ch;
if (argv < 2) {
printf("Usage: %s filename\n", argc[0]);
exit();
}
ch = commonestLetter(argc[1]);
if(ch)
printf("The commonest letter in the file %s is '%c'\n",
argc[1], ch);
else
printf("No letters in the file %s\n", argc[1]);
return 0;
}

How to pass string from a file to a function? Converting infix to postfix

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

Function call not working in a function

#include<stdio.h>
void clearKeyboard(void){
while(getchar()!='\n');
}
void pause(void){
printf("Press <ENTER> to continue...");
clearKeyboard();
}
void printWelcome(void){
printf ("---=== Grocery Inventory System ===---\n\n");
}
int getInt(void){
int iVal;
char charCheck='x';
while (charCheck != '\n'){
scanf ("%d%c",&iVal,&charCheck);
if ( charCheck != '\n'){
clearKeyboard();
printf ("Invalid integer, please try again: ");
}
}
return iVal;
}
int getYesOrNo(void){
//list of variables declared and initialized
char ch;
int ret;
ch = 0;
ret = 0;
//it will keep asking the user as long as they don't reply with y or n
while(ch != 'Y' || ch != 'y' || ch != 'N' || ch != 'n')
{
scanf(" %c", &ch);
clearKeyboard();
if (ch == 'Y' || ch == 'y'){
ret = 1;
return ret;
}
else if (ch == 'N' || ch == 'n'){
ret = 0;
return ret;
}
//if they type other than y or n, it will print out this message
else{
printf("Only (Y)es or (N)o are acceptable: ");
}
}
return ret;
}
int getIntLimited(int lowerLimit, int upperLimit){
int iVal;
do{
iVal = getInt();
if (!(iVal >= lowerLimit && iVal <= upperLimit))
printf ("Invalid value, 0 <= value <= 7: ");
}while (!(iVal >= lowerLimit && iVal <=upperLimit));
return iVal;
}
int getMenuChoice(void){
int SEL;
int temp;
printf("1- List all items\n");
printf("2- Search by SKU\n");
printf("3- Checkout an item\n");
printf("4- Stock an item\n");
printf("5- Add new item or update item\n");
printf("6- delete item\n");
printf("7- Search by name\n");
printf("0- Exit program\n> ");
scanf("%d", &SEL);
if (SEL > 7){
temp = getIntLimited(0,7);
}
return SEL;
}
void GrocInvSys(void){
int SEL;
int DONE = 0;
SEL = 0;
printWelcome();
while (DONE == 0){
SEL = getMenuChoice();
clearKeyboard();
if (SEL == 1){
printf("List Items!\n");
pause();
}
if (SEL == 2){
printf("Search Items!\n");
pause();
}
if (SEL == 3){
printf("Checkout Item!\n");
pause();
}
if (SEL == 4){
printf("Stock Item!\n");
pause();
}
if (SEL == 5){
printf("Add/Update Item!\n");
pause();
}
if (SEL == 6){
printf("Delete Item!\n");
pause();
}
if (SEL == 7){
printf("Search by name!\n");
pause();
}
if(SEL == 0){
printf("Exit the program? (Y)es/(N)o): ");
DONE = getYesOrNo();
}
}
}
int main(void){
GrocInvSys();
return 0;
}
For this code, it would display all the items in the getMenuChoice and whenever use types the number for each item, it would print a special message.
Everything is working fine, however it should say "Invalid value, 0 < value < 7: " whenever I type something other than 0 or 1 or 2 or 3 or 4 or 5 or 6 or 7.
So I am guessing my getIntlimited function is not working in the getMenuChoice function. Any guesses to why?
p.s. I have typed pause(); for every if SEL == statement,is there any way I can make it better?
The main problem is some excess code in getMenuChoice(). It just needs to print the menu and return the value of getIntLimited(0,7):
int getMenuChoice(void){
printf("1- List all items\n");
printf("2- Search by SKU\n");
printf("3- Checkout an item\n");
printf("4- Stock an item\n");
printf("5- Add new item or update item\n");
printf("6- delete item\n");
printf("7- Search by name\n");
printf("0- Exit program\n> ");
return getIntLimited(0,7);
}
Another problem is the call to clearkeyboard() after the call to getMenuChoice() in GrocInvSys(). This reads more input up to the next newline, but getInt() has already read the newline that terminated the integer. There is no need to read another line, since its contents are just ignored. Remove that call to clearkeyboard() to fix that problem.

Handling inputs for int, char, float

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

How would i make this program loop the main twice?

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

Resources