Undeclared (first use in this function); did you mean ‘append’? build error - c

I was trying to compile this .c script for centos or ubuntu using gcc and after getting this error tried to debug with Code Blocks but couldn't get around this same error.
#include <stdio.h>
#include <stdlib.h>
#include <strings.h>
#include <unistd.h>
#ifdef LINUX
#include <getopt.h>
#endif
#define STRLEN 1024*64
#define FILE1 argv[optind]
#define FILE2 argv[optind+1]
#define TEMPFILE "temp.nmon"
void hint()
{
(void)printf("Hint: convert an nmon file so it can be merged with an older one\n");
(void)printf("Syntax: nmonmerge [-a] [-v] original-file extra-file\n");
(void)printf("\t[-a] append converted extra-file data to end of the original-file\n");
(void)printf("\t[-v] verbose extra details are output\n\n");
/* 12345678901234567890123456789012345678901234567890123456789012345678901234567890 */
(void)printf("Without -a the merged data is send to stdout, so redirect it (\">\") to\n");
(void)printf("\tsave the converted data.\n");
(void)printf("Note: that header lines are striped out of the 2nd file as they are already\n");
(void)printf("\tin the original file. This assumes no configuration changes like new\n");
(void)printf("\tdisks, LUNs, adapters, networks etc., which would cause header and\n");
(void)printf("\tdata column mismatches\n");
(void)printf("Note: only the timestamps (Tnnnn) and the number of snapshots are modified\n");
(void)printf("\teverything else is unchanged.\n");
(void)printf("Note: be careful as you might have \"missing\" snapshots in the time\n");
(void)printf("\tbetween the data files.\n");
(void)printf("Note: an extra line is added, starting \"AAA,note\" and the filename\n");
(void)printf("\tthis line is ignored other tools but will help in diagnosing errors\n");
(void)printf("Note: do NOT sort the nmon file before merging (sorting not needed now anyway)\n");
(void)printf("Note: nmonmerge uses a temporary file called temp.nmon\n");
(void)printf("Example: to merge three files a.nmon, b.nmon and c.nmon\n");
(void)printf("\tnmonmerge -a a.nmon b.nmon\n");
(void)printf("\tnmonmerge -a a.nmon c.nmon\n");
(void)printf("\tNow a.nmon contains all the data\n");
(void)printf("Example: to merge three files a.nmon, b.nmon and c.nmon\n");
(void)printf("\tnmonmerge a.nmon b.nmon >x.nmon\n");
(void)printf("\tnmonmerge x.nmon c.nmon >y.nmon\n");
(void)printf("\trm x.nmon\n");
(void)printf("\tNow y.nmon contains all the data\n");
exit(0);
}
int main(int argc, char ** argv)
{
FILE *readfp;
FILE *writefp;
int i,j,k,hit,number;
char string[STRLEN+1];
int lastzzzz = 0;
int verbose = 0;
int append = 0;
writefp = stdout;
while ( -1 != (i = getopt(argc, argv, "?hva" ))) {
switch (i) {
case '?':
case 'h':
hint();
case 'v':
verbose++;
break;
case 'a':
append++;
break;
}
}
if(optind +2 != argc) {
(void)printf("Error: this command expects two filenames (nmon collected data files)\n");
hint();
}
if( (readfp = fopen(FILE1,"r")) == NULL){
perror("failed to open original file for reading");
(void)printf("file: \"%s\"\n",FILE1);
exit(75);
}
if( (writefp = fopen(TEMPFILE,"w+")) == NULL){
perror("failed to open temporary file for write");
(void)printf("file: \"%s\"\n",TEMPFILE);
exit(75);
}
(void)fprintf(writefp,"AAA,note,merged file %s starts here\n",FILE1);
for(i=0;fgets(string,STRLEN,readfp)!= NULL;i++) {
if(!strncmp(string, "ZZZZ,T",6)) {
sscanf(&string[6],"%d",&lastzzzz);
}
fprintf(writefp,"%s",string);
}
if(verbose)(void)printf("First file has %d snapshots in %d lines\n", lastzzzz,i);
fclose(readfp);
if(lastzzzz == 0) {
(void)printf("File %s does not include any ZZZZ lines! - this can't be an nmon output file = stopping.\n",FILE1);
exit(33);
}
if( (readfp = fopen(FILE2,"r")) == NULL){
perror("failed to open extra data file for reading");
(void)printf("file: \"%s\"\n",FILE2);
exit(75);
}
/* wind forward to first ZZZZ line to skip header lines */
for(i=0;fgets(string,STRLEN,readfp)!= NULL;i++) {
if(!strncmp(string, "ZZZZ,T",6)) {
(void)fprintf(writefp,"AAA,note,merged file %s starts here\n",FILE2);
(void)sscanf( &string[6],"%d",&number);
(void)sprintf(&string[6],"%04d", lastzzzz + number);
string[10] = ',';
(void)fprintf(writefp,"%s",string);
break;
}
}
if(verbose)(void)printf("Skipped %d header lines in second file\n", i);
for(k=0,hit=0;fgets(string,STRLEN,readfp)!= NULL;k++) {
/* 3 for short MEM,Tnnnn and 12 for TOP,1234567,Tnnn */
for(j=3;j<12;j++) {
if(string[j ] == ',' &&
string[j+1] == 'T' &&
isdigit(string[j+2]) ) {
hit++;
/* if(verbose)(void)printf("was=%s",string); */
(void)sscanf( &string[j+2],"%d",&number);
(void)sprintf(&string[j+2],"%04d", lastzzzz + number);
string[j+6] = ',';
(void)fprintf(writefp,"%s",string);
break;
}
}
}
if(verbose)(void)printf("Out of %d lines, converted %d lines, last snapshot was %d\n", i+k,hit, lastzzzz+number);
fclose(readfp);
fclose(writefp);
if(append) {
if( (writefp = fopen(FILE1,"w")) == NULL){
perror("failed to open original file writing");
(void)printf("file: \"%s\"\n",FILE1);
exit(75);
}
if(verbose)(void)printf("Output placed back in %s\n",FILE1);
} else {
writefp = stdout;
}
if( (readfp = fopen(TEMPFILE,"r")) == NULL){
perror("failed to open temporary file for reading");
(void)printf("file: \"%s\"\n",TEMPFILE);
exit(75);
}
for(i=0;fgets(string,STRLEN,readfp)!= NULL;i++) {
if(!strncmp(string, "AAA,snapshots,",14)) {
fprintf(writefp,"AAA,snapshots,%d\n",lastzzzz+number);
}
else
fprintf(writefp,"%s",string);
}
unlink(TEMPFILE);
return 0;
}
The error is pointing to this line: if(optind +2 != argc) { and this script is to be used to merge nmon log files and was taken from here: http://nmon.sourceforge.net/pmwiki.php?n=Site.Nmonmerge
I have no prior C programming knowledge so not sure where to start, nor the error is descriptive enough to give me any clues.
Full error with warnings:
error: 'optind' undeclared (first use in this function); did you mean 'append'?|
note: each undeclared identifier is reported only once for each function it appears in|
warning: implicit declaration of function 'isdigit' [-Wimplicit-function-declaration]|

optind should be defined in unistd.h. Since you use getopt(), you need this variable to keep track of the parameter that is currently being processed.
The variable optind is the index of the next element to be processed in argv. The system initializes this value to 1. The caller can reset it to 1 to restart scanning of the same argv, or when scanning a new argument vector.
https://linux.die.net/man/3/optind
Verify that required include files are being included. You are compiling on Linux, so you can simply remove #ifdef LINUX and the corresponding #endif.
You can also open unistd.h that comes with your compiler to see if it defines optind.

Related

How do I make the file pointer point at the very start of the file?

I'm having trouble setting the file pointer to the very start of a file to write some stuff at first AFTER having already written some text in it.
I've tried rewind(), fseek(), opening the file in "r+" & "a+" modes, nothing seems to work.
Here's a small recreation of the program:
#include<stdio.h>
#include<stdlib.h>
void master_globalprint(int lim)
{
int i = 0;
FILE* maspass;
errno_t err;
err = fopen_s(&maspass, "Master_Password.txt", "r+");
if (err != 0)
{
printf("Error opening Master_Password.txt");
exit(0);
}
rewind(maspass);
printf("Pointing to %ld", ftell(maspass));
while (i < lim)
{
fprintf(maspass, "%d", i); //Writing the array infront of the encrypted code
i++;
}
fclose(maspass);
}
void master_create() //To Create a Master Password
{
int count = 0;
char pass;
FILE* maspass;
errno_t err;
err = fopen_s(&maspass, "Master_Password.txt", "a");
if (err != 0)
{
printf("Error creating Master_Password.txt");
exit(0);
}
printf(" Enter Master Password : ");
while ((pass = getchar()) != EOF && pass != '\n')
{
count++;
fprintf(maspass, "%c", pass); //The characters are then printed one by one
}
if (count == 0)
{
remove("Master_Password.txt");
printf("Master Password cannot be empty");
exit(0);
}
fprintf(maspass, "%c", (count + 33)); //To put the amount of letters into file, forwarded by 33 to reach a certain ASCII threshold and converted to char
fprintf(maspass, "\n");
fclose(maspass);
master_globalprint(count);
}
void main()
{
master_create();
}
The above functions work and print the correct values except the master_globalprint function starts printing exactly where the last function left off.
Is it because I've to use command line arguments to achieve the task? If so, can I set the command line arguments to be executed by default somehow so that if the code is distributed, the user won't have to bother?
EDIT : Added in a reproducible code sample. When I put "a" in line 31, it prints only the stuff I input and not the numbers in master_globalprint(). If I put "w", it ONLY prints the numbers in master_globalprint() and not the stuff I input.
Here the writing mode should be w+:
err = fopen_s(&maspass, "Master_Password.txt", "a" /* w+ */);
Here you should close the file and then remove it:
if (count == 0)
{
/*fclose_s(maspass);*/
remove("Master_Password.txt");
printf("Master Password cannot be empty");
exit(0);
}
Instead of doing this, you should keep the file descriptor open and pass it to master_globalprint:
fclose(maspass);
master_globalprint(count);
/* master_globalprint(count, maspass);
* fclose(maspass); */
Then keep reusing the open file descriptor.

Printing line by line from alternate files into a third file in c

For an assignment I have to input text from 2 files line by line into a 3rd file. So file 1 line 1 would be file 3 line 1 and file 2 line would would be file 3 line 2. I have attempted to this but can not seem to get the lines from each file to alternate. I am only able to get lines from each file separately. Please help with any suggestions.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, char *argv[])
{
FILE *file1, *file2, *file3;
char line [1000]; /* or other suitable maximum line size */
// check to make sure that all the file names are entered
if (argc != 4) {
perror("Error: ");
printf("Not enough files were entered!\n");
exit(0);
}
file1 = fopen(argv[1],"r");;
file2 = fopen(argv[2],"r");
file3 = fopen(argv[3],"w");
// check whether the file has been opened successfully
if (file1 == NULL)
{
perror("Error: ");
printf("Cannot open file1 %s!\n", argv[1]);
exit(-1);
}
// check whether the file has been opened successfully
if (file2 == NULL)
{
perror("Error: ");
printf("Cannot open file2 %s!\n", argv[2]);
exit(0);
}
// check whether the file has been opened successfully
if (file3 == NULL)
{
perror("Error: ");
printf("Cannot open file3 %s!\n", argv[3]);
exit(0);
}
int count = 0;
while (1)
{
if(fgets(line, sizeof line, file1) != NULL)
{
count+=1;
fprintf(file3, line);
}
else
{
break;
}
if(fgets(line, sizeof line, file2) != NULL)
{
count++;
fprintf(file3, line);
}
else
{
break;
}
}
fclose (file1);
fclose (file2);
fclose (file3);
}
fprintf(FILE *, const char *format, ...) expects a format as the 2nd argument.
Using fprintf(file3, line); will invoke undefined behavior (UB) should line contain a '%' or at least a missing % if "%%" was encountered.
Use fputs()
// fprintf(file3, line);
fputs(line, file3);
Additional concerns for advanced coding:
If the source file contains a null character, using fgets() is insufficient as it does not report the length read. Other approaches include using fgetc(), fread() or non-standard C getline().
If an input file does not end with a '\n', that rump line may look like a pre-fix to the line read from the other file.
As OP has noted, line length's of about 1000+ are a problem.
Source files line-endings, should they not match the code's understanding of line-ending can cause issues.

