I have this code here to search a string in a file and display it. How can I edit this piece of code to make it possible to search just a part of this string?
say, the file contains the author "dennis zill", if I search "zill" I want the code to display "dennis zill".
int searchauthor(FILE *ptr) //searching starts
{
int save;
char de;
char in_name[30];
int flag = 1;
save = readbooks();
ptr = fopen("books info.txt", "r");
fflush(stdin);
printf("\n Enter the name of the author: ");
gets(in_name);
printf("-------------------------------------------------");
for(int i = 0; i < save; i++){
if(strcmpi(in_name, info[i].bauthor) == 0){
printf("\n Book name: %s\n Price: %u\n Number of books available: %u\n Number of pages: %u\n-------------------------------------------------", info[i].bname, info[i].price, info[i].numavail, info[i].bpages);
flag = 0;
}
}
if (flag == 1){
printf("\n Not found.\n Do you want to try another search [Y/N]? ");
scanf("%c", &de);
if(de == 'y' || de == 'Y'){
system("cls");
in_name[MAX] = reset(in_name);
fclose(ptr);
return 2;
}
else if(de == 'n' || de == 'N'){
printf("\n You will be redirected to main menu");
for(int k = 1; k <= 5; k++){
Sleep(300);
printf(".");
}
system("cls");
return 1;
}
}
printf("\n\n Do you want to try another search [Y/N]? ");
scanf("%c", &de);
if (de == 'y' || de == 'Y') {
system("cls");
in_name[MAX] = reset(in_name);
return 2; //return 2 to case 3 to search again
}
else if (de == 'n' || de == 'N') {
system("cls");
printf("\n You will be redirected to main menu");
for(int k = 1; k <= 5; k++){
Sleep(300);
printf(".");
}
system("cls");
return 1;
}
} //searching ends
The problem is the line:
if(strcmp(in_name, info[i].bauthor) == 0){
It will succeed only on a full match.
Rather that using strcmp use strstr (or its case-insensitive variant strcasestr() if it's available).
char *strstr(const char *haystack, const char *needle);
The haystack is the full authors name, needle the user's input.
Function returns NULL on failure so it's enough to check if non-NULL was returned.
if(strstr(info[i].bauthor, in_name) != NULL){
Related
After running the next code, in the function get_data(), everything runs normally until I get to the end of the For, when program should call the function continue_function() but in somehow, ignores it, and the program just ends.
Am I calling it in a wrong way?
I'm just start learning programming in C and this is one of the last exam's exercises.
#include <stdio.h>
#define MAX 100
#define YES 1
#define NO 0
struct record
{
char fname[15+1];
char lname[20+1];
char phone[9+1];
long income;
int month;
int day;
int year;
};
struct record list[MAX];
int last_entry = 0;
void get_data(void);
void display_report(void);
int continue_function(void);
void clear_kb(void);
main()
{
int cont = YES;
int ch;
while(cont == YES)
{
printf("\n");
printf("\n MENU");
printf("\n =========\n");
printf("\n1. Enter Names");
printf("\n2. Print Report");
printf("\n3. Quit");
printf("\n\nEnter Selection ==> ");
scanf("%d", &ch);
clear_kb();
system("cls");
switch(ch)
{
case 1: get_data();
break;
case 2: display_report();
break;
case 3: printf("\n\nThank You for using this Program!");
cont = NO;
break;
default: printf("\n\nInvalid Choice, Please Select 1 to 3!");
break;
}
}
}
void get_data(void)
{
int cont;
int ctr;
for(cont = YES; last_entry < MAX && cont == YES; last_entry++)
{
printf("\n\nEnter information for Person %d.", last_entry+1);
printf("\n\nEnter first name: ");
gets(list[last_entry].fname);
printf("Enter last name: ");
gets(list[last_entry].lname);
printf("Enter phone in 123-4567 format: ");
gets(list[last_entry].phone);
printf("Enter Yearly Income: ");
scanf("%ld", &list[last_entry].income);
printf("Enter Birthday: ");
do
{
printf("\n\tMonth (0 - 12): ");
scanf("%d", &list[last_entry].month);
}
while (list[last_entry].month < 0 || list[last_entry].month > 12);
do
{
printf("\tDay (0 - 31): ");
scanf("%d", &list[last_entry].day);
}
while (list[last_entry].day < 0 || list[last_entry].day > 31);
do
{
printf("\tYear (1800 - 2025): ");
scanf("%d", list[last_entry].year);
}
while (list[last_entry].year < 1800 || list[last_entry].year > 2025);
cont = continue_function();
}
if(last_entry == MAX)
{
printf("\n\nMaximum Number of Names has been entered!\n");
}
}
void display_report(void)
{
long month_total = 0, grand_total = 0;
int x, y;
fprintf(stdout, "\n\n");
fprintf(stdout, "\n REPORT");
fprintf(stdout, "\n ========");
for(x = 0; x <= 12; x++)
{
month_total = 0;
for(y = 0; y < last_entry; y++)
{
if(list[y].month == x)
{
fprintf(stdout, "\n\t%s %s %s %ld", list[y].fname, list[y].lname, list[y].phone, list[y].income);
month_total += list[y].income;
}
}
fprintf(stdout, "\nTotal for month %d is %ld:", x, month_total);
grand_total += month_total;
}
fprintf(stdout, "\n\nReport Totals:");
fprintf(stdout, "\nTotal Income is %ld", grand_total);
fprintf(stdout, "\nAverage Income is %ld", grand_total/last_entry);
fprintf(stdout, "\n\n* * * End of Report * * *");
}
int continue_function(void)
{
char ch;
printf("\n\nDo you wish to continue? (Y)es/(N)o: ");
getc(ch);
while(ch != 'n' && ch != 'N' && ch != 'y' && ch != 'Y')
{
printf("\n%c is invalid!", ch);
printf("\n\nPlease enter \'N\' to Quit or \'Y\' to Continue: ");
getc(ch);
}
clear_kb();
if(ch == 'n' || ch == 'N')
{
system("cls");
return(NO);
}
else
{
system("cls");
return(YES);
}
}
void clear_kb(void)
{
char junk[80];
gets(junk);
}
You're not using your get functions properly:
https://www.tutorialspoint.com/c_standard_library/c_function_getc.htm
int getc(FILE *); for instance requires a FILE* as argument and returns the character, but you are passing the character as argument, it should look like ch = getc(stdin);.
On another note, notice that when you use scanf you pass &c? This is because for a value to be modified, you need to pass the address where it's stored (&) and not the value itself. So even if getc took a char, it would have to be getc(&ch).
You should follow a quick tutorial on pointers and types, if you come from a higher level language or if you're new that could be a good idea.
I made a hangman game using a while loop. I want to use the number of dashes == 0 to break the loop so the player knows that they won. The word is hidden behind "-"s. My word is coding, so it has 6 dashes.
When I run the program, the first guess at the word is an accurate number of dashes. But after the second guess, and so on, it is adding all of the dashes from all the guesses together, not just from that one turn. By the third turn it says I have 9 dashes because that's how many is left over in all of the turns. Any ideas on how to fix?
char word[] = { "Coding" };
char dash[] = {"------"};
char guess;
int numguesses = 10;
int count;
int loopcount;
int i;
int dashcount;
int main()
{
printf("Your Word Is: %s", &dash);
//printf("\nWord: %c", &dash);
loopcount = 10;
count = 1;
while (count <= loopcount)
{
printf("\n\nPick a letter to guess: ");
scanf(" %c", &guess);
printf("\n\nYour Guess Was %c. ", guess);
count = count + 1;
if (guess == 'c')
{
dash[0] = 'c';
printf("\n\n %s", dash);
}
else if (guess == 'o')
{
dash[1] = 'o';
printf("\n\n %s", dash);
}
else if (guess == 'd')
{
dash[2] = 'd';
printf("\n\n %s", dash);
}
else if (guess == 'i')
{
dash[3] = 'i';
printf("\n\n %s", dash);
}
else if (guess == 'n')
{
dash[4] = 'n';
printf("\n\n %s", dash);
}
else if (guess == 'g')
{
dash[5] = 'g';
printf("\n\n %s", dash);
}
else
printf("That Letter Is Not Apart of this Word");
printf("\n\nYou are at Guess Number %d, Your word is at %s", count, dash);
for (i = 0; dash[i]; i++)
{
if (dash[i] == '-')
{
dashcount++;
}
}
printf("\n\nDoes it work ?: %d", dashcount);
}
if (count < numguesses)
{
printf("\n\n\nYou Won the Game, Your Awesome!!");
}
else
{
printf("\n\n\nI'm Sorry, the word was %s.", word);
}
printf("\n\n");
return 0;
}
The issue is that you are not resetting the dashcount variable, so every time it starts with previous value and adds the dashes left
for (i = 0; dash[i]; i++)
{
if (dash[i] == '-')
{
dashcount++;
}
}
You can easily fix this in this way
dashcount=0;
for (i = 0; dash[i]; i++)
{
if (dash[i] == '-')
{
dashcount++;
}
}
I have written a program in C, that when runs, is supposed to allow the user to play a game of tic tac toe - or noughts and crosses, whether it be against the computer, or another user. I have nearly completed it, and it prints the grid out perfectly fine. However, when I go to input which row/column I want to place the symbol in, instead of inserting the symbol, it just removes a space in the grid, aligning it incorrectly. I have tried to put a loop in the main method which fills the grid in with spaces to try and prevent null values.
If anyone could suggest anything it would be much appreciated. Thanks in advance!
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void user_prompt();
void clear_board(char gameBoard[3][3]);
void display_board(char gameboard[3][3]);
void user_move(char gameBoard[3][3]);
void computer_move(char gameBoard[3][3]);
int detect_win(char gameBoard[3][3]);
int gameMode;
char symbol1;
char symbol2;
char nickname1[10];
char nickname2[10] = "TicTacBot";
char gameBoard[3][3];
char playerTurn[10];
int main(void){
int i, j;
char gameBoard [3][3];
clear_board(gameBoard);
for(int i = 0; i < 3; i++) {
for(int j = 0; j < 3; j++) {
gameBoard[i][j] = ' ';
}
}
i = 0;
j = 0;
user_prompt();
display_board(gameBoard);
if(gameMode == 2){
for(i = 0; i < 9; i++){
user_move(gameBoard);
display_board(gameBoard);
if(detect_win(gameBoard) == 1){
printf("The winner is %s!!!\n", nickname1);
}
if(detect_win(gameBoard) == 2){
printf("The winner is %s!!!\n", nickname2);
}
}
}
else{
user_move(gameBoard);
display_board(gameBoard);
for(i = 0; i < 4; i++){
printf("TicTacBot's move.\n");
computer_move(gameBoard);
display_board(gameBoard);
if(detect_win(gameBoard) == 1){
printf("The winner is %s!!!\n", nickname1);
}
user_move(gameBoard);
display_board(gameBoard);
if(detect_win(gameBoard) == 1){
printf("The winner is %s!!!\n", nickname2);
}
}
}
if(detect_win(gameBoard) == 0){
("The game ended in stalemate!\n");
}
return 0;
}
/*
Prompts the user to enter a nickname, what symbol they would like to use, and whether they'd rather play against the computer or another user.
*/
void user_prompt(void){
printf("Please choose whether you would rather play against the computer (enter '1'),or another user (enter '2'): \n");
scanf("%d", &gameMode);
getchar();
while(gameMode != 1 && gameMode != 2){
printf("Please enter a valid digit: \n");
scanf("%d", &gameMode);
getchar();
}
if(gameMode == 1){
printf("Please choose whether you would rather play as 'X' (enter 'x') or as 'O' (enter 'o'): \n");
scanf(" %c", &symbol1);
getchar();
if(symbol1 == 'x') {
symbol2 == 'o';
}
else{
symbol2 == 'x';
}
}
else{
printf("Player 1, would you like to play as 'X' (enter 'x') or as 'O' (enter 'o'): \n");
scanf(" %c", &symbol1);
getchar();
while(symbol1 != 'x' && symbol1 != 'o'){
printf("Please enter a valid symbol: \n");
scanf(" %c", &symbol1);
getchar();
}
if(symbol1 == 'x'){
symbol2 == 'o';
}
else{
symbol2 == 'x';
}
}
if(gameMode == 1){
printf("Please enter a nickname: \n");
fgets(nickname1, 10, stdin);
getchar();
}
else{
printf("Please enter a nickname for player 1: \n");
fgets(nickname1, 10, stdin);
getchar();
printf("Please enter a nickname for player 2: \n");
fgets(nickname2, 10, stdin);
getchar();
}
}
/*
Resets the game board.
*/
void clear_board(char gameBoard[3][3]){
for(int i = 0; i < 3; i++){
for(int j = 0; j < 3; j++){
gameBoard[i][j] = 0;
}
}
}
/*
Displays the game board and all symbols within it.
*/
void display_board(char gameBoard[3][3]){
for(int i = 0; i < 3; i++){
for(int j = 0; j < 3; j++){
printf(" %c ", gameBoard[i][j]);
if(j == 2){
printf("\n");
}
if(j != 2){
printf("|");
}
}
if(i != 2){
printf("---+---+---\n");
}
}
}
/*
Takes input of a position on the board from the user, then places the user's symbol into that space on the game board.
*/
void user_move(char gameBoard[3][3]){
int row;
int column;
if(playerTurn == nickname1){
printf("Would you like to enter your %c in row 1, 2 or 3? \n", symbol1);
scanf("%d", &row);
getchar();
printf("Would you like to enter your %c in column 1, 2 or 3? \n", symbol1);
scanf("%d", &column);
getchar();
}
else{
printf("Would you like to enter your %c in row 1, 2 or 3? \n", symbol2);
scanf("%d", &row);
getchar();
printf("Would you like to enter your %c in column 1, 2 or 3? \n", symbol2);
scanf("%d", &column);
getchar();
}
if(row < 1 || row > 3){
printf("Please enter a valid row number: \n");
scanf("%d", &row);
getchar();
}
if(column < 1 || column > 3){
printf("Please enter a valid column number: \n");
scanf("%d", &row);
getchar();
}
if(gameBoard[row-1][column-1] != ' '){
printf("The position you entered is already taken. Try again! \n");
display_board(gameBoard);
user_move(gameBoard);
}
else if(gameBoard[row-1][column-1] != ' '){
printf("The position you entered is already taken. Try again! \n");
display_board(gameBoard);
user_move(gameBoard);
}
else{
if(playerTurn == nickname1){
gameBoard[row-1][column-1] = symbol1;
}
else{
gameBoard[row-1][column-1] = symbol2;
}
}
printf("%c", symbol2);
if(gameMode == 2){
return;
}
if(strcmp(playerTurn, nickname1)==0){
strcpy(playerTurn, nickname2);
}
else if(strcmp(playerTurn, nickname2)==0){
strcpy(playerTurn, nickname1);
}
}
/*
Automates a strategic move from the computer, aiming to win the game, or at the least prevent the user from winning
*/
void computer_move(char gameBoard[3][3]){
int row;
int column;
int endTurn = 0;
row = rand() % 3 + 0;
column = rand() % 3 + 0;
if(gameBoard[row][column] != symbol1 && gameBoard[row][column] != symbol2){
gameBoard[row][column] = symbol2;
endTurn = 1;
}
}
/*
Detects a win on the game board. Checks if there are three identical symbols in a row, or if there are no more spaces on the game board.
*/
int detect_win(char gameBoard[3][3]){
for(int row = 0; row < 3; row++){
if(gameBoard[row][0] == gameBoard[row][1] && gameBoard[row][1] == gameBoard[row][2]){
if(gameBoard[row][0] == symbol1){
return 1;
}
if(gameBoard[row][0] == symbol2){
return 2;
}
}
}
for(int column = 0; column < 3; column++){
if(gameBoard[0][column] == gameBoard[1][column] && gameBoard[1][column] == gameBoard[2][column]){
if(gameBoard[0][column] == symbol1){
return 1;
}
if(gameBoard[0][column] == symbol2){
return 2;
}
}
}
if(gameBoard[0][0] == gameBoard[1][1] && gameBoard[1][1] == gameBoard[2][2]){
if(gameBoard[1][1] == symbol1){
return 1;
}
if(gameBoard[1][1] == symbol2){
return 2;
}
}
if(gameBoard[0][2] == gameBoard [1][1] && gameBoard[1][1] == gameBoard[2][0]){
if(gameBoard[1][1] == symbol1){
return 1;
}
if(gameBoard[1][1] == symbol2){
return 2;
}
}
return 0;
}
There's a small logical error:
In line 98, 101, 117, and 121, (and perhaps other places - please check) you have used == (operator for equality check) instead of the = used for assignment.
For example,
symbol2 == 'o';
should be replaced with
symbol2 = 'o';
Hence, it just checks for equality, throws away the result, and continues; with no changes made to symbol2.
#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.
Do you want to continue (y/n) doesn't work in this c code. I want it to ask to enter a string when I type 'y' and exit from the program if I type n. I have tried many options, but to no avail.
Thanks for your help
do
{
i = 0, final = 0, s = 0;
printf("\n\nEnter Input String.. ");
scanf("%s", string);
while (string[i] != '\0')
if ((s = check(string[i++], s)) < 0)
break;
for (i = 0 ; i < nfinals ; i++)
if (f[i] == s )
final = 1;
if (final == 1)
printf("\n String is accepted");
else
printf("String is rejected");
printf("\nDo you want to continue.? \n(y/n) ");
}
while (getch() == 'y');
return getch();
}
if (getch() == 'n') {
// print something
return;
}
should fflush your buffer before taking char as an input
do
{//..your code
printf("\nDo you want to continue.? \n(y/n) ");
scanf("%c",&ch);
scanf("%c",&ch);
}
while (ch == 'y');