Reading numbers and characters from a file - c

I'm having some trouble with in files.
I'm attempting to read in numbers and special characters from a file. I'm given a file that contains numbers and operands. The file is read in from the command line.
Sample file:
1 4 + 5*
2 - 4 + 8
7 -2 +1 +3
0
So the file is terminated with 0 and each new line is an expression. What my code is attempting to do is read in one expression at a time
1 4 + 5 *
Work with it, then move on to the next expression (until the file reads 0). It need to contain the special characters as well (+, *, -, ect)
This is my code so far. I don't know the length of each expression (it can vary) so I just statically declared it as a length of 50.
int main(int argc, char* argv[]){
FILE* input;
char expression[50];
int i;
char ch;
input = fopen(argv[1], "r");
if(input == NULL){
printf("File does not exist! Exiting program!");
return 0;
}
do{
ch= fgetc(input);
if(ch == 0)
break;
while((ch != '\n')){
//printf("test2\n");
expression[i] = ch;
i++;
ch = fgetc(input);
}
//plan to do something with each expression here
} while(ch != EOF);
for(i=0; i < (strlen(expression)); i++)
printf("%c ", expression[i]);
return 0;
}
All I'm trying to do here is just check to see if it will read in the expressions and print them out correctly. When I try to run it I get a segfault, I put in the test2 statement to test and it prints it out(infinite loop) until it seg faults.
Any help would be greatly appreciated.

For your kind of file have:
while((ch=fgetc(input)) != '0' )
{
/* your main processing */
if (ch == '\n')
{
/* deal with end of expression */
}
}
Having multiple while blocks and fgetc(input); is confusing for everyone.

Related

Convert a column in CSV to a string in C

So, I was trying to write a program to take the first column of a CSV file and copy that do a string, but it's not going well. I put the code and the CSV file and I really appreciate any help.
int main () {
FILE *fp;
fp = fopen("filePATH", "r");
char column[80];
int line_n = 0;
char ch;
while ((ch = fgetc(fp)) != EOF) {
fgets(column, sizeof column, fp);
for (int i = 0; i < sizeof column; ++i){
fscanf(fp, "%[^;]", column);
}
printf("%s \n", column);
}
fclose(fp);
return 0;
}
CSV file:
2;51.5;144.0;24.80
5;62.3;157.0;25.30
10;52.8;141.0;26.60
10;34.5;120.0;24.00
1;41.6;131.0;24.20
5;49.0;144.0;23.80
6;47.1;142.0;23.50
2;51.8;144.5;24.80
1;55.6;135.0;30.50
9;51.9;150.0;23.10
9;48.5;139.0;25.10
The output I have is:
5
10
10
1
5
6
2
1
9
9
48.5;139.0;25.10
So, I don't understand why the program shows me the first column but copies only the last line for the string column.
To check the string column, I used:
char copy[20];
strncpy(copy, column, 18);
printf("%s ", copy);
And the output is:
48.5;139.0;25.10
Almost certainly you want to restructure the loops, but here are some minimal changes to your code that might be instructive:
#include<stdio.h>
char sample_input[] =
"2;51.5;144.0;24.80\n"
"5;62.3;157.0;25.30\n"
"10;52.8;141.0;26.60\n"
"10;34.5;120.0;24.00\n"
"1;41.6;131.0;24.20\n"
"5;49.0;144.0;23.80\n"
"6;47.1;142.0;23.50\n"
"2;51.8;144.5;24.80\n"
"1;55.6;135.0;30.50\n"
"9;51.9;150.0;23.10\n"
"9;48.5;139.0;25.10\n"
;
int
main(void)
{
FILE *fp = fmemopen(sample_input, sizeof sample_input, "r");
char column[80];
int line_n = 0;
int ch; /* fgetc returns an int. */
while( (ch = fgetc(fp)) != EOF ){
/* put ch back so it can be read by scanf */
ungetc(ch, fp);
/* This fgets does not seem to serve any purpose.
/* fgets(column, sizeof column, fp); */
ch = ';';
while( ch == ';' && fscanf(fp, "%79[^;\n]", column) == 1 ){
ch = fgetc(fp); /* Consume the ; or \n */
printf("%s%c", column, ch);
}
}
fclose(fp);
return 0;
}
It would probably be better to use the fgets to read each line of data and then use sscanf to parse the line, but I wanted to show that your current code can be made to (mostly) work with minimal changes. Note that the variable used to store the value returned by fgetc must be int rather than char in order to properly compare to EOF. Also, whenever you use %s or %[] in scanf, it is best to add a width modifier to prevent a buffer overflow.

