Implementation of lexical analysis program in TEST language - c

This is the program I have:
#include <stdio.h>
#include <string.h>
int main()
{
char Scanin[300],Scanout[300];
extern FILE *fin,*fout;
printf("Please enter the source program file name (including the path): ");
scanf("%s",Scanin);
printf("Please enter the lexical analysis output file name (including the path):");
scanf("%s",Scanout);
if((fin=fopen(Scanin,"r"))==NULL)
//Judge whether the input file name is correct
{
printf("\nError opening lexical analysis input file!\n");
return 1;
//Error in input file returned error code 1
}
if((fout=fopen(Scanout,"w"))==NULL)
//Judge whether the output file name is correct
{
printf("\nError creating lexical analysis output file!\n");
return 2;
//Error in output file returned error code 2
}
}
and this is the error I get:
Undefined reference to 'fout'
Undefined reference to 'fin'
error: 1d returned 1 exit status
This code was sent by my teacher and all she told me was to copy the code and give her an executable .exe file. And i am trying to ask help from her but she isn't responding to any of my messages, I am currently still having online classes.

Related

How to do proper error handling with the fopen function

I wrote a program that asks the user to enter the full pathname of a file. It will then attempt to open that file from the pathname string provided. I used the standard error checking that most books have recommended, which is to close the program if fopen() returns NULL (which it will do in the case that the file does not exist). When I run the program and enter some random characters when prompted (obviously not a valid filename) my program hangs with a runtime error because it's trying to open that file that doesn't exist.
What is the point of the standard error check (pfile == NULL) if your program has already crashed when it calls fopen()? See below code.
I'm using LabWindows CVI 2017 as my enfironment which uses the clang compiler. See image of run time error.
#include <stdio.h>
#include <string.h>
#define MAX 200
int main (void){
char buffer[MAX];
int len = 0;
FILE *pfile = NULL;
printf("please enter the full pathname of the file you wish to process.\n");
fgets(buffer, MAX, stdin);
len = strlen(buffer);
buffer[len - 1] = '\0';
pfile = fopen(buffer, "r");
if(pfile == NULL){
printf("not a valid filename, press any key to exit.");
getchar();
return -1;
}
int sum = 0;
int c = 0;
while((c = fgetc(pfile)) != EOF){
sum += sizeof(c);
}
printf("the size of your file is %d\n", sum);
getchar();
return 0;
}
You are doing the proper error handling. Your program is valid in that respect. However, your IDE does some extra error checking, which is the cause of the behavior you're seeing.
The usual rules for error checking in these sorts of situations are:
Do check for error returns. (You're doing that.)
Do print a useful error message. (You're doing that.)
Print error messages to stderr.
If the error involves a file, do include the filename in the error message.
If the error involves a function that sets errno, do print the "perror" text" ("No such file or directory", etc.).
If you're writing a tool that will be combined into larger scripts, do include the program's name in the error message.
If the error occurs due to an input file you're reading, do print the name of that file and the line number.
Adopting rules 1 through 6, an improved version of your error check would be
if(pfile == NULL) {
fprintf(stderr, "%s: can't open %s: %s\n", progname, buffer, strerror(errno));
return EXIT_FAILURE;
}
For this to work you'll need both of:
#include <string.h>
#include <errno.h>
If that's too much work, a simpler way is just to call
perror(buffer);
although this falls down somewhat on rules 2, 6, and 7.

create a file in c programming and write hello world in the file

#include<stdio.h>
int main()
{
FILE *opening;
opening = fopen("hello.usr","w");
fprintf(opening,"Hello world!");
fclose(opening);
printf("Writing to the file was successful.\n");
printf("Closing the program");
return 0;
}
I have tried this code to create a file in c programming and write the text "Hello world!" in it. What's wrong with this code?
If you want to know what is wrong check the result of fopen
opening = fopen("hello.usr","w");
if (opening == NULL) {
perror("fopen");
}
As of now, you don't know whether you managed to write to the file or not, so here's a suggestion which checks for it.
FILE *opening;
opening = fopen("hello.usr", "w");
if (opening == NULL){
perror("fopen");
return 0;
}
By returning 0 here you remove the option for segmentation fault as the code will still try to write to the file even if it doesn't exist.
The error message you are getting most certainly is NOT produced by a compiler. It looks to me as a message of some automatic checker that tests correctness of the submited solutions.
Make sure that the output matches exactly the required one.
The message:
Your program's output is shorter than the expected
may indicate that there is something wrong with new line characters ('\n'). Check for those.
For example if the required output is:
Writing to the file was successful. Closing the program.
... printed in one line, your output obviously doesn't match as it has a new line after the first sentence. And if the checker testes for the first occurrence of a new line character it sees only
Writing to the file was successful.
which could be one of many possible explanations. If this is the case try simply:
#include<stdio.h>
int main()
{
FILE *opening;
opening = fopen("hello.usr","w");
fprintf(opening,"Hello world!");
fclose(opening);
// printf("Writing to the file was successful.\n");
// printf("Closing the program");
printf("Writing to the file was successful. Closing the program\n");
return 0;
}
Note also that this sort of error messages (in automatic testing environments) are usually triggered by ommited, added extra or confused non-printable characters (spaces, tabs, new lines) or punctuation marks which is hard to notice.
You may also want to check in this respect the text you print to the file.
Try to Instead "w" use "wt" in fopen
Try the following
#include <stdio.h>
int main() {
FILE *opening = fopen("hello.usr", "w");
if(opening == NULL){
printf("An error occurred when opening the file!");
return 0;
}
else{
fprintf(opening, "Hello world!\n");
fclose(opening);
printf("Writing to the file was successful.\nClosing the program.\n");
}
return 0;
}

open() call path error

I am having issues with the input of open If my first argument is a path I get this output:
Error en open: No such file or directory
but if its file name there is no error, how can in fix it? The code is as follows:
#include<sys/types.h> //Primitive system data types for abstraction of implementation-dependent data types.
//POSIX Standard: 2.6 Primitive System Data Types <sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<stdlib.h>
#include<stdio.h>
#include<errno.h>
char buf1[]="abcdefghij";
char buf2[]="ABCDEFGHIJ";
int main(int argc, char *argv[])
{
int fd;
if( (fd=open(argv[1],O_CREAT|O_TRUNC|O_WRONLY,S_IRUSR|S_IWUSR))<0) {
printf("\nError %d en open",errno);
perror("\nError en open");
exit(-1);
}
if(write(fd,buf1,10) != 10) {
perror("\nError en primer write");
exit(-1);
}
if(lseek(fd,40,SEEK_SET) < 0) {
perror("\nError en lseek");
exit(-1);
}
if(write(fd,buf2,10) != 10) {
perror("\nError en segundo write");
exit(-1);
}
return 0;
}
The test sequence is:
root#ubuntu:/home/pablo/...# ./tarea1 /home/pablo/hello > temp ; cat temp
root#ubuntu:/home/pablo/...# ./tarea1 /home/pablo/>hello ; cat hello
Error en open: Is a directory
Your second test sequence is:
# ./tarea1 /home/pablo/>hello
This would be more clearly written as:
# ./tarea1 /home/pablo/ >hello
The shell gives your program the name of a directory, /home/pablo/, and creates a file hello in the current directory. Any standard output from your program goes to the file. When your program tries to open the directory for writing, it fails — not even root is allowed to write in a directory. (You can open a directory for reading, but can't actually read from it; that's useful for the various *at() functions (such as openat()), but not otherwise.)
If you really want a > in your file name, enclose the whole name in quotes:
# ./tarea1 "/home/pablo/>hello"
However, you don't really want a > in your file name; it just makes life difficult (not quite as bad as a newline in the file name, but close).
You haven't said whether you're using Linux or not. But I'm going to guess you are.
Linux open has this really annoying feature that for some reason the file doesn't already exist and you use the version of open that doesn't have the third mode parameter, it fails to create the file. At least that's what I've found. If however the file does exist and has the appropriate permissions, the 2 parameter open call should succeed.
The fix is to change the open call to:
fd=open(argv[1],O_CREAT|O_TRUNC|O_WRONLY,S_IRUSR|S_IWUSR, S_IRWXU)
By the way, I hope you're aware that the program will pass null to the open call if there are no parameters.

fopen c with multiple files

In my software I have to read multiple txt databases in a serial way, so I read the first, then I do something with the info I got from that file, than I open another one to write and so on.
Sometimes I got an error on an opening OR creation of a file, and then I got errors on all the following opening/creation, which uses different functions, different variables, different files.
So for example I call the function below, which uses two files, and I got an error "* error while opening file -%s- ..\n", then all the other fopen() in my code goes wrong!
This is an example of code for one single file:
FILE *filea;
if((filea=fopen(databaseTmp, "rb"))==NULL) {
printf("* error while opening file -%s- ..\n",databaseTmp);
fclose (filea);
printf("---------- createDatabaseBackup ----------\n");
return -1;
}
int emptyFolder=1;
FILE *fileb;
if((fileb=fopen(databaseBackup, "ab"))==NULL) {
printf("* error while opening file -%s- ..\n",databaseBackup);
fclose (fileb);
printf("---------- createDatabaseBackup ----------\n");
return -1;
}
else {
int i=0;
char c[500]="";
for (i=0;fgets(c,500,filea);i++) {
fprintf(fileb,"%s",c);
emptyFolder=0;
}
}
fclose(fileb);
fclose(filea);
There is an upper limit on the number of open handles for a given process. May be you have a handle leak in your program ?
Error while creating a file typically means you don't have access permission to the parent folder .
Those error log messages belong to your program . You can enhance it further. There is an errnum set by the os as fopen is essentially a system call. You can print that error number and get more info about your issue.
If fopen returned NULL, the file wasn't opened, so there's no point in trying to fclose it.
You should check the return value of fgets besides whether it is 0 or not. If it reads 500 characters and the buffer is not null-terminated, the fprintf will attempt to write more characters than is allocated for c

Struggling to understand file pointers?

Main description of the problem below, where it happens. But simply, I cannot figure out why I get error messages after asking
if (outf!=NULL){
printf("Output file already exists, overwrite (y/n):");
scanf("%c",yn);
}
Where outf is a file pointer to an existing file. Please read description halfway through code.
#include <stdio.h>
#include <stdlib.h>
#include <float.h>
#include <string.h>
int main() {
/* Declare file pointer */
FILE *inf;
FILE *outf;
int linenumber,linecounter=0,linepresent;
char filename[21];
char detail[21];
char linedetail[21];
char outfilename[21];
char letter,yn='y';
int position;
/*INPUT DETAILS Ask user for file name and line number*/
printf("Please enter an input filename and a linenumber: ");
//scan filename to char string and line number to int variable
scanf("%s %i",&filename,&linenumber);
/*OUTPUT DETAILS Ask user for file name, letter & position, etc*/
printf("Please enter an output filename, a letter and a position:");
scanf("%s %c %i",&outfilename,&letter,&position);
/* Open file for reading */
inf=fopen (filename,"r");
outf=fopen(outfilename,"r");
/*check that file exists*/
if (inf!=NULL) {
Up until here everything works fine!
Then I try to find out if the outf file already exists. If outf points to an existing file, it DOES print "Output file already exists, overwrite (y/n):"
HOWEVER, as soon as it prints this I get error windows opening! This is probably an extremely rookie mistake - I'm still learning C. If there is no such file the program completes normally and bypasses the if statement okay.
if (outf!=NULL){
printf("Output file already exists, overwrite (y/n):");
scanf("%c",yn);
}
if (yn=='y'){
/*keep reading to end of file*/
while (feof(inf)==0) {
linecounter++;
/*read each line and store the line number in detail[WORDS GO HERE]*/
fscanf (inf,"%s", &detail);
/*If we reach the line selected by the user*/
if (linecounter==linenumber){
strcpy(linedetail,detail);
linepresent=1;
}
}
if (linepresent==0) {
printf("File only contains %i lines",linecounter);
}
} else {
exit(1);
}
} else {
printf("Input file not found");
}
printf("%s",linedetail);
/* close the file */
fclose(inf);
fclose(outf);
return (0);
}
First, already mentioned problems: You're opening the output file in reading mode. To open it for writing:
outf=fopen(outfilename,"w"); /* Note the "w". */
Also, scanf() accepts pointers to variables, not their values, so if you write scanf("%c", yn);, you will give scanf the character y as a pointer, which is nonsense. You need to do it like this: scanf("%c", &yn);.
Even if you fix these, however, your program won't do what you expect. If the file you're trying to open for writing doesn't exist, fopen() won't return NULL, it will create a new file. Your code will always overwrite the output file if it exists. NULL is returned only if fopen couldn't open/create the file (e.g. you didn't have the permissions to do it), and you should handle it like this:
outf=fopen(outfilename, "w");
if(outf == NULL) {
perror("Failed to open output file: ");
fclose(inf); /* Don't leave files opened. It's bad form. */
exit(1);
}
/* Open succeeded, do your stuff here. */
Note that no else block is needed after the if, because exit() ends the program immediately.
Also, there is no such thing as a "pointer to a file". FILE is just a structure that represents an open file.
http://www.cplusplus.com/reference/clibrary/cstdio/fopen/
You are open the output file with the read flag. Try changing it to "w".
outf=fopen(outfilename,"w");
Although it is worth noting writing to a file opened with "w" will whack the old file. use "a" to append to the file.
You should pass the address of yn to scanf function.
scanf("%c", &yn);

Resources