Link to home
Start Free TrialLog in
Avatar of markov123
markov123

asked on

Need help in syntax. No of occurrences

I need help in finding out the problem with my code.

I have displayed here parts of the code for clarification.




/initialisation
char      inchars[200],
      outchars[200], spoutchars[200];
int      acount = 0,count=0,i=0, j = 0, c, letter[26];



//here i am opening a file for writing
outfile = fopen("c:\\nasser\\cprograms\\tout.txt","w");
if (outfile == NULL)
      printf("Cannot find output file");


// some process
//
//
//



// a bunch of capital letters written here
// eg. THIS IS A TEST TO COUNT THE NUMBER OF OCCURENCES OF EACH LETTER
fputs(spoutchars,  outfile);



//initializing array letter to zeros
for (j = 0; j < 26; ++j)
      letter[j] = 0;
      

//reading outfile, and assigning a number of occurences of each letter
while ((c = getc(outfile)) != EOF)
      ++letter[c - 'A'];
      
      
Everything works the way I wanted until I got to this statement
// printing out the array letter.      
for (i = 0; i < 26; i++)
      printf("%d", letter[i]);
      
I was expecting freq of occurrences of each letter here but I get a bunch of 26 zeros.

I am definitely doing something wrong, but not quite sure what it is.

Any help would be appreciated.

Thanks in advance.

Mark.
Avatar of ozo
ozo
Flag of United States of America image

I don't see you opening outfile for reading anywhere.

If getc(outfile) is ever anything other than 'A'-'Z' or EOF letter[c - 'A'] will be out of the range of the array.
Avatar of markov123
markov123

ASKER

As I mentioned above, I did not post the whole code, here it is.

Outfile contains only 'A'-'Z', so there is no problem there.

#include <stdio.h>

int main()
{


/////////////////////////////////////////////////
/////////// Initialisation //////////////////////
/////////////////////////////////////////////////
FILE  *infile;
FILE      *outfile;
//FILE  *outfile;

//char outchars[200];
char      inchars[200],
            outchars[200], spoutchars[200];
int            acount = 0,count=0,i=0, j = 0, c, letter[26];

// open i/o files

infile = fopen("c:\\markov\\cprograms\\linetest.txt","r");

if (infile == NULL)
      printf("Cannot find input file");



outfile = fopen("c:\\markov\\cprograms\\tout.txt","w");

if (outfile == NULL)
      printf("Cannot find output file");





while (fgets(inchars, 200, infile) !=NULL)
{
      while(inchars[i] !='\n')//scan a line i
      {
            
            outchars[i] = toupper(inchars[i]);  //convert to upper case
            
            outchars[i] = toupper(inchars[i]);  //convert to upper case
            if ((outchars[i] >= 'A' && outchars[i] <= 'Z'))//test within a line
                  spoutchars[i] = outchars[i];
      
           count++;
      
        i++;
      }
      
      
      
      acount++;      
    i=0;
      fputs(spoutchars,  outfile);
   
}

//initialise new array

for (j = 0; j < 26; ++j)
      letter[j] = 9;
      
      
while ((c = getc(outfile)) != EOF)
      ++letter[c - 'A'];
      
for (i = 0; i < 26; i++)
      printf("%d", letter[i]);


//for (j = 0; j < 10; j = j + 1)
//      printf(spoutchars[j]);


//printf("There are %d lines in this file\n", acount);
//printf(" letter a: %d\n", count);
//printf("%s",spoutchars);
fclose(infile);
fclose(outfile);



      return 0;
}
Some compilers have strange operator precedence. If ozo's suggestion doesnt work, you could try:

letter[c - 'A'] += 1;

because:

++letter[c - 'A'];

could be interpreted as:

(++letter)[c - 'A'];

which would obviously not be what you want.

Paul

>>while ((c = getc(outfile)) != EOF)
You've opened outfile for write only access! This will not work! You cant use 'getc' on an output file.

Paul
I still don't see outfile being opened for reading before trying to getc(outfile)
Thanks for your comments, I found my programs too cumbersome, I have therefore re written it in a simpler (hopefully more efficient) way.

While the program removes all non alphabetic characters and doen the capitalization. I still have a problem in getting the occurrences.

So when the file gets executed, these two statements print nothing:
     letter[c - 'A'];
     printf("%c", cap_char);

Again, am posting the code here.


Your help on this is highly appreciated.

Thanks in advance




