So im working on learning how to do file I/O, but the book I'm using is terrible at teaching how to receive input from a file. Below is is their example of how to receive input from a file, but it doesn't work. I have copied it word for word, and it should loop through a list of names until it reaches the end of the file( or so they say in the book), but it doesn't. In fact if I leave the while loop in there, it doesn't print anything.
#include <stdio.h>
#include <conio.h>
#define MAX 250
int main()
{
char name[MAX];
FILE*pRead;
pRead=fopen("test.txt", "r");
if (pRead==NULL)
{
printf("file cannot be opened");
}else
printf("contents of test.txt");
while(fgets(name,sizeof(name),pRead)!=NULL){
{
printf("%s\n",name);
fscanf(pRead, "%s", name);
}
getch();
}
Even online, every beginners tutorial I see does some variation of this, but I can't seem to get it to work even a little bit.
I believe your array is too small and therefore when you are reading fscanf overwrites memory causing bizarre behavior
If you just want to read the file - presuming now there is one name per line followed by newline in the input file - just read the file using fgets() instead.
#define MAXLINE 256
char name[MAXLINE];
while (fgets(name,sizeof(name),pRead)!=NULL)
{
// do whatever
}
Related
So I've written a program that will take in a information about a dvd (specifically it's postion, IDkey(just some random number) Title, Genre and Year of release), and using a struct it will write that info to a .txt file called "person.txt". I'm positive my code works for the most part but when I go to test it the output received in the .txt file is written in some weird symbol language and not English and quite frankly I have no idea as to why this is. Any explanation on why this is happening would be much appreciated, thanks :)
PROGRAM
#include <stdio.h>
#include <stdlib.h>
// a struct to read and write
struct dvd
{
int fposition;
int fIdKey;
char ftitle[50];
char fgenre[50];
int fyear;
};
int main ()
{
FILE *outfile;
struct dvd input;
// open file for writing
outfile = fopen ("person.txt", "w");
if (outfile == NULL)
{
fprintf(stderr, "\nError opend file\n");
exit (1);
}
printf("Postion: ");
scanf("%d", &input.fposition);
printf("ID Key: ");
scanf("%d", &input.fIdKey);
printf("Title: ");
scanf("%s",&input.ftitle);
printf("Genre: ");
scanf("%s", &input.fgenre);
printf("Year: ");
scanf("%d", &input.fyear);
// write struct to file
fwrite (&input, sizeof(struct dvd), 1, outfile);
if(fwrite != 0)
printf("contents to file written successfully !\n");
else
printf("error writing file !\n");
// close file
fclose (outfile);
return 0;
}
TEST RUN
TEST RUN OUTPUT IN THE .TXT FILE
You are writing these values to the file:
int fposition;
int fIdKey;
char ftitle[50];
char fgenre[50];
int fyear;
But you are displaying the whole file as characters. That kind of works for ftitle and fgenre because they really are characters...though since you don't populate all 50 characters there are some ugly uninitialized characters shown as well. That is easy to fix: just fill the unused characters (as well as the null terminator) with some known character (such as space) before writing to the file, or do not write the unused characters at all. You can use strlen() to find the length of each string and memset() to set the unused characters to a well-known character which is printable.
Next, saving an int and reading it as text is problematic. You need to decide on a single format. Either you write as integers like now, and you read as integers (which means you need a special program to read the file), or you commit to writing only text to the file.
Easiest might be to only write text to the file. You can use fprintf() for that, instead of fwrite(). You can use fprintf() for the character arrays as well, it will automatically write only the "used" part of each string up to the null terminator, skipping all the "garbage" characters.
I couldnt find specific answer to my question. I am really low level, just started and had a class in which I learned to create file from the CodeBlocks. Took code with me home but it wont work because its not on the same computer. So, the idea was to make something that will allow user to choose path for the newly formed .txt file. When, instead of s, I manually insert "c:\example.txt" or something like that, the code creates a file "example.txt" but when I send it as input it simply wont. Why?
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
FILE *a=NULL;
char s[50];
puts("Enter the path of the file: ");
fgets(s,50,stdin);
a=fopen(s,"w");
if(a==NULL)
exit(1);
else
printf("Successful input");
}
So the entire problem was the fgets function which adds the \nat the end? Is there any other idea to make this work?
You can replace the
fgets(s,50,stdin);
with
scanf("%49[^\n]%*c", s);
- this reads input excluding the \n into s, as long as its size allows, and consumes the \n, so that it doesn't get into the way of possible later input.
I'm trying to do a relatively simple library project in C, but I'm stuck. I'm using fscanf to set a variable (cote which is char[5]) and then fgets to set another variable (titre which is a char[50]). Both of these variables belong to a structure called Ouvrage.
The problem is that fgets seems to add the string it is reading to cote, before the fgets : strlen(o.cote) returns 5 yet afterwards it returns 31.
Here is the code for test.c :
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct {
char cote[5];
char titre[50];
} Ouvrage;
void main(void)
{
FILE *flot;
Ouvrage o;
// Opening the file
flot = fopen("ouvrages.don", "r");
if(flot == NULL)
{
printf("Error opening file.\n");
exit(1);
}
// Reading the cote
fscanf(flot, "%s%*c", o.cote);
// Printing the length of cote
printf("STRLEN: %d\t", strlen(o.cote));
// Reading the titre
fgets(o.titre, 50, flot);
o.titre[strlen(o.titre) - 1] = '\0';
// Printing the length of cote again.... Different.
printf("STRLEN: %d\n", strlen(o.cote));
}
And here is the ouvrage.don file :
NJDUI
Charlie et la chocolaterie
ROM
Rhoal Doal
So how is fgets affecting a previous variable and how to stop it ? Any help is greatly appreciated.
Welcome to the world of c-strings. Assuming cote is supposed to be 5 characters long, you actually need to reserve 6 characters in order to have space for the end of string character ('\0'); what happened was that fscanf wrote that string character as the first character of titre,but then fgets overwrote that, which is why you saw what you saw. Also note that as far as I'm concerned, scanf and related is the tool of the devil; why not just use fgets (which allows you to specify the maximum number of bytes to read [read closely the manpage to avoid an off by one]) for both reads?
I am working on a school project in which we have to do some operations (select, min, max) on a table saved in .txt file.
The problem is that we can't use common functions such as fopen, fscanf, fclose.
The program will be launched from command line like this: .\project.exe select parameters <table.txt
Do you have some ideas how to get content of the .txt file to stdin without using fopen?
Thanks.
You do not need to open the file - the operating environment will do it for you.
When your program is called with <table.txt, your standard input is switched to read from that file instead of the keyboard. You can use scanf to read the data, and do not worry about opening and closing the file.
Same goes for the output of your program and the >table_out.txt redirection: rather than printing to the screen, printfs in your program would be writing to a file, which would be automatically closed upon your program's exit. Of course if you need to print something to the screen when your output is redirected, you can do so by printing to stderr (e.g. fprintf(stderr, "Invalid table format\n").
There are few ways to acomplish this.
Reading STDIN
I guess the teacher wants this method in particular. The idea is reading standard input rather than particular file.
In C++ you can simply read the stdin object. Here's an example:
#include <stdio.h>
#include <string.h>
int main(void)
{
char str[80];
int i;
printf("Enter a string: ");
fgets(str, 10, stdin);
/* remove newline, if present */
i = strlen(str)-1;
if( str[ i ] == '\n')
str[i] = '\0';
printf("This is your string: %s", str);
return 0;
}
Source: http://www.java2s.com/Code/C/Console/Usefgetstoreadstringfromstandardinput.htm
Using system utils
You can call "type" util # Windows (not sure about it) or "cat" util in Linux as a subprocess to read some partticular file. But this is rather a "hack", so I do not recommend using this one.
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.