"How to make my program read visible characters and spaces from a file

I am supposed to be "fixing" code given to me to make it display the correct number of visible characters in a file (spaces too). The correct number is supposed to be 977. I have never dealt with files before and I don't understand what I need to do to display the correct number.
* Driver Menu System for Homework
* Andrew Potter - Mar 5, 2019 <-- Please put your name/date here
*/
#include <stdio.h>//header file for input/output -
#include <stdlib.h>
#include <ctype.h>
// since you will place all your assigned functions (programs) in this file, you do not need to include stdio.h again!
int menu(void); //prototype definition section
void hello(void);
void countall(void);
int main(void)
{
int selection = menu();
while(selection != 99) {
switch(selection) {
case 1:
hello();
break;
case 2:
countall();
break;
case 3:
break;
case 4:
break;
default:
printf("Please enter a valid selection.\n");
}
selection = menu();
}
return 0;
}
int menu(void) {
int choice;
printf("***************************\n");
printf(" 1. Hello \n");
printf(" 2. Countall\n");
printf(" 3. \n");
printf(" 4. \n");
printf("99. Exit\n");
printf("Please select number and press enter:\n");
printf("***************************\n");
scanf("%d", &choice);
getchar();
return choice;
}
void hello(void) {
printf("Hello, World!!!\n");
}
//*****Andrew 5/1/19*****
#define SLEN 81 /* from reverse.c */
/* original header: int count(argc, *argv[]) */
void countall(void)
{
int ch; // place to store each character as read
FILE *fp; // "file pointer"
long unsigned count = 0;
char file[SLEN]; /* from reverse.c */
/*Checks whether a file name was included when run from the command prompt
* The argument count includes the program file name. A count of 2 indicates
* that an additional parameter was passed
if (argc != 2)
{
printf("Usage: %s filename\n", argv[0]);
exit(EXIT_FAILURE);
}
* The following uses the second parameter as the file name
* and attempts to open the file
if ((fp = fopen(argv[1], "r")) == NULL)
{
printf("Can't open %s\n", argv[1]);
exit(EXIT_FAILURE);
} */
/*************************************
Code from reverse.c included to make the program work from within our IDE
*************************************/
puts("Enter the name of the file to be processed:");
scanf("%s", file);
if ((fp = fopen(file,"rb")) == NULL) /* read mode */
{
printf("count program can't open %s\n", file);
exit(EXIT_FAILURE);
}
/* EOF reached when C realizes it tried to reach beyond the end of the file! */
/* This is good design - see page 573 */
while ((ch = getc(fp)) != EOF)
{
if (isprint(ch)) {
count++;
}
else if (isprint(ch)) {
count++;
}
putc(ch,stdout); // same as putchar(ch);
count++;
}
fclose(fp);
printf("\nFile %s has %lu characters\n", file, count);
}
I expected I would get the correct number of visible characters using the combination of isprint and isspace but I usually get 2086.
The assignment directions are: "Word identifies 977 characters including spaces. Your current countall() believes there are 1043. Make the corrections necessary to your code to count only the visible characters and spaces! (Hint: check out 567 in your textbook.)" Before I edited any code the count was 1043, now i am getting 2020. I need 977.
isprint() returns a Boolean result - zero if the character is not "printable", and non-zero if it is. As such isprint(ch) != '\n'makes no sense. Your complete expression in the question makes even less sense, but I'll come on to that at the end.
isprint() on its own returns true (non-zero) for all printable characters, so you need no other tests. Moreover you increment count unconditionally and in every conditional block, so you are counting every character and some twice.
You just need:
if( isprint(ch) )
{
count++;
}
putc( ch, stdout ) ;
While your code is clearly an incomplete fragment, it is not clear where or how your are reading ch. You need a getc() or equivalent in there somewhare.
while( (ch = getc(fp)) != EOF )
{
if( isprint(ch) )
{
count++;
}
putc( ch, stdout ) ;
}
It is not clear whether you need to count all whitespace (including space, tab and newline) or just "spaces" as you stated. If so be clear that isprint() will match space, but not control characters newline or tab. isspace() matches all these, but should not be counted separately to isprint() because 'space' is in both white-space and printable sets. If newline and tab are to be counted (and less likely; "vertical tab") then:
while( (ch = getc(fp)) != EOF )
{
if( isprint(ch) || isspace(ch) )
{
count++;
}
putc( ch, stdout ) ;
}
Another aspect of C that you seem to misunderstand is how Boolean expressions work. To test a single variable for multiple values you must write:
if( var == x || var == y || var == z )
You have written:
if( var == x || y || z )
which may make sense in English (or other natural language) when you read it out aloud, but in C it means:
if( var == (x || y || z ) )
evaluating (x || y || z ) as either true or false and comparing it to var.
It is probably worth considering the semantics of your existing solution to show why it actually compiles, but produces the erroneous result it does.
Firstly,
isprint(ch) != '\n' || '\t' || '\0'
is equivalent to isprint(ch) != true, for the reasons described earlier. So you increment the counter for all characters that are not printable.
Then here:
isspace(ch) == NULL
NULL is a macro representing an invalid pointer, and isspace() does not return a pointer. However NULL will implicitly cast to zero (or false). So here you increment the counter for all printable characters that are not spaces.
Finally, you unconditionally count every character here:
putc(ch,stdout); // same as putchar(ch);
count++;
So your result will be:
number-of-non-printing-characters +
number-of-printing-characters - number-of-spaces +
total-number-of-characters
which is I think (2 x file-length) - number-of-spaces
Finally note that if you open a text file that has CR+LF line ends (conventional for text files on Windows) in "binary" mode, isspace() will count two characters for every new-line. Be sure to open in "text" mode (regardless of the platform).
From isprint():
A printable character is a character that occupies a printing position on a display (this is the opposite of a control character, checked with iscntrl).
and
A value different from zero (i.e., true) if indeed c is a printable character. Zero (i.e., false) otherwise.
So that function should be sufficient. Please note that you have to make sure to feed all these is...() functions from <ctype.h> unsigned values. So if you use it with a value of uncertain origin, better cast to char unsigned.
#include <stdlib.h>
#include <stdio.h>
#include <ctype.h>
int main(void)
{
char const *filename = "test.txt";
FILE *input = fopen(filename, "r");
if (!input) {
fprintf(stderr, "Couldn't open \"%s\" for reading. :(\n\n", filename);
return EXIT_FAILURE;
}
long long unsigned count = 0;
for (int ch; (ch = fgetc(input)) != EOF;) {
if (isprint(ch))
++count;
}
fclose(input);
printf("Count: %llu\n\n", count);
}
If I wasn't lucky enough to guess which characters you want to be counted, have a look at ctype.h, there is a table.
if ((ch == '\t') || isprint(ch))
count++;
If you want to handle tabs differently (maybe to count how many spaces they use):
if (ch == '\t') {
/* Do smth */
} else if (isprint(ch)) {
count++;
}
This should be enough.

