C programming fopen - c

#include <stdio.h>
#include <stdlib.h>
typedef struct aluno{
char cabecalho[60];
char info[100];
int n_alunos;
char dados[100];
char curso[100];
int numero;
char nome[100];
char e_mail[100];
int n_disciplinas;
int nota;
}ALUNO;
void cabclh(ALUNO alunos[],int a){
FILE *fp;
int i;
for(i=0;i<100;i++){
fp=fopen("trabalho.txt","r");
if(fp==NULL){
printf("Erro ao abrir o ficheiro\n");
}
while(!feof(fp)){
fgets(alunos[i].cabecalho,60,fp);
printf("%s\n",alunos[i].cabecalho);
}
}
fclose(fp);
}
what is wrong here?
main:
int main(int argc, char *argv[]){
ALUNO alunos[100];
int aluno;
int b;
cabclh(aluno,b);
system("PAUSE");
return 0

Quite a few issues here.
The first parameter passed to cabclh is of the wrong type:
void cabclh(ALUNO alunos[],int a);
: :
int aluno;
cabclh(aluno,b);
You should probably exit the function (or some other error handling) if you can't open the file:
if (fp==NULL){
printf("Erro ao abrir o ficheiro\n");
return; // <- Added
}
There's no need to open the file a hundred times. If a regular file doesn't open the first time, it probably won't open at all (although there are cases where this may happen). This particular segment will result in wasted file handles:
for(i=0;i<100;i++){
fp=fopen("trabalho.txt","r");
}
In addition it will reset the file pointer to the start of the file each time.
If your intent is to read up to 100 items from that file for storage into your array, I would suggest you start with:
#include <stdio.h>
#include <stdlib.h>
typedef struct aluno{
char cabecalho[60];
char info[100];
int n_alunos;
char dados[100];
char curso[100];
int numero;
char nome[100];
char e_mail[100];
int n_disciplinas;
int nota;
} ALUNO;
void cabclh (ALUNO alunos[]) {
FILE *fp;
int i;
// Initialise all elements to indicate no data.
for (i = 0; i < 100; i++)
alunos[i].cabecalho[0] = '\0';
// Open the file, returning if not there.
fp = fopen ("trabalho.txt","r");
if (fp == NULL) {
printf("Erro ao abrir o ficheiro\n");
return;
}
// Only allow up to 100 elements.
for (i = 0; i < 100; i++) {
// Only read and load if more to go.
if (!feof(fp)) {
// Read the line and strip off newline character.
fgets (alunos[i].cabecalho,60,fp);
if (alunos[i].cabecalho[strlen(alunos[i].cabecalho)-1] == '\n')
alunos[i].cabecalho[strlen(alunos[i].cabecalho)-1] = '\0';
printf ("%s\n", alunos[i].cabecalho);
}
}
// Close the file.
fclose (fp);
}
int main (int argc, char *argv[]) {
ALUNO alunos[100];
cabclh(alunos);
system("PAUSE");
return 0;
}
It successfully reads a test file I created. Now it may be that your input file is more complicated that just 100 strings to be loaded into cabecelho but the code above is a good start, showing the controlling logic. Ad different line format would only change the way each line is read, not the loop around it.
And, if you want to be able to handle arbitrary numbers of lines, I would move away from arrays to more expandable data structures. But, for a first attempt, you're making the right choice keeping it simple.

It looks like you're opening the file 100 times, then using a while loop with [i] that's never changing. i = 100 because it's never changed inside your while loop.

I see at least one thing wrong:
char cabecalho[60];
// ... and later ...
fgets(alunos[i].cabecalho,100,fp);
Last I checked, 100 is bigger than 60, so you have a buffer overflow error.

I don't understand why are you doing an fopen 100 times:
for(i=0;i<100;i++){
fp=fopen("trabalho.txt","r");
}
Just do:
fp=fopen("trabalho.txt","r");

Besides all the other errors, you have an extra brace above the fclose(fp), which is likely causing a compilation issue due to unmatched braces.

void cabclh(ALUNO alunos[],int a){
FILE *fp;
int i=0;
fp=fopen("trabalho.txt","r");
if(fp==NULL){
printf("Erro ao abrir o ficheiro\n");
return;
}
while(!feof(fp) && i<100){
fgets(alunos[i].cabecalho,60,fp);
printf("%s\n",alunos[i++].cabecalho);
}
fclose(fp);
}

Related

Beginner, trying to read file returns a null pointer in ubuntu

#define max 5
typedef struct
{
char tar[20];
int trab[31];
}data;
int main()
{
int i,j, aux;
char fname[25];
data inf[max];
/*for(i=0;i<max;i++)
{
strcpy(inf[i].tar,inf[i-1].tar);
}*/
printf("File name?");
scanf(" %s", fname);
FILE *f=fopen("fname","r");
if(f== NULL)
{
printf("Cannot find\n");
return 1;
}
I try to read a file I'm very certain is in the same dir, however each time the FILE pointer returns NULL.
I would appreciate any help :(
Although you've tagged this as C++, your code looks more like C, so I'm using a C signature for main. The main problem you have is quotes around fname. Your code is ignoring the path that was entered and trying to open a file with the literal name fname.
int main(void)
{
int i,j, aux;
char fname[25];
printf("File name? ");
scanf(" %24s", fname); /* Always use width specifier on %s */
FILE *f=fopen(fname, "r"); /* No quotes around fname */
if( f == NULL ){
perror(fname);
return 1;
}
...

My C Program Keep Crashing

i am trying to create an program to generate empty files. but when it try to run the program it crashes after taking inputs from the console .
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
int create(char* filename)
{
char filext[10];
printf("\nEnter File Extension :");
fgets(filext);
FILE* fp;
fp = fopen(strcat(filename,strcat(".",filext)),"w");
if(!fp)
{
return 0;
}
fclose(fp);
return 1;
}
int main(int argc , char* argv[])
{
int f;
int i;
char buffer[33];
if (argc == 3)
{
for(i = 0; i < atoi(argv[2]) ; i++)
{
f = create(strcat(argv[1],itoa(i,buffer,10)));
if(f==0)
{
printf("error in creating files . check uac!!!");
}
else{
printf("\nfile Created ...\n");
}
}
}
else{
printf("syntax Error");
}
return 0;
}
when I try to run this program I get the following output
F:\selfcreatedtools\filegen>gcc gen.c
F:\selfcreatedtools\filegen>a level 100
Enter File Extension :php
after entering the extension the program crashes.
i am a beginner in c programming.
Your main problem lies in the strcat(".",filext) part of fp = fopen(strcat(filename,strcat(".",filext)),"w");
Try
strcat(filename, ".");
strcat(filename, filext);
fp = fopen(filename, "w");
And it might be better if the function definition header was made
int create(char filename[SIZE]) (where SIZE is a value less than the size filename will be) instead of int create(char* filename) since you are using strcat() to modify the string in the user-defined function create(). You wouldn't want illegal memory accesses that would cause errors if the string encroaches upon the memory allotted to something else.
A similar problem is there with using strcat() to modify the string at argv[1] as pointed out by Jonathan Leffler for which BLUEPIXY has provided a solution in the comments.

Get the user to enter a name but using file stream *fp

I am a beginner in c so I have a problem with get the user to input last name, a comma & then first name. However it will pass to the function call
int get_name(FILE *fp)
in my main function. I have a problem either if I have to use the arguments parameters.
Example, main (int argc, char *argv[])) or just main (void))
and from what I have been searching so far, FILE*fp cannot get the user to enter from stdin it only use to open the file(?) BUT I am required to get the user to input from keyboard and pass to the function. I have written some codes. but they don't seem to work but I am going to put down on here the one I am sure that I need a few changes most.
#define LINESIZE1024
int main(void){
FILE *fp;
char line[LINESIZE];
char first;
char last;
char comma;
while(1){
if(!fgets(line,LINESIZE,stdin)){
clearerr(stdin);
break;
}
if(fp = (sscanf(line,"%s %s %s",&last,&comma,&first)==3))
get_name(fp);
if(get_last_first(fp)== -1)
break;
printf("Please enter first name a comma and then last name");
}
BUT I got an error saying I can't use pass it from pointer to an integer. and many MORE but I accidentally closed my concolse and all the errors that appeared while I was trying to fix are gone. So please give me some ideas.
What about seconde code
while(1){
if(!fgets(line,LINESIZE,fp)){
clearerr(stdin);
break;
}
if(sscanf(line,"%s %s %s",last,comma,first)==3)
get_last_first(fp);
return 0;
}
It gave me errors too. fp,last,first,comma used uninitialized in this function
OK so I think I have fixed the previous problem now. However it doesn't print the name back if the name is given correctly. Here is my fixed main code.
int main(void){
FILE *fp = stdin;
char line[LINESIZE];
char first[16];
char last[16];
while(1){
if(!fgets(line,LINESIZE,stdin)){
clearerr(stdin);
break;
}
if(sscanf(line,"%s ,%s",last,first)==2)
if(get_name(fp)==2)
printf("Your name is: %s %s\n", first, last);
}
return 0;
}
here is my function.
int get_name(FILE *fp){
char line[LINESIZE];
char last[16], first[16];
int n;
/* returns -1 if the input is not in the correct format
or the name is not valid */
if(fgets(line, LINESIZE, fp) == NULL) {
return -1;
}
/* returns 0 on EOF */
if((n = sscanf(line, " %[a-zA-Z-] , %[a-zA-Z-]", last, first)) == EOF) {
return 0;
}
/* prints the name if it's valid */
if((n = sscanf(line, " %[a-zA-Z-] , %[a-zA-Z-]", last, first)) == 2) {
return 2;
}
return 1;
}
I thank you people so much for taking time to read and help me. Please don't be mean :)
Seems that you are making it more complicated than needed. Don't call fgets and scanf in main. Only do that in the function get_name.
It can be something like this:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define LINESIZE 1024
int get_name(FILE *fp)
{
char line[LINESIZE];
char* t;
if(!fgets(line, LINESIZE,fp))
{
printf("Error reading input\n");
return 0;
}
t = strstr(line, ",");
if (t)
{
*t = '\0';
++t;
printf("First: %s - Last: %s\n", line, t);
return 2;
}
printf("Illegal input\n");
return 0;
}
int main(int argc, char **argv)
{
get_name(stdin);
return 0;
}
If you later decide that you want to read from a file, you can reuse the function get_name without changing it at all. All you need is to change main. Like:
int main(int argc, char **argv)
{
FILE* f = fopen("test.txt", "r");
if (f)
{
get_name(f);
fclose(f);
}
else
{
printf("Open file failed\n");
}
return 0;
}
If you want to read from the keyboard, read from stdin or use scanf, which internally reads from stdin. If you want to read from a file instead, use FILE *fp, but don't forget to open the file and check if it was successful (you'll find lots of tutorials for this).
Further, when reading in strings, you need an array of characters, not a single one. Note further, that scanf can already deal with formats like "everything that is not a ',' then a ',' then a string. Note that format "[^,]" means "any character except a ',':
So you could adapt the code as follows:
#define LINESIZE 1024
int main(void){
char line[LINESIZE];
char first[LINESIZE];
char last[LINESIZE];
while(fgets(line,LINESIZE,stdin)) {
if(sscanf(line,"%[^,],%s",last,first)==2) {
printf("Read in %s ... %s\n",last,first);
}
else {
printf("Please enter first name a comma and then last name");
}
}
return 0;
}
And if your professor is picky concerning the "use FILE*", you could write:
FILE *fp = stdin;
...
while(fgets(line,LINESIZE,fp)) {
...

fgets and sscanf records from file with delimitators

I have to read from a file multiple records(each components of the records are separated by a comma), and I can't understand what's the problem, so here's my file:
Rossi,Mario,M,mariorossi#gmail.com,3923333332,Portiere Bianchi,Giuseppe,M,giuseppebianchi#gmail.com,3470000021,Attaccante Ferrari,Anna,F,annaferrari#gmail.com,3466482645,Attaccante Romano,Antonio,M,antonioromano#gmail.com,3450394672,Centrocampista
and here's my code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct dati_giocatori {
char cognome[20];
char nome[20];
char genere[20];
char email[50];
char telefono[16];
char ruolo[20];
};
typedef struct dati_giocatori GIOCATORE;
void stampa_file(FILE *pfile, GIOCATORE *vettore, int dim, char *stringa);
int main (){
FILE *pfile;
GIOCATORE *vettore;
int dim=0;
char stringa[200];
printf("Quanti giocatori vuoi visualizzare?");
scanf("%d",&dim);
vettore=(GIOCATORE*)malloc(dim*sizeof(GIOCATORE));
pfile=fopen("Giocatori.txt","r");
stampa_file(pfile,vettore,dim,stringa);
system("pause");
fclose(pfile);
pfile=fopen("Giocatoriv.txt","r");
system("pause");
free(vettore);
fclose(pfile);
system("pause");
return 0;
system("pause");
}
void stampa_file(FILE *pfile, GIOCATORE *vettore, int dim, char *stringa){
int i=0;
int j=0;
if(pfile!=NULL){
if(!feof(pfile)){
while(i<dim){
if(!feof(pfile)){
fgets(stringa,200,pfile);
sscanf(stringa,"%[^,],%[^,],%[^,],%[^,],%[^,],%s",vettore[i].cognome,vettore[i].nome,
vettore[i].genere,vettore[i].email,vettore[i].telefono,vettore[i].ruolo);
i++;
}
else{
printf("\n----- Giocatori finiti -----\n");
printf("\n");
i=dim;
}
}
}
else{
printf("\nFile finito.\n");
}
}
else{
printf("Errore nell'apertura del file.\n");
printf("\n");
}
while(j<dim){
printf("%s,%s,%s,%s,%s,%s\n",vettore[j].cognome,vettore[j].nome,
vettore[j].genere,vettore[j].email,vettore[j].telefono,vettore[j].ruolo);
j++;
}
system("pause");
}
I know the problem is with the sscanf(), because it prints on screen just the first component of every record, and five commas, but I can't figure out how to solve this problem... It does not assign the right data to the right place on the records, is the sscanf() format correct? I am not very familiar with delimiters, how should I fix this?
Thanks everyone for helping. I'm sorry you waited so long for the response but I could not edit yesterday. I'm really sorry also for the posting errors, I'm new at stack overflow and I'm also new in C (it's my first language)...(and just to make it difficult to me, I'm also not a native speaker as you can notice by my grammar errors).
Yes the email addesses are fake.
By the way, I'm gonna be honest I don't know hot to check if the file has a newline character at the end of every record...While writing the file I thought that pressing "enter" would gave to me the newline character, but reading you comments I am not sure anymore. I want to use newline character at the end of every record, but how do I do that? and, will this make my code work?
(I opened a second time the file because I was just trying other things on it, so please don't mind about that, same for the system pause).
Okay, first of all next time make your question and specially your code more readable (you must use indentation properly). I don't understand why you use so many system("pause"); also in a wrong way. You also cast the result of vettore=(GIOCATORE*)malloc(dim*sizeof(GIOCATORE)); and you should not do it. You open the file, then use it, close it and open a new file doing nothing on it so I removed this. Note that using while (!feof(file)) is always wrong. Then in your stampa_file function I made lots of changes.
Here is the code.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/*
* NOTE: I'M NOT CHECKING **ANY** RETURNING ERROR
* SUCH AS FROM FOPEN OR MALLOC.
*/
struct dati_giocatori {
char cognome[20];
char nome[20];
char genere[20];
char email[50];
char telefono[16];
char ruolo[20];
};
typedef struct dati_giocatori GIOCATORE;
void stampa_file(FILE *pfile, GIOCATORE *vettore, int dim, char *stringa);
int main (){
FILE *pfile;
GIOCATORE *vettore;
int dim=0;
char stringa[200];
printf("Quanti giocatori vuoi visualizzare?");
scanf("%d",&dim);
vettore= malloc(dim*sizeof*vettore);
pfile=fopen("Giocatori.txt","r");
stampa_file(pfile,vettore,dim,stringa);
fclose(pfile);
return 0;
}
void stampa_file(FILE *pfile, GIOCATORE *vettore, int dim, char *stringa){
int i=0;
int j=0;
size_t size = 200;
if(pfile!=NULL){
while((getline(&stringa, &size, pfile)) != -1 && i<dim) {
sscanf(stringa,"%[^,],%[^,],%[^,],%[^,],%[^,],%s",vettore[i].cognome,vettore[i].nome,
vettore[i].genere,vettore[i].email,vettore[i].telefono,vettore[i].ruolo);
i++;
}
}
printf("No more records to read\n");
while(j<i){
printf("%s,%s,%s,%s,%s,%s\n",vettore[j].cognome,vettore[j].nome,
vettore[j].genere,vettore[j].email,vettore[j].telefono,vettore[j].ruolo);
j++;
}
if(dim > i){
printf("Not enough players\n");
}
}
That's the file I used for tests:
Rossi,Mario,M,mariorossi#gmail.com,3923333332,Portiere
Bianchi,Giuseppe,M,giuseppebianchi#gmail.com,3470000021,Attaccante
Ferrari,Anna,F,annaferrari#gmail.com,3466482645,Attaccante
Romano,Antonio,M,antonioromano#gmail.com,3450394672,Centrocampista

Print out first line of input file char by char, but nothing comes to screen

So Im trying to print out the first line of a file thats being passed in lets say its a plain text file with a couple of words in the first line.
I open the file and pass it through a function that does some work on the file called process. This little bit of work if for debugging reason , because my ultimate goal is to read in the entire text file line my line and process each line and reverse the words in that line.
But im stuck here i run the program with a text file argument and i get nothing in return and i know my logic sounds right i think? I just want this to ultimately printout every character in that line. Then eventually put all those characters in a char array or char instream[500]
Can someone tell me what iam doing wrong?
#include <stdio.h>
#include <stdlib.h>
void process(FILE *infile);
int main(int argc, char *argv[])
{
int i;
FILE *fp;
printf("argc = %d\n",argc);
for(i = 1 ; i <= argc; i++)
{
fp = fopen(argv[i], "r");
if(fp == NULL)
{
printf("The file: %s doesnt exist.\n", argv[i]);
}
else
{
printf("The file: %s does exist \n",argv[i]);
process(fp);
}
}
return 0;
}
void process(FILE *infile)
{
int k =0;
char iochar;
char instream[500];
while((iochar = getc(infile)) != '\n')
{
printf("Hi there %c", iochar ); // nothing prints out here why not??
//instream[k++] = iochar;
}
}

Resources