-1

I'm pretty new to C and I'm having difficulty with a few different concepts, including pointers, arrays, and reading files. Here is my program I've started, I'm sure their are a few errors, could you show me what I'm doing wrong? The program is supposed to read the letters from congress.txt and store them as capital letters without spaces, I also tried to make a little test which will print the letters for me so I can see if the characters in the array store are correct. I've heard that I shouldn't test against != EOF here before but my teacher has used that and I don't want to simply copy something I don't understand.

This is what is in congress.txt:

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.

#include<stdio.h>

int processFile(int *store);
int cipher(int *store, int *code);

int main(void){
    int store[300], code[300], i;

    processFile(store);
    for (i = 0; store[i] != 0; ++i){    //does a print test of store so I can see      if the txt was stored properly
        printf("%c", store[i]);
    }
    getchar();
    return;
}

int processFile(int *store){
    int i, a = 0;
    FILE *f = fopen("congress.txt", "r");

    for (i = 0; a != EOF;){
        fscanf(f, "%c", &a);        //store character in a
        if (a <= 'Z' && a >= 'A'){  //store capital letters
            store[i] = a;
            i++;
        }
        if (a <= 'z' && a >= 'a'){  //store lower case letters as capital
            store[i] = a - 32;
            i++;
        }
    }
}
joce
  • 9,624
  • 19
  • 56
  • 74
ShaneBird
  • 187
  • 9
  • 1
    Read more about the "EOF anti-pattern" here: http://stackoverflow.com/questions/5431941 and http://drpaulcarter.com/cs/common-c-errors.php#4.2 Your use is slightly different than usual, but the key point is that `fscanf()` can return `EOF`, and when it does, `a`'s value is unchanged (`fscanf()` actually will do nothing to `a` when it hits `EOF` - it won't write `EOF` into `a`). – Michael Burr Apr 24 '14 at 02:22
  • 3
    `fscanf` will never set `a` to `EOF`. And `fscanf` is overkill for reading a single character. Just use `getchar()`, and assign the result to an `int`, not a `char`, so you can detect `EOF`. Don't use magic numbers; see `isupper` and `islower` in `` (and be sure to cast the argument to `unsigned char`). – Keith Thompson Apr 24 '14 at 02:27
  • ok so basically the loop never ends then? – ShaneBird Apr 24 '14 at 02:27
  • how can I make getchar() read values from my file? – ShaneBird Apr 24 '14 at 02:30
  • 1
    short version: `EOF` is not a character, it's a special value used to signal that a read operation failed (depending on the actual read function used, sometimes it means actually that end of file occurred; sometimes it means that any error occurred). Check the documentation for whichever read function you are calling (`fscanf` in this case) to see what it does in case of errors. – M.M Apr 24 '14 at 02:31

3 Answers3

2

This line:

fscanf(f, "%c", a);

should be:

fscanf(f, "%c", &a);
chrk
  • 4,037
  • 2
  • 39
  • 47
1

This loop doesn't make any sense.

for (i = 0; b != NULL; i++)
    printf("%s", store[i]);
    b = store[i + 1];
}

store[i] is an int, so you can't print it with "%s". I think you meant printf("%c", store[i]); which means to print the characters whose character code is that int (which is OK, because you read this earlier with scanf).

b != NULL should be b != 0, but this tests an uninitialized value of b on the first time around the loop. Try this instead:

for ( i = 0; store[i] != 0; ++i )
    printf("%c", store[i]);

In the other piece of code, 65, 90, 97, 122 are more clearly expressed as 'A', 'Z', 'a', 'z' respectively.

You may want to consider using the isupper, islower functions from <ctype.h>. a - 32 should be replaced by toupper(a);.

M.M
  • 138,810
  • 21
  • 208
  • 365
1

I would change your body of processFile to:

int i, a = 0;
FILE *f = fopen("congress.txt", "r");

if(f) 
{
    for( i=0; i<300 && ((a=fgetc(f)) != EOF); i++)
    {
        if ( isupper(a) ){  //store capital letters
            store[i] = a;
        }
        else if ( islower(a) ){  //store lower case letters as capital
            store[i] = toupper(a);
        }
    }
    fclose(f);
}
if (i==300) i--;
store[i] = 0; // always put a zero after the last element 
              // since your loop in main depends on it to exit.

This takes care of EOF problems, and also fixes potential overflows of the store array. (You might want to pass store's max size to the routine instead of hardcoding 300...)

JohnH
  • 2,713
  • 12
  • 21