Reading and Displaying content of the Text File via C coding - c

I am trying to code a game in C that deals with selection of races.
Each races has their own "stories" and when the user chooses to read one of their stories,
what I want to happen is,
While the program is running on Command Prompt, it will display the content I have typed in that specific text file about the story of the selected race.
This is what I have done so far.
void Race(char nameRace[20])
{
int race_choice,race_choice2,race_story;
FILE *race;
FILE *race1;
FILE *race2;
FILE *race3;
printf("The Races: 1.Human 2.Elf 3.Orc\n");
printf("Press 1 for Details of Each Races or 2 for selection: ");
scanf("%d",&race_choice);
if (race_choice==1)
{
printf("Which Race do you wish to know about?\n\t1.The Human\n\t2.The Elf\n\t3.The Orc\n\t: ");
scanf("%d",&race_story);
if (race_story==1)
{
race1=fopen("race1.txt","r");
fgetc(race1); // This does not display what I have typed on the race1.txt file on Command prompt.
// And I plan to write 2~3 paragraphs on the race1.txt file.
printf("\nGo Back to the Selection?(1 to Proceed)\n ");
scanf("%d",&race_choice2);
if (race_choice2==1)
{
printf("\n\n");
Race(nameRace);
}
else
{
wrongInput(race_choice2);// This is part of the entire code I have created. This works perfectly.
}
}
}
}
Please help me? :) Please!

The functionality you seem to be lacking is the ability to read a text file and output it. So it might be a good idea to code up a function which does just this, and then you whenever you need to display the contents of a file you can just pass a file name to our function and let it take care of the work, e.g.
static void display_file(const char *file_name)
{
FILE *f = fopen(file_name, "r"); // open the specified file
if (f != NULL)
{
INT c;
while ((c = fgetc(f)) != EOF) // read character from file until EOF
{
putchar(c); // output character
}
fclose(f);
}
}
and then within your code would just call this as e.g.
display_file("orcs.txt");

fgetc function reads, and returns single character from file, it doesn't prints it.
So you will need to do following:
while(!feof(race1)) { // Following code will be executed until end of file is reached
char c = fgetc(race1); // Get char from file
printf("%c",c); // Print it
}
It will print contents of race1 char-by-char.

I think you'll probably want to read the file line by line, so it's best to use fgets() instead of fgetc().
Example:
while(!feof(race1)) // checks to see if end of file has been reached for race1
{
char line[255]; // temporarily store line from text file here
fgets(line,255,race1); // get string from race1 and store it in line, max 255 chars
printf("%s",line); // print the line from the text file to the screen.
}
If you replace fgetc(race1) with the chunk of code above, it may work. I have not tried running it but it should work.

Related

What do I need to do to read a file then pick a line and write it to another file (Using C)?

I've been trying to figure out how I would, read a .txt file, and pick a line of said file from random then write the result to a different .txt file
for example:
.txt
bark
run
car
take line 2 and 3 add them together and write it to Result.txt on a new line.
How would I go about doing this???
I've tried looking around for resources for fopen(), fgets(), fgetc(), fprintf(), puts(). Haven't found anything so far on reading a line that isn't the first line, my best guess:
-read file
-print line of file in memory I.E. an array
-pick a number from random I.E. rand()
-use random number to pick a array location
-write array cell to new file
-repeat twice
-make newline repeat task 4-6
-when done
-close read file
-close write file
Might be over thinking it or just don't know what the operation to get a single line anywhere in a file is.
just having a hard time rapping my head around it.
I'm not going to solve the whole exercise, but I will give you a hint on how to copy a line from one file to another.
You can use fgets and increment a counter each time you find a line break, if the line number is the one you want to copy, you simply dump the buffer obtained with fgets to the target file with fputs.
#include <stdio.h>
#include <string.h>
int main(void)
{
// I omit the fopen check for brevity
FILE *in = fopen("demo.c", "r");
FILE *out = fopen("out.txt", "w");
int ln = 1, at = 4; // copy line 4
char str[128];
while (fgets(str, sizeof str, in))
{
if (ln == at)
{
fputs(str, out);
}
if (strchr(str, '\n') && (ln++ == at))
{
break;
}
}
fclose(in);
fclose(out);
return 0;
}
Output:
int main(void)

Check if the user input an empty string in C using char array