debug with no errors or warnings

The following code compiles with no error or warnings, I can also execute the program and it will act as expected in that it will return the error messages at locations it is expected, for example, providing arguments to non-existent files. This lets me know the code is working as far as line 28 (close of the !fpc section)
Meaning there must be an issue from the
register int ch, i;
Down to
return (1);
before
printf("\"%s\"\n",line);\
The program is expected to take command line arguments of the program name itself and two file names, it then opens both of these files, and should then copy strings from the first file up to a max length to the second file while adding " to both the start and end of the string in the new file.
The code I have is
fgetline.c
#include "fgetline.h"
int main(int argc, char *argv[]) {
if (argc != 3) {
printf("usage: enquote filetocopy filetowrite \n");
exit(1);
}
fp = fopen(argv[1], "r");
if (!fp) {
printf("Couldn't open copy file: (%d) %s\n", errno, strerror(errno));
return -1;
}
fpc = fopen(argv[2], "r+");
if (!fpc) {
printf("Couldn't open write file: (%d) %s\n", errno, strerror(errno));
return -1;
}
register int ch, i;
ch = getc(fp);
if (ch == EOF)
return -1;
i = 0;
while (ch != '\n' && ch != EOF && i < max) {
line[i++] = ch;
ch = getc(fp);
}
line[i] = '\0';
while (ch != '\n' && ch != EOF) {
ch = getc(fp);
i++;
}
return(i);
printf("\"%s\"\n",line);
fclose(fp);
fclose(fpc);
return 0;
}
fgetline.h
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
int fgetline(FILE *fp, char *line, int max);
FILE *fp, *fpc;
#define max 30
char line[max + 1];
I am compiling with
debian:~/uni/Ass0$ gcc fgetline.c -Wall -o enquote
debian:~/uni/Ass0$ cd /
testing I did was
debian:~/uni/Ass0$ ./enquote
usage: enquote filetocopy filetowrite
debian:~/uni/Ass0$ ./enquote test
usage: enquote filetocopy filetowrite
debian:~/uni/Ass0$ ./enquote test frog
Couldn't open write file: (2) No such file or directory
debian:~/uni/Ass0$ ./enquote monkey frog
Couldn't open copy file: (2) No such file or directory
debian:~/uni/Ass0$ cat test
ting
test
123
tim#debian:~/uni/Ass0$ cat test2
tim#debian:~/uni/Ass0$ ./enquote test test2
tim#debian:~/uni/Ass0$ cat test2
expected result would be when I run ./enquote test test2, would copy
ting
test
123
from test to test2 so it would appear like
"ting"
"test"
"123"
Thanks, not sure how much more info to give.
There are many issues with your code, compiling with all warnings enabled would have spotted some of them:
Declaring global variables in a header file is good practice, but not defining them there. The extern keyword is used for declarations. The definitions belong in the C file. In this case, variables such as fp, fp1, line should be defined as local variables, not global variables.
Output file argv[2] should be open with "w" mode, "r+" is used for updated mode and will fail if the file does not exist. Update mode is very tricky and confusing, avoid using it.
Do not use the register keyword, it is obsolete now as compilers are smart enough to determine how to best use registers.
Your while loops will read just 2 lines from the input file, storing the first into the line array and discarding the second one.
The return (i); statement exits the program, no output is performed, the remaining statements in the function are ignored completely (-Wall might have spotted this error).
You can simplify the problem by considering this: You want to output a " at the beginning of each line and before the '\n' at the end of each line. You do not need to buffer the line in memory, which would impose a limit on line length. Just output the " whenever you start a line and before you end one:
#include <errno.h>
#include <stdio.h>
#include <string.h>
int main(int argc, char *argv[]) {
FILE *fp, *fpc;
int ch, last;
if (argc != 3) {
printf("usage: enquote filetocopy filetowrite\n");
exit(1);
}
fp = fopen(argv[1], "r");
if (!fp) {
fprintf(stderr, "Could not open input file: (%d) %s\n",
errno, strerror(errno));
return 2;
}
fpc = fopen(argv[2], "w");
if (!fpc) {
fprintf(stderr, "Could not open output file: (%d) %s\n",
errno, strerror(errno));
return 2;
}
last = '\n'; // we are at the beginning of a line
while ((ch = fgetc(fp)) != EOF) {
if (last == '\n') {
fputc('"', fpc); // " at the beginning of a line
}
if (ch == '\n') {
fputc('"', fpc); // " at the end of a line
}
fputc(ch, fpc);
last = ch;
}
if (last != '\n') {
// special case: file does not end with a \n
fputc('"', fpc); // " at the end of a line
fputc('\n', fpc); // put a \n at the end of the output file
}
fclose(fp);
fclose(fpc);
return 0;
}

