In my program I am supposed to make a rush hour game in C. I am importing the board shown from a text file.
After than I ask the user for input, which is supposed to be the char on the board he wants to move.
My question is when the user picks the char, how can I check if the char he picked exists in the board.txt file, because if it doesn't, I need to ask the user to pick a new character.
This is how the input section of the code looks so far:
char Direction[1];
char Vehicle[1];
int intInput =0;
// get the char input for the type of vehicle
printf("Please enter which vehicle you would like to move:\n");
scanf("%s", &Vehicle);
//THIS IS WHERE I NEED TO CHECK IF THE CHAR PICKED EXISTS IN board.txt
printf(" This is the input: %s\n", Vehicle);
//get the char input for the direction you want to move
printf("Please choose if you want to move right(R) or left(L):\n");
scanf("%s", &Direction);
if(Direction != "r"||"l"){
printf("Please choose a valid direction(R=Right L=Left):\n");
scanf("%s", &Direction);
}
else{
printf("Your move was %s\n", Direction);
}
//get the int input
printf("Enter how far you would like to move:");
scanf("%d", &intInput);
if(intInput<0){
printf("Please enter a positive integer:");
scanf("%d", &intInput);
}
else{
printf("The inpuy is %d", intInput);
}
how I check if the char he picked exists in the board.txt
The best method is to read the data per line into a buffer to read use fgets
And find char in that buffer. To find use strchr
following code illustrate what i mean
FILE * fp;
fp= fopen("board.txt", "r");
char buffer[256];
if (!fp)
{
printf("error");
return;
}
while (fgets(buffer, 256, fp))
{
char *ptr = strchr(str, Direction);
if(ptr)
printf("found\n");
else
printf("Not found\n");
}
fclose(fp);
Related
There are some problems in this code which I am unable to figure it out. No.1 is with printf() which is just allowing me to enter name but date of birth. No.2 is maybe the the problem with if statement. No. 3 is that the else statement just stops the process but didn't show me the message.
int list_view(char *name, char *dob, char *id, char *phone_num, char *address, char *account, char *fixing, char *amount){
printf("To show you details, please enter the person name and id card number: \n");
printf("Enter your Name: ");
printf("Enter you Date of Birth: ");
if(fgets(name, sizeof name, stdin) && fgets(dob, sizeof dob, stdin)){
FILE * fr;
int one_by_one;
fr = fopen("/home/bilal/Documents/file.txt", "r");
for (int i=0; i<8; i++){
printf("\nHere is your "); /* listing is transferred above just to show ones */
while((one_by_one = fgetc(fr)) != EOF && one_by_one != '\n'){
printf("%c",one_by_one); /* display on screen*/
}
} /* end of for loop */
fclose(fr);
} /* end of if statement */
else{
printf("No access");
}
return 0;
}
First you should prompt and get each piece of input in turn. ie
printf("Enter your Name: ");
fgets(name, sizeof name, stdin); /// with some checking
printf("Enter you Date of Birth: ");
fgets(dob, sizeof dob, stdin); // with some checking
second,
sizeof name
is useless, its the size of a pointer. If these input buffers are supplied by the caller then they have to pass in a buffer size arg too.
You seem hung up on your 'if'.
This is what you need I think. If they dont enter a value for either prompt then you want to say 'no access' and return
printf("Enter your Name: ");
if(!fgets(name, namesize, stdin))
{
printf("no access");
return;
}
printf("Enter you Date of Birth: ");
if(!fgets(dob, dobsize, stdin))
{
printf("no access");
return;
}
I am trying to read employee information from the user and enter it into a file using fwrite() function and later i want to print the data contents on the screen using fread() to read from file and then print it.
When i am inside the program, this process is working absolutely fine but after program is exited and i access the file where the information has been stored, i see unreadable characters but in the program they are printed as normal english characters and digits.
Here is my code:
#include<stdio.h>
struct emp{
int id;
char name[30];
double salary;
}S;
void main(){
char fname[60];
printf("Enter file name: ");
scanf("%s", fname);
FILE *fptr = fopen(fname, "a+"); // open file in append + mode, create if not found.
if(fptr == NULL){
printf("Some error occured !\n");
return;
}
int i, size;
printf("Enter the number of employees whose information is needed to be added to the file: ");
scanf("%d", &size);
// writing
for(i = 0 ; i < size ; i++){
printf("Employee %d:\n", i+1);
printf("Enter id: ");
scanf("%d", &S.id);
printf("Enter name: ");
while(getchar() != '\n'); // clear buffer
scanf("%s", S.name);
printf("Enter salary: ");
scanf("%lf", &S.salary);
fwrite(&S, sizeof(struct emp), 1, fptr);
printf("----------------------------------------\n");
}
rewind(fptr); // move pointer to first record in file
// reading
printf("File contents: \n");
printf("ID\t\tNAME\t\tSALARY\n");
while(fread(&S, sizeof(struct emp), 1, fptr) != 0){
printf("%d\t\t%s\t\t%lf\n", S.id, S.name, S.salary);
}
}
Here is the picture of what i am trying to expalin.
You are writing to the file the struct and not printing its contents separately. It works when you read it back, but when you open the file, it simply doesn't know what it is (you have int and char* and double in your struct.
If you want to visualize it on the file, you need to print each term of the struct individually, and read it back the same way, in order to see it on screen.
I have two functions that uses up a .dat file.
The first function adds a structure of a question and its answers to the file and the other is to view the questions in the file.
The addQues() function is called main inside a loop that inquires if the user wants to add more questions. The problem is when the addQues() function is called the second time and onward, it successfully writes the question to the file but when the viewQues() function is called, the questions are not shown. The size of the file also increases after each succeeding call of addques()
/* the structure is as follows */
typedef struct {
char question[256];
char choiceA[32];
char choiceB[32];
char choiceC[32];
char choiceD[32];
char ans;
int num;
}question;
/* function to add questions */
void addQues(){
FILE *fileptr;
question catcher, ques;
int x;
fileptr = fopen("Questions.dat", "a+");
if(fileptr != NULL){
catcher.num = 0;
while(fread(&catcher, sizeof(question), 1, fileptr)!= 0){}
printf("There are %d questions. Please type in the Question you would like to add.\n\nQuestion: ", catcher.num);
fflush(stdin);
scanf("%[^\n]%*c", &ques.question);
printf("Add four[4] choices to the question\n");
printf("\nChoice a.: ");
fflush(stdin);
scanf("%[^\n]%*c", &ques.choiceA);
printf("\nChoice b.: ");
fflush(stdin);
scanf("%[^\n]%*c", &ques.choiceB);
printf("\nChoice c.: ");
fflush(stdin);
scanf("%[^\n]%*c", &ques.choiceC);
printf("\nChoice d.: ");
fflush(stdin);
scanf("%[^\n]%*c", &ques.choiceD);
printf("\nType the letter of the correct answer of this question.\nAnswer: ");
fflush(stdin);
scanf("%c", &ques.ans);
ques.num = catcher.num+1;
printf("%s", ques.question); /* made this snippet to make sure that white spaces in my input were recorded */
getch();
if(fwrite(&ques, sizeof(question), 1,fileptr) == 1){
printf("File write was successful\n"); /* made this snippet to make sure if writing is successful. and it is successfull everytime */
}else{
printf("File write was unsuccessfull");
}
getch();
fclose(fileptr);
}else{
printf("File either not found or does not exist.");
}
}
/* code view the Questions in the file */
void viewQues(){
FILE *fp;
question ques;
fp = fopen("Questions.dat", "r");
if(fp != NULL){
while(fread(&ques, sizeof(question), 1, fp) != 0){
printf("[%d] %s\n", ques.num, ques.question);
}
fclose(fp);
}else{
printf("File is either not found or does not exist.");
}
}
I am somehow confused because it somethimes works fluidly, sometimes it doesn't.
This is only my 1st semester of taking up C-programming so I still have alot to learn.
I am also quite new to this website please do forgive me if I may have violated any required format.
EDIT:
The program requires the user to input a question, 4 choices, and it's correct answer.
in the addQues function before the program asks for input, it already notifies the user how many questions there are in the file.
example is
There are 0 question/s (this updates when a question is added). lease type in the Question you would like to add.
Question: //user types What is the capital of Philippines?
Enter Choice A: // user types 'Manila'
Enter Choice B: // user types 'Cebu'
Enter Choice C:// user types 'Davao'
Enter Choice C:// user types 'Palawan'
Enter the letter of the correct answer: // User types in 'a'
Expected output would be
[1] What is the capital of Philippines?
after the second call and onwards the output that it shows is still only
[1] What is the capital of Philippines?
I am sorry I do not know how to make the sample scenario different from the rest of the text.
I'm writing a simple exercise app in C, which should ask user if he want write something to file or read the file. I want give name to the file and then input some text in console. I want use that text to save it to the file.
The problem is that, when I already give name to the file, I can't input data to the console and by this I can't save these datas to the text file. In addition, the while loop ignores my 'y' to restart the program again. Furthermore, when I want use reading file then it really does, program works, but it also adds instruction from default (printing just error) but I don't want that, just only read from file and print it to the console.
Can someone explain me what I'm doing wrong and how to solve this? I'd be grateful.
Here's my code:
int main()
{
FILE *file;
char nameFile[32];
char string[500];
char ans[2];
int choice;
do{
printf("What do you want to do?\n");
printf("1. Write text to file\n");
printf("2. Read text file\n");
scanf("%d", &choice);
switch (choice) {
case 1:
printf("Give name to the file (*.txt).\n");
scanf("%s", nameFile); //This line skips me to line where program ask user if restart the program (I have no idea why :()
system("clear");
file=fopen(nameFile, "w");
if(file!=NULL){
printf("Input text:\n");
scanf("%[^\n]", string); //<--- HERE I'cant input text to console, seems like scanf doesn't work.
fprintf(file, "%s", string);
printf("\n\t\t\t-----------Ended writing.------------\n");
fclose(file);
}
else
{
printf("Could not open the file.");
return -1;
}
break;
case 2:
printf("Give name to the file (*.txt)");
scanf("%s", nameFile);
system("clear");
file=fopen(nameFile, "r");
if(file!=NULL){
while (!feof(file)) {
fscanf(file, "%s", string);
printf("%s\n",string); //After printing data from text file, adds instruction from line , and that is printing Error. How to get rid of it?
}
}
else{
printf("Could not open the file.");
return -1;
}
default:
printf("Error.");
break;
}
printf("Do you want to restart the program? (y/*)"); //Even if I write 'y', program ends anyway :(
scanf("%s", ans);
}
while(ans=='y');
return 0;
}
https://ideone.com/aCYJR5
scanf("%[^\n]", string); doesn't work unless the input buffer is clear. Use instead scanf("%499s", string) where 499 is the size of the string minus 1.
Don't use while (!feof(file)){...}, use instead while(fscanf(file, "%500s", string) == 1){...}
Use while(ans[0]=='y') as suggested earlier. Or use
char ans;
scanf(" %c", &ans);//note the blank space before `%c`
while(ans == 'y')
You also forgot to break a switch statement. Try the following:
char c;
char ans;
do {
printf("What do you want to do?\n");
printf("1. Write text to file\n");
printf("2. Read text file\n");
scanf("%d", &choice);
switch(choice) {
case 1:
printf("Give name to the file (*.txt).\n");
scanf("%s", nameFile);
file = fopen(nameFile, "w");
if(file == NULL) { printf("Could not open the file."); return -1; }
printf("Input text:\n");
while((c = getchar()) != '\n' && c != EOF);
fgets(string, sizeof(string), stdin);
string[strcspn(string, "\r\n")]=0;
fprintf(file, "%s", string);
printf("\n\t\t\t-----------Ended writing.------------\n");
fclose(file);
break;
case 2:
printf("Give name to the file (*.txt)");
scanf("%s", nameFile);
file = fopen(nameFile, "r");
if(file == NULL) { printf("Could not open the file."); return -1; }
while(fgets(string, sizeof(string),file))
printf("%s\n", string);
fclose(file);
break;
}
printf("Do you want to restart the program? (y/*)");
scanf(" %c", &ans);
} while(ans == 'y');
See also
Why is “while ( !feof (file) )” always wrong?
How to clear input buffer in C?
your while should be
while(ans[0]=='n');
A char array is a string, you are trying to compare a whole string to the character 'y'. Also, it should "Loop while ans[0] is equal to 'n'" meaning keep going if the user specifies n.
Please help me. This is my code so far. The delete record function is not working and can someone help the update record function with following conditions:
- Ask user to input player name.
- Ask user to input player score.
- Ask user to input player level.
- If the player name does not exist on the list, then show message “name of [player name] not found!”
Thanks a lot.
#include <stdio.h>
#include <string.h>
struct Player {
char name[50];
int score;
int level;
};
struct Player data[50];
FILE *ptr;
FILE *ptr2;
int fileSize()
{
int lSize;
int end;
ptr = fopen("text.txt", "r");
lSize = ftell (ptr);
fseek (ptr, 0, SEEK_END);
end = ftell (ptr);
fseek (ptr, lSize, SEEK_SET);
return end;
}
int getNoOfRecords()
{
return (fileSize()/(sizeof(struct Player)));
}
void deletePlayerRecord()
{
char name[50];
int counter=0, i=0;
ptr2 = fopen("text2.txt","a");
int records = getNoOfRecords();
ptr = fopen("text.txt","a+");
do {
printf("Input player name[1..10]: ");
scanf("%[^\n]s", name);
fflush(stdin);
} while (strlen(name)<1 || strlen(name)>10);
while(counter!=records)
{
fread(&data,sizeof(struct Player),1,ptr);
if(strcmp(data[i].name,name)==0)
{
}
else
{
fwrite(&data,sizeof(struct Player),1,ptr2);
}
counter++;
}
fclose(ptr);
fclose(ptr2);
remove("text.txt");
rename("text2.txt","text.txt");
printf("\n%s successfully deleted.\n\n", name);
printf("Press Enter to continue....\n\n");
getchar();
}
void updatePlayerRecord()
{
char name[50];
int counter=0, i=0;
int records = getNoOfRecords();
ptr = fopen("text.txt","a+");
do {
printf("Input player name[1..10]: ");
scanf("%[^\n]s", name);
fflush(stdin);
} while (strlen(name)<1 || strlen(name)>10);
if(counter!=records)
{
fread(&data,sizeof(struct Player),1,ptr);
if(strcmp(data[i].name,name)==0)
{
}
counter++;
}
printf("\nScore and Level successfully updated.\n\n");
printf("Press Enter to continue....\n\n");
getchar();
}
void addPlayerRecord(){
int i=0;
do {
printf("Input player name[1..10]: ");
scanf("%[^\n]s", data[i].name);
fflush(stdin);
} while (strlen(data[i].name)<1 || strlen(data[i].name)>10);
fflush(stdin);
getchar();
data[i].score=0;
data[i].level=0;
ptr = fopen("text.txt", "a");
printf("\n");
fprintf(ptr, "\r\n%s#%d#%d", data[i].name, data[i].score, data[i].level);
fclose(ptr);
printf("\nData successfully added.\n\n");
printf("Press Enter to continue....\n\n");
getchar();
}
void viewPlayerRecord(){
int i=0;
ptr = fopen("text.txt", "r");
printf("Player Name\t\t|Average Score\t|Number of Playing\n");
printf("=======================================================\n");
while(fscanf(ptr, "%[^#]#%d#%d\n", data[i].name, &data[i].score, &data[i].level)!=EOF)
{
printf("%s\t\t\t|%d\t\t\t\t|%d\n", data[i].name, data[i].score, data[i].level);
i++;
}
fclose(ptr);
}
int main() {
int choice;
do{
printf("Score Record Dota Player\n");
printf("========================\n");
printf("1. View Record\n");
printf("2. Update Player Record\n");
printf("3. Add New Player\n");
printf("4. Delete Player\n");
printf("5. Save and Exit\n\n");
do {
printf("Input your choice[1..5]: ");
scanf("%d", &choice);
fflush(stdin);
getchar();
} while (choice < 1 || choice > 5);
switch (choice) {
case 1:
viewPlayerRecord();
break;
case 2:
updatePlayerRecord();
break;
case 3:
addPlayerRecord();
break;
case 4:
deletePlayerRecord();
break;
}
} while(choice!=5);
return 0;
}
There are many issues with your code:
Every operation works on the database file. That may be a good design, but a more usual approach would be to load the database into memory on startup, i.e. to populate your data and then work on this. When exiting the program, you commit all changes to the database file. (Your option 5 is named "Save and exit", but is effectively a null operation. That name hints at the outlined approach.)
You should make up your mind whether your database is a binary file or a text file. You use fprintf and fscanf, which are used for text files, when you add and display records, but you use fwrite and fread, which are used for binary files, when you update and delete records. In my opinion, binary access is a bit easier, because you just have to store and retrieve chunks of a fixed size, namely sizeof(struct Player). Text files are more user-friendly, because they can be displayed and modified in a text editor, but they have to be parsed and require more advanced error handling.
Your fileSize() will only work with binary files, but at the moment you write only text files. It is usually better to use the return values of the file functions to determine whether reading or writig was successful.
When the database file doesn't exist, your view function will crash. Check for file existence and for the correct format.
At the moment, you use data only as scratch space. You osften access data[i], but i is zero throughout your code.
A corrected delete function that works is:
void deletePlayerRecord()
{
struct Player p;
char name[50];
int del = 0;
ptr2 = fopen("text2.txt", "w");
ptr = fopen("text.txt", "r");
do {
printf("Input player name[1..10]: ");
scanf("%[^\n]s", name);
fflush(stdin);
} while (strlen(name)<1 || strlen(name)>10);
while (fscanf(ptr, "%[^#]#%d#%d\n", p.name, &p.score, &p.level) == 3) {
if(strcmp(p.name, name) == 0) {
printf("\n%s successfully deleted.\n\n", name);
del++;
} else {
fprintf(ptr2, "%s#%d#%d\n", p.name, p.score, p.level);
}
}
fclose(ptr);
fclose(ptr2);
remove("text.txt");
rename("text2.txt", "text.txt");
printf("%d character(s) deleted\n\n", del);
}
This code still has many drawbacks:
The success of fopen is not checked.
The fscanf and fprintf formats have to be copied verbatim from the view and add record options. That's bad style. You should probably write readPlayer and writePlayer functions.
The same goes for the input code. Write front-end functions that do the error checking so that you don't have to repeat the whole code over and over again. This makes the code hard to read and also prone to errors.