I'm trying to have the program check, that, if a user inputs nothing the print statement will say it cant find the file name, but the issue I'm having is that the command line will just go to a new line after hitting enter instead of saying the print statement.
This is the code here. I was told that Null is the place holder for if nothing is put in so I thought it would work.
int main()
{
FILE *fin;
FILE *fout;
char fInName[50];
char fOutName[50];
printf("pleas type input file, and output file please type legibly\n ");
scanf("%s %s", &fInName, &fOutName);
fin = fopen(fInName, "r");
fout = fopen(fOutName, "r");
if (fInName == NULL && fOutName == NULL)
{
printf("Error: Cannot open input file %s.", fInName);
}
else if (fInName != NULL && fOutName == NULL)
{
printf("file found");
}
}
What im trying to test is if a first file name is entered and the second isnt then print the statement. If both arent entered then print file does not exist.
there is more to the code to see if the file exists or not, but thst would be a bit much, now Im just trying to understand why it wont read unentered data.
Ive tried looking at examples such as: How to detect empty string from fgets
and tried to alter the code to fit that type of style but it didnt work for me so Im giving you the code it was originally so that anything helpful wouldnt confuse me more.
Edit:
okay so I tried to do a simple code in order to see what may be the cause of this issue:
int main()
{
char firstname[50];
char lastname[50];
char nothing [0];
printf("pleas type input file, and output file please type legibly pwease\n ");
scanf("%s" "%s", firstname, lastname);
if (firstname == lastname )
{
printf("Error: Cannot open input file %s.", firstname);
}
else
{
printf("file found");
}
}
I ran the code using adam and either if I typed adam (space) adam or adam(enter) adam the program thinks that the input is not the same, I feel like that would help identify why it doesnt know why nothing is typed in.
The problem is occurring when you try to check if fInName == NULL.
The problem is that fInName is just a variable that you're using to store the name of the file that you want to open. What you actually want to check is that the user gave you a valid filename, and to do so you will want to understand what the return value of functions are.
For example, when you try to open a file using fopen(), if fopen() is unable to successfully open the file, say because the user didn't input anything or misspelled the filename, then fopen() will return NULL, storing it in whatever variable you assigned it to (in your case, *fin and *fout).
Also, scanf() is not recommended for char arrays because if the user inputs more data than you allocated for the array, which in this case is enough space for 50 characters, then scanf() will try to write data to memory that's not yours, causing a buffer overflow.
A much safer option is to use fgets() because you can choose exactly how much data is written into your char array, with the only downside being that fgets() will write newline characters \n (caused by hitting the enter key) into the array, though the simple solution is to overwrite the newline character with '\0'.
Therefore, I would propose:
int main(void)
{
char fInName[50];
char fOutName[50];
// ensure proper usage
do
{
printf("What file would you like to open? ");
// get infile from user and remove trailing newline '\n' character
fgets(fInName, 50, stdin);
fInName[strcspn(fInName, "\n")] = '\0';
}
// prompt for input until user enters something
while (strlen(fInName) < 1);
do
{
printf("What file would you like to output to? ");
// get outfile from user and remove trailing newline '\n' character
fgets(fOutName, 50, stdin);
fOutName[strcspn(fOutName, "\n")] = '\0';
}
// prompt for input until user enters something
while (strlen(fOutName) < 1);
FILE *fin = fopen(fInName, "r");
if (fin == NULL)
{
printf("Error: Cannot open input file %s.", fInName);
return 1;
}
else
{
printf("file found");
}
}

Get first char of every string from text file in C

I'm a bit green in C and whole programming so I need help on task.
My goal is to read text file with random words(strings) and if there are any numbers in strings, change them to first letter of that word/string. Example: "He99llo Im N3w Her3" > "HeHHllo Im NNw HerH"
Questions: 1. How can I read separate strings from text file?
2. How can I get first letter (not number) from seperate strings?
By the way, I've wrote code, that takes only first char of text file and changes numbers into it, whenever it's number or not, but I dont know how to add code here...
EDIT: Here's the code written code:
#include <stdio.h>
#include <ctype.h>
#include <stdlib.h>
int Change(FILE *Reading, FILE *Writing){ /*Reads from file and changes numbers into first character of file*/
int FirstLetter, letter;
Reading = fopen("C:\\Users\\Rimas\\Desktop\\read.txt", "r");
Writing = fopen("C:\\Users\\Rimas\\Desktop\\write.txt", "w");
if (Writing == NULL) {
printf("I couldn't open write.txt for writing.\n");
exit(0);
}
FirstLetter = getc(Reading);
if (Reading){
fprintf(Writing, "%c", FirstLetter);
while ((letter = getc(Reading)) != EOF){
if (isdigit(letter)){
letter = FirstLetter;
}
fprintf(Writing, "%c", letter);
}
}
fclose(Reading);
fclose(Writing);
return 0;
}
int main() {
FILE *Reading;
FILE *Writing;
Change(Reading, Writing);
return 0;
}
Here's some logic to help you:
Write a function that accepts a string and converts it as you described. Do this first. And test it well because it is the fundamental part of the program.
Now you want to read a text file from main and simply display each word on screen in it's own line. This is to help you understand how to read words from a file. I would use fscanf for this. Make sure you can read the entire text file and it doesn't crash
Now right before printing the word that read in form step 2, call the function from step 1. This will alter the word and when you print you should get the correct results.

Whats wrong with fread in this program?