C Reading a file of digits separated by commas

I am trying to read in a file that contains digits operated by commas and store them in an array without the commas present.
For example: processes.txt contains
0,1,3
1,0,5
2,9,8
3,10,6
And an array called numbers should look like:
0 1 3 1 0 5 2 9 8 3 10 6
The code I had so far is:
FILE *fp1;
char c; //declaration of characters
fp1=fopen(argv[1],"r"); //opening the file
int list[300];
c=fgetc(fp1); //taking character from fp1 pointer or file
int i=0,number,num=0;
while(c!=EOF){ //iterate until end of file
if (isdigit(c)){ //if it is digit
sscanf(&c,"%d",&number); //changing character to number (c)
num=(num*10)+number;
}
else if (c==',' || c=='\n') { //if it is new line or ,then it will store the number in list
list[i]=num;
num=0;
i++;
}
c=fgetc(fp1);
}
But this is having problems if it is a double digit. Does anyone have a better solution? Thank you!
For the data shown with no space before the commas, you could simply use:
while (fscanf(fp1, "%d,", &num) == 1 && i < 300)
list[i++] = num;
This will read the comma after the number if there is one, silently ignoring when there isn't one. If there might be white space before the commas in the data, add a blank before the comma in the format string. The test on i prevents you writing outside the bounds of the list array. The ++ operator comes into its own here.
First, fgetc returns an int, so c needs to be an int.
Other than that, I would use a slightly different approach. I admit that it is slightly overcomplicated. However, this approach may be usable if you have several different types of fields that requires different actions, like a parser. For your specific problem, I recommend Johathan Leffler's answer.
int c=fgetc(f);
while(c!=EOF && i<300) {
if(isdigit(c)) {
fseek(f, -1, SEEK_CUR);
if(fscanf(f, "%d", &list[i++]) != 1) {
// Handle error
}
}
c=fgetc(f);
}
Here I don't care about commas and newlines. I take ANYTHING other than a digit as a separator. What I do is basically this:
read next byte
if byte is digit:
back one byte in the file
read number, irregardless of length
else continue
The added condition i<300 is for security reasons. If you really want to check that nothing else than commas and newlines (I did not get the impression that you found that important) you could easily just add an else if (c == ... to handle the error.
Note that you should always check the return value for functions like sscanf, fscanf, scanf etc. Actually, you should also do that for fseek. In this situation it's not as important since this code is very unlikely to fail for that reason, so I left it out for readability. But in production code you SHOULD check it.
My solution is to read the whole line first and then parse it with strtok_r with comma as a delimiter. If you want portable code you should use strtok instead.
A naive implementation of readline would be something like this:
static char *readline(FILE *file)
{
char *line = malloc(sizeof(char));
int index = 0;
int c = fgetc(file);
if (c == EOF) {
free(line);
return NULL;
}
while (c != EOF && c != '\n') {
line[index++] = c;
char *l = realloc(line, (index + 1) * sizeof(char));
if (l == NULL) {
free(line);
return NULL;
}
line = l;
c = fgetc(file);
}
line[index] = '\0';
return line;
}
Then you just need to parse the whole line with strtok_r, so you would end with something like this:
int main(int argc, char **argv)
{
FILE *file = fopen(argv[1], "re");
int list[300];
if (file == NULL) {
return 1;
}
char *line;
int numc = 0;
while((line = readline(file)) != NULL) {
char *saveptr;
// Get the first token
char *tok = strtok_r(line, ",", &saveptr);
// Now start parsing the whole line
while (tok != NULL) {
// Convert the token to a long if possible
long num = strtol(tok, NULL, 0);
if (errno != 0) {
// Handle no value conversion
// ...
// ...
}
list[numc++] = (int) num;
// Get next token
tok = strtok_r(NULL, ",", &saveptr);
}
free(line);
}
fclose(file);
return 0;
}
And for printing the whole list just use a for loop:
for (int i = 0; i < numc; i++) {
printf("%d ", list[i]);
}
printf("\n");

Removing punctuation and capitalizing in C

I'm writing a program for school that asks to read text from a file, capitalizes everything, and removes the punctuation and spaces. The file "Congress.txt" contains
(Congress shall make no law respecting an establishment of religion, or prohibiting the free exercise thereof; or abridging the freedom of speech, or of the press; or the right of the people peaceably to assemble, and to petition the government for a redress of grievances.)
It reads in correctly but what I have so far to remove the punctuation, spaces, and capitalize causes some major problems with junk characters. My code so far is:
void processFile(char line[]) {
FILE *fp;
int i = 0;
char c;
if (!(fp = fopen("congress.txt", "r"))) {
printf("File could not be opened for input.\n");
exit(1);
}
line[i] = '\0';
fseek(fp, 0, SEEK_END);
fseek(fp, 0, SEEK_SET);
for (i = 0; i < MAX; ++i) {
fscanf(fp, "%c", &line[i]);
if (line[i] == ' ')
i++;
else if (ispunct((unsigned char)line[i]))
i++;
else if (islower((unsigned char)line[i])) {
line[i] = toupper((unsigned char)line[i]);
i++;
}
printf("%c", line[i]);
fprintf(csis, "%c", line[i]);
}
fclose(fp);
}
I don't know if it's an issue but I have MAX defined as 272 because that's what the text file is including punctuation and spaces.
My output I am getting is:
C╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠
╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠Press any key to continue . . .
The fundamental algorithm needs to be along the lines of:
while next character is not EOF
if it is alphabetic
save the upper case version of it in the string
null terminate the string
which translates into C as:
int c;
int i = 0;
while ((c = getc(fp)) != EOF)
{
if (isalpha(c))
line[i++] = toupper(c);
}
line[i] = '\0';
This code doesn't need the (unsigned char) cast with the functions from <ctype.h> because c is guaranteed to contain either EOF (in which case it doesn't get into the body of the loop) or the value of a character converted to unsigned char anyway. You only have to worry about the cast when you use char c (as in the code in the question) and try to write toupper(c) or isalpha(c). The problem is that plain char can be a signed type, so some characters, notoriously ÿ (y-umlaut, U+00FF, LATIN SMALL LETTER Y WITH DIAERESIS), will appear as a negative value, and that breaks the requirements on the inputs to the <ctype.h> functions. This code will attempt to case-convert characters that are already upper-case, but that's probably cheaper than a second test.
What else you do in the way of printing, etc is up to you. The csis file stream is a global scope variable; that's a bit (tr)icky. You should probably terminate the output printing with a newline.
The code shown is vulnerable to buffer overflow. If the length of line is MAX, then you can modify the loop condition to:
while (i < MAX - 1 && (c = getc(fp)) != EOF)
If, as would be a better design, you change the function signature to:
void processFile(int size, char line[]) {
and assert that the size is strictly positive:
assert(size > 0);
and then the loop condition changes to:
while (i < size - 1 && (c = getc(fp)) != EOF)
Obviously, you change the call too:
char line[4096];
processFile(sizeof(line), line);
in the posted code, there is no intermediate processing,
so the following code ignores the 'line[]' input parameter
void processFile()
{
FILE *fp = NULL;
if (!(fp = fopen("congress.txt", "r")))
{
printf("File could not be opened for input.\n");
exit(1);
}
// implied else, fopen successful
unsigned int c; // must be integer so EOF (-1) can be recognized
while( EOF != (c =(unsigned)fgetc(fp) ) )
{
if( (isalpha(c) || isblank(c) ) && !ispunct(c) ) // a...z or A...Z or space
{
// note toupper has no effect on upper case characters
// note toupper has no effect on a space
printf("%c", toupper(c));
fprintf(csis, "%c", toupper(c));
}
}
printf( "\n" );
fclose(fp);
} // end function: processFile
Okay so what I did was created a second character array. My first array read in the entire file. I created a second array which would only take in alphabetical characters from the first array then make them uppercase. My correct and completed function for that part of my homework is as follows:
void processFile(char line[], char newline[]) {
FILE *fp;
int i = 0;
int j = 0;
if (!(fp = fopen("congress.txt", "r"))) { //checks file open
printf("File could not be opened for input.\n");
exit(1);
}
line[i] = '\0';
fseek(fp, 0, SEEK_END); //idk what they do but they make it not crash
fseek(fp, 0, SEEK_SET);
for (i = 0; i < MAX; ++i) { //reads the file into the first array
fscanf(fp, "%c", &line[i]);
}
for (i = 0; i < MAX; ++i) {
if (isalpha(line[i])){ //if it's an alphabetical character
newline[j] = line[i]; //read into new array
newline[j] = toupper(newline[j]); //makes that letter capitalized
j++;
}
}
fclose(fp);
}
Just make sure that after creating the new array, it will be smaller than your defined MAX. To make it easy I just counted the now missing punctuation and spaces (which was 50) so for future "for" loops it was:
for (i = 0; i < MAX - 50; ++i)

How to fix 'Segmentation Fault(core dumped)' error when reading characters from two input files?

I am in the process of writing an encryption program but have come to a halt because of the error: 'Segmentation Fault(Core Dumped)'. The below program is suppose to print from two input files:
The first input file: should be read in and then change the upper case characters to lower case characters and lower case characters to upper case characters.
The second input file: should be read in and just print the number of times the user desired character appears in the file. In this case the user desired character I want is the letter 'a'.
Let's say for example the first input file(input.txt) contains:
Hello My Name is Joe
This should print as: hELLO mY nAME IS jOE
Let's say for example the second input file(keys.txt) contains:
A
M
This should just print the character: A
NOTE This doesn't necessarily encrypt the input file yet however, i'm trying to get familiar with using more than one input file at once. I can use all the help I can get! THANK YOU!
ALSO, when compiling, the code should look like this:
gcc myProgram.c
./a.out e input.txt keys.txt
(The above 'e' just stands for encryption.)
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
int main(int args, char *argc[]){
int i,c,x,len,len2;
char str[1024];
char str2[500];
FILE *finp;
FILE *keyFile;
/* ****** CODE TO ENCRYPT STARTS HERE ****** */
if((argc[1]="e")&&((finp = fopen(argc[2],"r"))==NULL)
&&((keyFile=fopen(argc[3],"r"))==NULL)){
printf("Could Not Open file %s\n", argc[2]);
exit(1);
}//End First IF statement
/* *** START CODE TO GRAB FROM 1st INPUT FILE: input.txt *** */
/*Grab strings from first input file and change lower case to upper case and
upper to lower case*/
while(fgets(str,1024,finp)!=NULL){
len = strlen(str);
for(i>0;i<len;++i){
if(((str[i]>=64)&&(str[i]<=90))||((str[i]>=97&&(str[i]<=122))))
str[i]^=32;}}
/* *** END OF CODE FOR 1st INPUT FILE **** */
/* *** START CODE TO GRAB FROM 2nd INPUT FILE: keys.txt **** */
/*Grab character from second input file and print the character*/
while(fgets(str2,500,keyFile)!=NULL){
len2 = strlen(str2);
for(x>0;x<len2;++x){
if(str2[x]=='A'){
putchar(str2[x]);
}}
/* ***** END CODE FOR 2nd INPUT FILE*** */
}
printf("%s\n",str);
fclose(finp);
return 0;}
I think the main problem in your code is that you have not initialized i and x before using them.
Replace the line
for(i>0;i<len;++i){
with
for(i=0;i<len;++i){
// ^^^ i = 0; not i > 0;
and replace the line
for(x>0;x<len2;++x){
with
for(x=0;x<len2;++x){
// ^^^ x = 0; not x > 0;
You can clean up the code at the start of the function. The logic used in
if((argc[1]="e")&&((finp = fopen(argc[2],"r"))==NULL)
&&((keyFile=fopen(argc[3],"r"))==NULL)){
printf("Could Not Open file %s\n", argc[2]);
exit(1);
}//End First IF statement
is wrong on many accounts. Replace that with more readable code:
if ( strcmp(argv[1], "e") == 0 )
{
if ( (finp = fopen(argc[2],"r")) == NULL )
{
printf("Could Not Open file %s\n", argc[2]);
exit(1);
}
if ( (keyFile = fopen(argc[3],"r")) == NULL )
{
printf("Could Not Open file %s\n", argc[3]);
exit(1);
}
}
else
{
// Decide what you want to do when the first argument is not "e".
}
in your code
(argc[1]="e")
should be
!strcmp(argv[1], "e")
Same kind of mistake for argc[2] and argc[3].
Remember, argc is of type int (not array). argv[] is of type char *.
That said, you should always check for the argc value against n befire making use of argv[n-1].
Then, please keep in mind, the second operand of && is evaluated only if the first operand yields a TRUE value. You shoule check the logic you're using in
if((argc[1]="e")&&((finp = fopen(argc[2],"r"))==NULL)
&&((keyFile=fopen(argc[3],"r"))==NULL))
I don't think it serves the purpose you want it to serve.
Also, as pointed out by Mr. #iharob, you never seem to initialize the counter variables used in either of your for loops. This will lead to undefined behavior.
You have many many errors
The first if statement, is completely wrong
The argc[1] = "e", is wrong from many points of view, first you cant compre strings with the == operator, but you didn't use the comparison operator, it's the assignment operator and you can't assign to arrays, so it's twofold wrong.
You used the && operator to check if both files where NULL at the same time, which would be false if only one of them is, making the code that follows invoke undefined behavior, possibly causing the SEGMENTATION FAULT.
You never check if the program was invoked with the correct number of arguments, but you still access the argc array, which by the way is normally argv, argc is used for the number of parameters i.e. where you used args, but that doesn't actually matter.
Your for loops are also wrong
for (i > 0 ... )
you never initialize the i, also a little bit of knowledge of how strings work in c, would make a c programmer to write the following loop to traverse the string
for (i = 0 ; ((str[i] != '\n') && (str[i] != '\0')) ; ++i)
since fgets() will read the trailing '\n' inserted by pressing the Return/Enter key and thus flushing standard input, you need to check against str[i] == '\n' but if you are paranoid you should also check for '\0' I am paranoid and I do check although that is ineficient, I prefer to do it instead of seeing unexpected things later.
Here is a sample of your program without the mistakes, I don't know if it does what you want but it's the same program just with errors that could lead to SEGMENTATION FAULT corrected
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
int main(int argc, char *argb[])
{
int i;
char str[1024];
char str2[500];
FILE *inputFile;
FILE *keyFile;
if (argc < 3) /* insufficient number of parameters provided */
return -1;
if (argb[1][0] == 'e')
return 0;
inputFile = fopen(argb[2], "r");
if (inputFile == NULL)
{
printf("Could Not Open file %s\n", argb[2]);
return -1;
}
keyFile = fopen(argb[3], "r");
if (keyFile == NULL)
{
printf("Could Not Open file %s\n", argb[2]);
fclose(inputFile);
return -1;
}
while (fgets(str, sizeof(str), inputFile) != NULL)
{
for (i = 0 ; ((str[i] != '\n') && (str[i] != '\0')) ; ++i)
{
if (((str[i] >= 64) && (str[i] <= 90)) || ((str[i] >= 97) && (str[i]<=122)))
str[i] ^= 32;
}
}
while (fgets(str2, sizeof(str2), keyFile) != NULL)
{
for (i = 0 ; ((str2[i] != '\n') && (str2[i] != '\0')) ; ++i)
{
if (str2[i] == 'A')
putchar(str2[i]);
}
}
printf("%s\n", str);
fclose(inputFile);
return 0;
}

Resources