For my assignment I have to create a program similar to the -wc unix command which counts words, lines, etc.
I have to read in flags and read in a text file.
I've set up all the flags and now I'm trying to read in a text file. I don't think I'm doing this right.
void readInFile(char** argv, int arg)
{
FILE *myFile;
char c;
myFile = fopen(argv[arg], "r");
if(!myfile)
{
printf("%s not found!", argv[arg]);
exit(EXIT_FAILURE);
}
}
in my main I call the function readInFile() and pass 2 arguments. Argv and the element where the file should be. So assume this to be correct.
I need help with actually opening up the file. I feel like my fopen() is wrong. I'm new to reading/writing files in C. Thanks alot!
I'm going to give you some general advice here.
Usually functions should do a single job. In this case, you are writing a function to read in a single file. So, don't pass a pointer to all the command-line arguments; pass in a single read-only pointer to the name of the file to open. Then in main() select the correct argument and pass that as the argument.
void readInFile(char const *filename)
Now, if this function will be reading in the file and doing nothing else, it needs to return the data somehow. But if this function will be doing the equivalent of wc, maybe it will read the file and print stuff, not return any data to the main() function. Then maybe the name should be improved:
void wordcount(char const *filename)
The actual call to fopen() looks fine to me.
You check for error, and then call exit() immediately. That's one way to do it. Another way to do it is to return an error code from your function, and have the caller (the main() function) check for failure, and handle the error there.
int wordcount(char const *filename)
{
// ... do stuff
if (failed)
return 1; // return nonzero error code on failure
// ... do more stuff
return 0; // success code
}
int main(int argc, char const **argv)
{
char const *filename;
int result;
filename = argv[1];
result = wordcount(filename);
if (result)
{
fprintf(stderr, "unable to open file '%s'\n", filename, result);
exit(result);
}
return 0;
}
For a program this simple, it doesn't matter much. But once you start building larger systems in software, you will be happier if your functions work well together, and part of that is making functions that return error codes rather than terminating your whole program on any error.
Why am I using 0 for the success code, and non-zero for failure? It's a common way to do it. It's easy to test for non-zero, like if (result) and there are many non-zero codes but only one zero, so you can return many different kinds of errors, but there is only one value needed for "success".
Note that instead of calling exit() from main(), you can just use the return statement. When you return 0 from main(), that signals success, and a non-zero value indicates an error. So you could just use return result; from main() if you like.
In my dummy code, I'm just returning 1 as the error code. But actually, when you call fopen() it returns an error code to you, in a global variable called errno. Probably a better option is to make your function return the actual error code as specified in errno. You could even modify the print statement in the main() function print the errno code, or use the strerror() function to turn that error code into a human-readable message.
Your call to fopen is correct, assuming that argv[arg] is a valid string which refers to a file that exists on the filesystem.
There is a small typo in the program snippet. if(!myfile) should prpbably be if(!myFile). With this change, I presume the code should work. Can you please elaborate the error faced by you?
P.S: I tried your program and it seems to work!
Related
I have this code, note that it is shortened down. The problem is if the file exists
it still overwrites it. Been 30 years since I did any programming so bear with me. Thanks!
FILE *openFil(FILE *open, char namn[]);
int main(int argc, const char * argv[])
{
FILE *openFil(FILE *open, char namn[]);
FILE *anmal =NULL;
char filNamn[] = "ANMAL.DAT";
postTypAnm pAnm;
anmal = openFil(anmal, filNamn);
}
FILE *openFil(FILE *pointer, char name[])
{
if ((pointer =fopen(name, "r+b"))== NULL)
if ((pointer =fopen(name, "w+b"))== NULL)
{
/* It Enters here as well, but it should not do that or????? */
printf("error\n");
exit(0);
}
return pointer;
}
If you're using the C11 standard you can use the "x" argument to specify that if the file exists the fopen() function will fail.
For reference: http://www.cplusplus.com/reference/cstdio/fopen/
Here's a working example.
#include <errno.h>
#include <stdio.h>
#include <stdbool.h>
#include <stdlib.h>
bool openFile(FILE **ptr,
const char *fileName);
int main(int argc, const char * argv[]) {
FILE *anmal = NULL;
const char *fileName = "ANMAL.DAT";
if(!openFile(&anmal, fileName)) {
exit(EXIT_FAILURE);
}
}
bool openFile(FILE **ptr,
const char *fileName)
{
*ptr = fopen(fileName, "w+bx");
if(!*ptr) {
perror("Error opening file: ");
return false;
}
return true;
}
This is using the x extension in GNU C to test whether the file exists.
As other people have pointed out, there are numerous problems in your original code.
You've redeclared the function prototype for openFil within main.
In openFil there's no point in both accepting the FILE pointer as
a parameter and overwriting it with the return value. Especially if
you're expecting to input a NULL pointer and use the function to
initialise it. Either use a pointer-to-pointer as a parameter so you
can modify the pointer within the function, or ignore it completely
and set its value with the function's return value. Not both.
You're not actually testing for whether the file exists at all. According to the manual pages for fopen (man fopen) neither of the flags you used in opening the file (r+ and w+) care whether the file exists. r+ opens for reading/writing and always positions the stream at the beginning of the file. w+ opens for reading/writing, truncating the file if it exists already. This explains why you didn't get the effect you intended.
1.
"It Enters here as well, but it should not do that or?????"
No, It shouldn´t. If both pointers are NULL the opening of the streams to ANMAL.DAT were not successful, neither in w+b nor in r+b mode. Proof if the file really exist in the directory of the executable. Else try to use the entire path from the root directory to the file.
"The problem is if the file exists it still overwrites it."
Why do you know that the file is really overwritten in a proper manner?
Since if ((pointer =fopen(name, "r+b")) == NULL) and if ((pointer = fopen(name, "w+b"))== NULL) both fail, it seems that the ANMAL.DAT does not exist where fopen() searches for it or otherwise an error occurs when trying to open it (maybe has incorrect format or is corrupted?).
Place perror(name) in the error routine to check if errno was set to indicate an error at name.
2.
In the error routine: exit(0) is not correct if an error has happened. Use exit(EXIT_FAILURE).
Side note:
You have another prototype for the function openFil-> FILE *openFil(FILE *open, char namn[]); inside of main, which is redundant.
Also the identifier of the second parameter is different in the prototype before main to the identifier at the definition of openFil, namn in comparison to name.
Does scope impact, checking for errors while obtaining input from stdin or outputting to stdout? For example if I have a code body built in the following way:
void streamCheck(){
if (ferror(stdin)){
fprintf(stderr, "stdin err");
exit(1);
}
if (ferror(stdout)){
fprintf(stderr, "stdout err");
exit(2);
}
}
int main(){
int c = getchar();
streamCheck();
...
putchar(c)
streamCheck();
}
are the return values of ferror(stdin) / ferror(stdout) impacted by the fact that I am checking them in a function rather than in the main? If there is a better way to do this also let me know I am quite new to C.
As long as you call ferror on a particular stream before calling any other function on that stream you should be fine.
It doesn't matter that ferror is being called from a different function that getchar or putchar was called from.
There is no problem in your function. ferror() checks the error indicator of the FILE * that is passed as argument. In other words, the error indicator is a property of the file object and is directly obtainable from the FILE * pointer. Therefore, no matter where you call ferror() from, it will be able to determine if an error happened with the FILE * that is passed as argument (that is, of course, if the argument is valid).
are the return values of ferror(stdin) / ferror(stdout) impacted by
the fact that I am checking them in a function rather than in the
main?
The return value of ferror() is characteristic of the current state of the stream that you provide as an argument. At any given time, the stdin provided by stdio.h refers to the same stream, with the same state, in every function, including main(). Therefore, you will obtain the same result by calling the ferror() function indirectly, via an intermediary function, as you would by calling it directly.
NEVERTHELESS, the approach you present in your example is poor. For the most part, C standard library functions indicate whether an error has occurred via their return values. In particular, getchar() returns a special value, represented by the macro EOF, if either the end of the file is encountered or an error occurs. This is typical of the stdio functions. You should consistently test functions' return values to recognize when exceptional conditions have occurred. For stream functions, you should call ferror() and / or feof() only after detecting such a condition, and only if you want to distinguish between the end-of-file case and the I/O error case (and the "neither" case for some functions). See also "Why is 'while ( !feof (file) )' always wrong?"
Personally, I probably would not write a generic function such as your streamCheck() at all, as error handling is generally situation specific. But if I did write one, then I'd certainly have it test just one stream that I specify to it. Something like this, for example:
void streamCheck(FILE *stream, const char *message, int exit_code) {
if (ferror(stream)) {
fputs(message, stderr);
exit(exit_code);
}
}
int main(void) {
int c = getchar();
if (c == EOF) {
streamCheck(stdin, "stdin err\n", 1);
}
// ...
if (putchar(c) == EOF) {
streamCheck("stdout err\n", 2);
}
}
I am trying to exit a program without using exit(). I have come up with a very convoluted and dirty solution (I am a Beginner).
I would like to use if statements and if it is true, then I would like to use goto to go the main function and then return 3; and end the program.
Here is a bit of code:
FILE *filepointer;
char * line = NULL;
size_t len = 0;
size_t read;
int linecount = 0;
filepointer = fopen(filename, "r");
if (filepointer == NULL)
{
printf("[ERR] Could not read file %s.\n",filename );
goto FILE_ERROR;
}
...
int main(){
...
FILE_ERROR: return 3;
}
This however does not work as I cannot get jump between functions because I get undeclared Label as an error. Is there any way I can exclude exit() from my program and still end it returning a certain value. If there is a better solution, please let me know
The only good answer to this question is: don't do it. gotos used in this way make your code very hard to reason about.
Refactor your code so that you have a clear structure and hierarchy of calls. Use return values to propagate success/failure throughout the call stack.
goto can't be used to jump across different functions; it can only be used within the same function. To jump between functions, you can look at setjmp() and longjmp() functions.
Having said, since you claim to be a beginner, I am not convinced you really need to use either of the above. You can simply modify your function to return an "error" value. And in main(), check its value and return from main() with the error value.
By design, a goto cannot jump from one function to another. It can only be used to jump within a given function.
There are ways to jump between functions, but doing so is not only very poor design but also dangerous as it is very easy to put your program in an invalid state.
The proper way to handle this is to have your function return a specific value (or set of values) to indicate an error. Then the calling function would check for one of those error values and act accordingly.
For example:
int readFile(char *filename)
{
FILE *filepointer;
char * line = NULL;
size_t len = 0;
size_t read;
int linecount = 0;
filepointer = fopen(filename, "r");
if (filepointer == NULL)
{
// add strerror(error) to the error message to know why fopen failed
printf("[ERR] Could not read file %s: %s.\n",filename, strerror(errno) );
// error completion
return 0;
}
...
// successful completion
return 1;
}
int main(){
...
if (readFile("myfile") == 0) {
return 3;
}
...
}
If you wanted to use a go-to , and insisted on doing that, you could I guess try to expand your 1st function so it includes / encapsulates the 2nd function, and get rid of the 2nd function conpletely, so your able to do go tos and subroutines within this much larger function.
Is that an option you could try ? (If you were dead cert on using Goto's, ) ?
I would give that a go.
I have to a do C program that uses the unix environment. I have already purchased the "Advancing Programming in the Unix Environment" book and it has helped out a lot so far. However, some of my questions have gone unanswered and I'm looking for some help.
I'm trying to write a program that can verify if the first and second arguments entered if a copy program exist. If the first argument does not exist, then an error message and exit must occur. If the second argument does exist, then an overwrite prompt must be displayed. I'm not exactly sure how to verify if a file already exists or not basically.
I have seen a few people saying that you can do (!-e) or something like that to verify the file existing/not existing.
If anyone could help me, I'd really appreciate it.
The access() function is designed to tell you if a file exists (or is readable, writeable or executable).
#include <unistd.h>
int result;
const char *filename = "/tmp/myfile";
result = access (filename, F_OK); // F_OK tests existence also (R_OK,W_OK,X_OK).
// for readable, writeable, executable
if ( result == 0 )
{
printf("%s exists!!\n",filename);
}
else
{
printf("ERROR: %s doesn't exist!\n",filename);
}
in your int main(int argc, char** argv) { block.
if (argc == 3) {
// then there were 3 arguments, the program name, and two parameters
} else if (argc == 2) {
// then prompt for the "second" argument, as the program name and one
// parameter exists
} else {
// just print out the usage, as we have a non-handled number of arguments
}
now if you want to verify that the file exists, that's different than verifying that the program argument exists. Basically attempt to open the file and read from it, but pay close attention to catching the integer error codes and checking them for errors. This will prevent your program from progressing into bits where those critical operations are assumed to have worked.
There is a common, yet misguided conception among new programmers when dealing with files in C. Basically, one really wants to make sure that a specific block of code works (the copying block in your case), so they check, check, and double-check conditions before the block is executed. Check if the file exists, check if it has correct permissions, check that it isn't a directory, etc. My recommendation is that you not do this.
Your copying block should be able to fail properly, just as properly as it should be able to succeed. If it fails, then typically you have all the information necessary to print out a meaningful error message. Should you check first and then act there will always be a small time gap between the check and action, and that time gap will eventually see the file removed or altered after the checks have passed, yet before it is read. Under such a scenario all of the pre-checking code failed to provide any benefit.
Code without benefit is just a nesting ground for future bugs and architectural problems. Don't waste your time writing code that has dubious (or no) benefit. When you suspect that some code you have written has little benefit, you need to restructure your code to put it in the right place. When you suspect that code someone else has written has little benefit, you need to first doubt your suspicions. It is trivially easy to not see the motivations behind a piece of code, and even more so when just starting out in a new language.
Good Luck!
--- code for the weary ---
#include <errorno.h>
#include <stdio.h>
#include <stdlib.h>
extern int errno;
int main(int argc, char** argv) {
// to hold our file descriptor
FILE *fp;
// reset any possible previously captured errors
errno = 0;
// open the file for reading
fp = fopen(argv[1], "r");
// check for an error condition
if ( fp == 0 && errno != 0 ) {
// print the error condition using the system error messages, with the
// additional message "Error occurred while opening file"
perror("Error occurred while opening file.\n");
// terminate the program with a non-successful status
exit(1);
}
}
If I wanted to run a shell command in linux with a c program, I would use
system("ls");
Is there a way I can accomplish this in Wind River vxworks?
I found the below example but I'm wondering do I need to include vxworks header files for this to work? I assume I do, but how do I figure out which one?
Example:
// This function runs a shell command and captures the output to the
// specified file
//
extern int consoleFd;
typedef unsigned int (*UINTFUNCPTR) ();
extern "C" int shellToFile(char * shellCmd, char * outputFile)
{
int rtn;
int STDFd;
int outFileFd;
outFileFd = creat( outputFile, O_RDWR);
printf("creat returned %x as a file desc\n",outFileFd);
if (outFileFd != -1)
{
STDFd=ioGlobalStdGet(STD_OUT);
ioGlobalStdSet(STD_OUT,outFileFd);
rtn=execute(shellCmd);
if (rtn !=0)
printf("execute returned %d \n",outFileFd);
ioGlobalStdSet(STD_OUT,STDFd);
}
close(outFileFd);
return (rtn);
}
I found the code segment below worked for me. For some reason changing the globalStdOut didn't work. Also the execute function did not work for me. But my setting the specific task out to my file, I was able to obtain the data I needed.
/* This function directs the output from the devs command into a new file*/
int devsToFile(const char * outputFile)
{
int stdTaskFd;
int outputFileFd;
outputFileFd = creat( outputFile, O_RDWR);
if (outputFileFd != ERROR)
{
stdTaskFd = ioTaskStdGet(0,1);
ioTaskStdSet(0,1,outputFileFd);
devs();
ioTaskStdSet(0,1,stdTaskFd);
close(outputFileFd);
return (OK);
}
else
return (ERROR);
}
If this is a target/kernel shell (i.e. running on the target itself), then remember that all the shell commands are simply translated to function calls.
Thus "ls" really is a call to ls(), which I believe is declared in dirLib.h
I think that the ExecCmd function is what you are looking for.
http://www.dholloway.com/vxworks/6.5/man/cat2/ExecCmd.shtml
As ever, read the documentation. ioLib.h is required for most of the functions used in that example, and stdio.h of course for printf().
As to the general question of whether you need to include any particular headers for any code to compile, you do need to declare all symbols used, and generally that means including appropriate headers. The compiler will soon tell you about any undefined symbols, either by warning or error (in C89/90 undefined functions are not an error, just a bad idea).