I'm intermediate student of C. I'm trying to make a bank management program but first I need to make a login program, so I created one of the following. As I've recently learned about file I/O in C and don't know much about fread and fwrite. I have a file (data.txt) which format if as following.
user1 1124
user2 3215
user3 5431
In the following program I've asked user to input user name and pin(4-digit password) and copy file data into a structure then compare these two for verifying information.
What is wrong with my program and how to make fread work properly. And is the formating in data.txt file all right or should I change it.
Thanks in advance...
#include<stdio.h>
#include<ctype.h>
#include<string.h>
struct user_account {
char u_name[30];
int u_pin;
} log_in;
int login()
{
int start;
int i, n;
int t_pin[4]; // TEMPORARY INT PIN for storing pin inputed by user
char t_name[30]; // TEMPORARY STRING for storing name inputed by user
FILE *fp;
fp = fopen("data.txt","rb"); // Opening record file
if(fp == NULL)
{
puts("Unable to open file!");
return 1;
}
start : {
printf("User Name : ");
scanf("%s",&t_name);
printf("Pin Code : ");
for(i = 0; i < 4; i++) { // This loop is for hiding input pin
n = getch();
if(isdigit(n)) {
t_pin[i] = n;
printf("*"); }
else {
printf("\b");
i--;
}
}
fread(&log_in,sizeof(log_in),1,fp);
// Comparing user name and pin with info in the structure copied from the file
if(strcmp(log_in.u_name, t_name) == 0 && log_in.u_pin == t_pin)
puts("Login successful! Welcome User");
else {
printf("\nIncorrect Information!\n");
printf("Press any key to log in again...");
getch();
system("cls");
goto start; }
}
}
int main()
{
int login();
return 0;
}
The problem is that you have an ASCII/text file but you are trying to use fread to read directly into a structure; this requires a binary formatted file. fread cannot do format conversion. Use fscanf instead:
fscanf(fp, "%s %d", &log_in.u_name, &log_in.u_pin);
Problems that I see:
The following line is incorrect.
scanf("%s",&t_name);
You need to use:
scanf("%29s",t_name);
fread is not the right solution given the file format. fread works when the file is in binary format.
Given the format of your input file, you need to use:
scanf("%29s %d", log_in.uname, &log_in.u_pin);
Comparing the pins using log_in.u_pin == t_pin should produce a compiler error. The type of log_in.u_pin is int while the type of t_pin is int [4]. You will have to change your strategy for getting the integer value from t_pin.
You can use something like:
int pin = 0;
for (i = 0; i < 4; ++i )
{
pin = 10*pin + t_pin[i];
}
However, for that to work, you have store the proper integer values in t_pin. When the character you read is '1', you have to store 1. Either that, or you will have to change the above for loop to:
pin = 10*pin + t_pin[i]-'0';
The way are using goto start to loop in your function is not correct. You haven't read all the user ID and pins to from the input file and compared them. The way you have it, you will end up doing:
Read the user name and pin
Check against the first entry in the file. If they don't match...
Read the user name and pin again.
Check against the next entry in the file. If they don't match...
etc.
You want to:
Read the user name and pin
Check against the first entry in the file. If they don't match...
Check against the next entry in the file. If they don't match...
Check against the next entry in the file. If they don't match...
etc.
a) fread is used to read fixed sized (in bytes) records. While that is an option, you might find that fscanf is more suited to your use case.
b) goto has its uses, arguably, but in your particular case a while loop is far more appropriate as it make the intention clearer and is less susceptible to misuse.
c) The crux of your issue is reading the file. You only read in and check against a single record from your file per pass and once all records are read you will be getting EOF rather than additional records.
You have a few options. You might read the entire user table into a list prior to your login loop. When a user logs in you must iterate through the list until a match or end of list is found. Alternatively you might loop through the entire file on each user attempt looking for a match and seek to the back to the beginning of the file when you are done. In either case you must check for and handle read errors.
d) Finally when a non-digit is entered you will probably find that backspace isn't what you had in mind. Also you might consider allowing the user to press backspace while entering the pin.

displaying contents of a file on monitor in C

I'm trying to recreate a program I saw in class.
The teacher made a file with 10 lines, he showed us that the file was indeed created, and then he displayed its contents.
My code doesn't work for some reason, it just prints what looks like a"=" a million times and then exits.
My code:
void main()
{
FILE* f1;
char c;
int i;
f1=fopen("Essay 4.txt","w");
for(i=0;i<10;i++)
fprintf(f1," This essay deserves a 100!\n");
do
{
c=getc(f1);
putchar(c);
}while(c!=EOF);
}
What is the problem? as far as I can see I did exactly what was in the example given.
The flow is as such:
You create a file (reset it to an empty file if it exists). That's what the "w" mode does.
Then you write stuff. Note that the file position is always considered to be at the very end, as writing moves the file position.
Now you try to read from the end. The very first thing you read would be an EOF already. Indeed, when I try your program on my Mac, I just get a single strange character just as one would expect from the fact that you're using a do { } while. I suggest you instead do something like: for (c = getc(f1); c != EOF; c = getc(f1)) { putchar(c) } or similar loop.
But also, your reading should fail anyway because the file mode is "w" (write only) instead of "w+".
So you need to do two things:
Use file mode "w+".
Reset the file position to the beginning of the file after writing to it: fseek(f1, 0, SEEK_SET);.

Resources