#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main()
{
     FILE *rfile;
     
     rfile = fopen("c:\\markov\\cprograms\\t.txt", "r");
     
     long count = 0;

     int in_char,
                 cap_char,
                 letter[26],
                 c;

     if ((rfile) == NULL)
     {
          printf("Cannot open input file\n");
     
     }

     in_char = fgetc(rfile);
     printf("%c", toupper(in_char));

     while (in_char != EOF)  
     {
     
       in_char = fgetc(rfile);
       cap_char = toupper(in_char);
       
       if((cap_char >= 'A') && (cap_char <= 'Z'))
       {
                  letter[c - 'A'];
                  printf("%c", cap_char);
                   
       }
       count++;
   
     }
      
        printf("%s", letter);      
     printf("\nThere are %d characters in the file\n", count);
     fclose(rfile);
     return 0;
}

1) this statement does nothing:  letter[c - 'A'];
2) is your file 'c:\\markov\\cprograms\\t.txt' populated with chars?
1) I have just changed it to letter[cap_char - 'A']


2) yes, my file is just a normal text file.

i need two simple operations.

1. capitalise,
2. count the occurrences,
 for example: C PROGRAMMING IS QUITE FRUSTRATING.

Output: A: 0, B: 0, C: 1, D: 0, E: 1, and so forth.



>>letter[cap_char - 'A']
This just has a value. If you wish to change the value in that location then you need to do something with it. I suspect you want to add one? You are adding one to 'count' elsewhere in your code, perhaps that is what you need to do here.

Paul
Besides the statement which does nothing, there is a logic error in your loop. You are doing this:

    in_char = fgetc(rfile);

    while (in_char != EOF)  
    {
        in_char = fgetc(rfile);

        /* Do something with in_char */
    }

Do you see the error now?
Sorry, but I do not see the error here.

I have modified it further:

 while (in_char != EOF)  
     {
     
       in_char = fgetc(rfile);
       cap_char = toupper(in_char);
       
       if((cap_char >= 'A') && (cap_char <= 'Z'))
       {
                  ++letter[cap_char - 'A'];
                  //printf("%d\t", cap_char);
                  printf("%d ", letter[count]);
                  count++;
                   
       }

It compiles and runs, instead of printing the occurences, it prints out large numbers, which I assume are addresses. For example, if the text 5 contains 5 chars, I get a combination of 5 large numbers (maybe one or two small).

Again I appreciate your inputs, would like some more.

Thanks in advance.

Mark
SOLUTION
Avatar of cwwkie
cwwkie

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
ASKER CERTIFIED SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial


I got the program to work. Two problems I had

1. The array was not initialised to zero.
2. The loop for printing out chars was inside the main while loop, when I took it out, the program worked like a charm.

I still cannot figure out why it wont work when the printf is inside the loop.

I like to thank both Paul and cw for your help. You guys have been very patient.

Here is the latest version:


 //ititialise array
        for(i = 0; i < 26; ++i)
              letter[i] = 0;

 while (in_char != EOF)  
     {
     
       in_char = fgetc(rfile);
       cap_char = toupper(in_char);
       
       if((cap_char >= 'A') && (cap_char <= 'Z'))
       {
                  ++letter[cap_char - 'A'];
                  //printf("%d\t", cap_char);
                  //printf("%d ", letter[count]);
                  count++;
                   
       }
       //count++;
   
     }
              
              
        //count freq
        for (int j = 0; j < 26; j++)
              printf(" %c:%d ", 'A' + j, letter[j]);
     printf("\nThere are %d characters in the file\n", count);
     fclose(rfile);
     return 0;
Is it working correctly now? In the previous version you would forget to count one character.
I have tested it and the count is correct.  The only problem I have is that I need the first line below in order for the progam to work, if I dont incluse that line, it fails. I have no idea why.


     in_char = fgetc(rfile);  //the prog fails if i dont include this line
     printf("%c\n", toupper(in_char));

     while (in_char != EOF)  
     {
     
       in_char = fgetc(rfile);
       cap_char = toupper(in_char);
       
       if((cap_char >= 'A') && (cap_char <= 'Z'))
       {
                  ++letter[cap_char - 'A'];
                      count++;
                   
       }
       //count++;
   
     }
              
              
Thats because you have to read the first character before checking it dont you?

The normal way to tidy this up is to do something like:

     while ((in_char = fgetc(rfile)) != EOF)  
    {
     
       // in_char = fgetc(rfile); Dont need this anymore because its already been read.
       cap_char = toupper(in_char);
  ...

Paul
Thanks Paul, will try and make those changes