I have a stem file named myfile
, it has 2 sub files : myfile.data
and myfile.names
.
Now I want to write a code where it will first check the .names
file's last line and see whether there is a zero or not, if there is any other number other than zero then it will say noisy data
. And if the .names
files last line has a zero, then I need to read the .data
file and do some operations on that .data
file to produce a valid output.
Now below I am giving what I have tried to do:
int main(int argc, char **argv)
{
char *path = argc > 1 ? argv[1] : "stdin";
sprintf(path, "%s.names", argv[1]);
FILE *in = argc > 1 ? xfopen(path, "r") : stdin;
char buff[1024];
int check = 0;
fseek(in, 0, SEEK_SET);
while(!feof(in))
{
memset(buff, 0x00, 1024);
fscanf(in, "%[^\n]\n", buff);
}
if(strchr(buff, '0') != NULL){
check = 1;
}
if(check == 0){
printf("Noisy data...\n");
}
else if(check == 1){
char *path = argc > 1 ? argv[1] : "stdin";
sprintf(path, "%s.data", argv[1]);
FILE *in = argc > 1 ? xfopen(path, "r") : stdin;
char buf[1024];
if( fgets(buf, sizeof buf, in) == NULL ){
fputs("Input error\n", stderr);
return 1;
}
...
...
produces the perfect output.
}
}
}
To execute this : <./executable_filename> <stemFileName> > <outputFileName>
So whenever I am doing : ./myFileName myfile output
It is showing me : myfile.names.data: No such file or directory
Why is it happening? Please help.
CodePudding user response:
Here's an example which shows how to open the *.names
file and includes logic to check if the final line of the file satisfies various properties.
#include <errno.h>
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int
main(int argc, char **argv)
{
if( argc < 2 ){
fprintf(stderr, "root filename required\n");
return 1;
}
const char *base = argv[1];
char input_path[PATH_MAX];
snprintf(input_path, sizeof input_path, "%s.names", base);
FILE *ifp = fopen(input_path, "r");
if( ifp == NULL ){
perror(input_path);
return 1;
}
char buf[1024];
/* Read the entire file one line at a time. You could fseek to the
end of the file and seek backwards to the start
of the last line, but that seems to be an unnecessary
complication for this example. */
while( fgets(buf, sizeof buf, ifp) != NULL ){
;
}
/* When you get to the end, the last `fgets` returned NULL
but did not write anything into buf, so buf contains the last
line of the file */
/* Check for read errors.
ferror does not modify errno, but I can't find that
in the language standard, so we'll make a copy. Restoring
errno ensures that `perror` reports the error that occurred
during fgets rather than an error that occurs in the call to
ferror. This is probably overkill for this simple example. It
would be more important to check that `fgets` read a full line
and handle that. If the last line of the file is too large
to fit in `buf`, the program should handle it; probably by aborting
with an error message, but I don't know what you want to do in that
case so I'm not bothering to check.
*/
int errno_sav = errno;
if( ferror(ifp) ){
errno = errno_sav;
perror(input_path);
return 1;
}
puts("The last line is:");
fputs(buf, stdout);
/* Check if the last line contains a '0' */
if( strchr(buf, '0') ){
puts("The last line contains a 0");
}
/* Check if the last line is exactly the string "0\n" */
if( strcmp(buf, "0\n") == 0 ){
puts("The last contains nothing but a single 0");
}
char *end;
/* Check if the last line is exactly some string representation
of the integer 0. (ie, "0000\n" "0x0") */
if( strtol(buf, &end, 0) == 0 && end != buf && *end == '\n'){
puts("The last line is the integer 0");
}
return EXIT_SUCCESS;
}
Note that you might want to check that snprintf
had enough space to write the filename, but that is not practically necessary. If the path is so long that it is an issue, the fopen will fail and you'll get a decent error message. It is possible that this will cause your program to incorrectly process a file with a truncated name like ...bas.nam
, and it might be a good exercise to learn how to deal with that.