How do I remove SEGFAULT here?

I created a function to print the contents of a file:
void readFile(char* filename)
{
int c ;
file = fopen(filename, "r");
printf("The contents of the file are:\n");
while((c = fgetc(file)) != EOF)
{
printf("%c", c);
}
return;
}
where file is a global variable. GDB gives output as follows:
_IO_getc (fp=0x0) at getc.c:39
39 getc.c: No such file or directory.
(gdb) bt
#0 _IO_getc (fp=0x0) at getc.c:39
#1 0x000000000040075e in readFile ()
#2 0x00000000004006d4 in main ()
However, the file is present and I get the SEGFAULT after printing the contents of the file. It might be because the buffer here (c) is small but I am not sure. Also, I don't know how do I fix this even if that were the case. Can anyone suggest how do I proceed?
EDIT
I call the readFile function only once. Here is my calling function:
int main(int argc, char* argv[])
{
char * filename;
filename = argv[1];
readFile(filename);
printf("File Handler: %ld", (long)file);
fclose(file);
return 0;
}
You're passing in a filename that doesn't exist or for some other reason cannot be opened. Get rid of the segfault by checking for errors (you'll need to #include <errno.h> and <string.h> too for this:
void readFile(char* filename)
{
int c ;
file = fopen(filename, "r");
if (file == NULL) {
printf("Cannot open file '%s' : %s\n", filename, strerror(errno));
return;
}
printf("The contents of the file are:\n");
while((c = fgetc(file)) != EOF)
{
printf("%c", c);
}
return;
}
Most likely your file is NULL and you are still trying to read it.
I simulated this behaviour (SEG fault) when I deleted this file.
If file exists then your code works fine.
Check what path you are passing.. If you are using single \ try with \\ and see if this works. First \ will work as escape sequence and final path will be send as D:\temp\use.dat to fopen.
readFile("D:\\temp\\user.dat");
Before you do anything with a file, you must ensure that you opened it successfully. This is done by checking that the file pointer received by calling fopen is not NULL.
Once you do this, you read using whatever function you choose until it returns a value that indicates failure to read — a NULL pointer for fgets, 0 or EOF for fscanf, or EOF for fgetc.
In any case, you challenge these return values in two ways. The first way is to check for read errors using ferror. The other way is to check whether the end of the file was reached using feof.
A complete program that should work, based upon your code:
#include <stdio.h>
#include <errno.h>
#include <stdlib.h>
enum { OPEN_ERROR = 1, READ_ERROR };
enum { PARAM_EXIT = 1, OPEN_EXIT, READ_EXIT };
FILE *file = NULL;
int readFile(char* filename)
{
int c;
file = fopen(filename, "r");
if (file == NULL)
return OPEN_ERROR;
printf("The contents of file '%s' are:\n", filename);
while((c = fgetc(file)) != EOF)
printf("%c", c);
/*
* fgetc returns EOF on end of file and when an error occurs.
* feof is used to determine whether the end of the file was reached.
* Otherwise, we encountered a read error.
*/
if (feof(file))
c = 0;
else
c = READ_ERROR;
return c;
}
int main(int argc, char *argv[])
{
int status = 0;
if (argc == 1) {
fprintf(stderr, "usage: %s file\n", argv[0]);
return PARAM_ERROR;
}
/* Check that <program ""> wasn't used... */
if (argv[1][0] == '\0') {
fprintf(stderr, "error: empty filename detected, exiting. . .\n");
return PARAM_ERROR;
}
switch (readFile(argv[1])) {
case 0:
break;
case OPEN_ERROR:
fprintf(stderr, "error: file open failed - %s\n", strerror(errno));
status = OPEN_EXIT;
break;
case READ_ERROR:
fprintf(stderr, "error: file read failed - %s\n", strerror(errno));
status = READ_EXIT;
break;
default:
fprintf(stderr, "error: unknown error occurred, aborting...\n");
abort();
}
if (file != NULL)
fclose(file);
return status;
}
Of course, normally you would close the file in the same function in which it was opened (e.g. something like filep = openFile(...); readFile(filep); fclose(filep);, except error handling would be used of course).
I am completely changing my answer
Actually, the file that I was reading was open in gedit (which might explain why I was getting "NULL" even after printing the file contents. I closed the file and removed my NULL comparison code and it works perfectly fine.
Ok, from everybody's comments I got to know that you basically get a SEGFAULT when you read the contents of file that has NULL contents. I just made a simple fix in my while loop:
while((c != EOF))
{
printf("%c", c);
c = fgetc(file);
if(c == NULL)
break;
}
Problemo solved! (Although, the compiler gives me a warning of "comparison between pointer and integer".)

Why do I mysteriously segfault when writing to file?

I wish I could i could give more information, but I genuinely have no idea what is going on here. This code opens files for appension or overwriting, depending on user arguments (appension by default). It gets as far as the fgets for user input, and then as soon as the input is entered, it segfaults and dumps core. This is strange, because before I implemented arguments (i.e. it was just ./a.out file) it worked fine, so I guess it has something to do with the new stuff about arguments...
#include <stdio.h>
#include <string.h>
int printhelp(void);
int main(int argc, char *argv[])
{
char input[256];
int loopstat = 0;
FILE *inputfile;
if (argc < 2) /* Check argc for minimum 2 arguments (i.e. cw FILE) */
{
printf("ca: missing file operand\n");
return 0;
}
else if (argc > 2) /* Check argc for more than 2 arguments (i.e. cw -o FILE) */
{
if (strncmp(argv[1], "-", 1) == 0) /* if first argument begins with "-", it must be an option, so descend into option checking */
{
if (strcmp(argv[1], "-a") == 0) /* If -a option is given, open for appending */
{
FILE *inputfile = fopen(argv[2], "a");
}
else if (strcmp(argv[1], "-o") == 0) /* If -o option is given, open for overwriting */
{
FILE *inputfile = fopen(argv[2], "w");
}
else if (strcmp(argv[1], "--help") == 0) /* If --help option is given, print help and quit */
{
printhelp();
return 0;
}
else
{
printf("cw: invalid option\n"); /* If invalid option is given, print the fact and quit*/
return 0;
}
}
}
else /* if argc is equal to 2 (i.e. "cw FILE" or "cw -o")...*/
{
if (strncmp(argv[1], "-", 1) == 0) /* Check if user has specified an option but no file (i.e. "cw -o") */
{
printf("cw: missing file operand\n"); /* If they have, print that no file is spec'd and quit */
return 0;
}
else /* If not, it's a legit file with no other arguments (e.g. "cw FILE") so open it in append mode by default */
{
FILE *inputfile = fopen(argv[2], "a");
}
}
/* Writing loop */
printf("Enter input...\n");
while (loopstat == 0) /* Get user input and write to file until they give exit command */
{
fgets(input, 256, stdin); /* Get user input */
if (strcmp(input, ":x\n") == 0) /* If input == exit command, quit */
{
printf("co: exit received, terminating...\n");
loopstat++;
}
else /* Write to file */
{
fprintf(inputfile, "%s", input);
}
}
fclose(inputfile);
}
int printhelp(void) /* Print help on --help command */
{
printf(
"Usage: ca FILE\nContinuously append input to the FILE\nca does not currently support multiple file appension.\nReport bugs to scamp#lavabit.com\n");
return 0;
}
P.S. sorry if I messed up the indentation, it's really confusing to have to add four spaces before everything in this much code.
Here you are shadowing your variable:
else /* If not, it's a legit file with no other arguments (e.g. "cw FILE") so open it in append mode by default */
{
FILE *inputfile = fopen(argv[2], "a");
}
should be
else /* If not, it's a legit file with no other arguments (e.g. "cw FILE") so open it in append mode by default */
{
inputfile = fopen(argv[2], "a");
}
You have several instances like this, so remove the declaration there as well.
You are declaring the identifier inputfile several times, but it won't be the same object at each time.
See the behavior of this program for instance (from Wikipedia):
#include <stdio.h>
int main(void)
{
char x = 'm';
printf("%c\n", x);
{
printf("%c\n", x);
char x = 'b';
printf("%c\n", x);
}
printf("%c\n", x);
}
You have to declare inputfile just once, and then assign it in if statements.
FILE *inputfile;
if (/* ... */)
inputfile = /* ... */
else if (/* ... */)
inputfile = /* ... */
else
inputfile = /* ... */
int main(int argc, char *argv[])
{
char input[256];
int loopstat = 0;
FILE *inputfile;
then you have:
if (strcmp(argv[1], "-a") == 0)
{
FILE *inputfile = fopen(argv[2], "a");
}
You should not redeclare a new object inputfile but reuse your inputfile declared at the top of your function.
Example:
inputfile = fopen(argv[2], "a");
The problem is there:
FILE *inputfile;
....
if (strcmp(argv[1], "-a") == 0)
{
FILE *inputfile = fopen(argv[2], "a");
}
By writing this way you are hiding the variable inputfile from the compiler. Thus the variable defined in the beginning stays uninitialized.
You should write it following way:
if (strcmp(argv[1], "-a") == 0)
{
inputfile = fopen(argv[2], "a");
}
So now you will use the variable defined in the top of the function.
You should read about the variable scope.

Resources