Home > database >  Determining last character of letter
Determining last character of letter

Time:10-21

Here is my code that I got it doesn't work it reads zero for everything please help i thought -1 is for the last string in the character. I need the program to report the number of words whose last letter is 'a', the number of whose last letetr is 'b' and so on that is irrespective of case. Here is my code below and I need help fixing it.

#include <string>
#include <iostream>
#include <fstream>
#include <cassert>
#include <cstring>
using namespace std;

int main(void)
{
    int aCtr = 0, bCtr = 0, cCtr = 0, dCtr = 0, eCtr = 0, fCtr = 0, gCtr = 0, hCtr= 0, iCtr = 0, jCtr = 0, kCtr = 0, lCtr = 0, mCtr = 0, nCtr = 0, oCtr = 0, pCtr = 0, qCtr = 0, rCtr = 0, sCtr = 0, tCtr = 0, uCtr = 0, vCtr = 0, wCtr = 0, xCtr = 0, yCtr = 0, zCtr = 0;
    string inputFileName;   //Declare variables
    string s;               //for storage
    ifstream fileIn;        //and file handling
    cin >> inputFileName;
    fileIn.open(inputFileName.data());
    assert(fileIn.is_open() );
    while (fileIn>>s)
    {
            if(isalpha(s[-1]))
            {
            if((s[-1]=='a') || (s[-1]=='A'))
                {
                aCtr  ;
                }
            }

    }
      {
            if(isalpha(s[-1]))
            {
            if((s[-1]=='b') || (s[-1]=='B'))
                {
                bCtr  ;
                }
            }

    }
      {
            if(isalpha(s[-1]))
            {
            if((s[-1]=='c') || (s[-1]=='C'))
                {
                cCtr  ;
                }
            }

    }
      {
            if(isalpha(s[-3]))
            {
            if((s[-3]=='d') || (s[-3]=='D'))
                {
                dCtr  ;
                }
            }

    }
      {
            if(isalpha(s[-1]))
            {
            if((s[-1]=='e') || (s[-1]=='E'))
                {
                eCtr  ;
                }
            }

    }
      {
            if(isalpha(s[-1]))
            {
            if((s[-1]=='f') || (s[-1]=='F'))
                {
                fCtr  ;
                }
            }

    }
      {
            if(isalpha(s[-1]))
            {
            if((s[-1]=='g') || (s[-1]=='G'))
                {
                gCtr  ;
                }
            }

    }
      {
            if(isalpha(s[-1]))
            {
            if((s[-1]=='h') || (s[-1]=='H'))
                {
                hCtr  ;
                }
            }

    }
      {
            if(isalpha(s[-1]))
            {
            if((s[-1]=='i') || (s[-1]=='I'))
                {
                iCtr  ;
                }
            }

    }
      {
            if(isalpha(s[-1]))
            {
            if((s[-1]=='j') || (s[-1]=='J'))
                {
                jCtr  ;
                }
            }

    }
      {
            if(isalpha(s[-1]))
            {
            if((s[-1]=='k') || (s[-1]=='K'))
                {
                kCtr  ;
                }
            }

    }
      {
            if(isalpha(s[-1]))
            {
            if((s[-1]=='l') || (s[-1]=='L'))
                {
                lCtr  ;
                }
            }

    }
      {
            if(isalpha(s[-1]))
            {
            if((s[-1]=='m') || (s[-1]=='M'))
                {
                mCtr  ;
                }
            }

    }
      {
            if(isalpha(s[-1]))
            {
            if((s[-1]=='n') || (s[-1]=='N'))
                {
                nCtr  ;
                }
            }

    }
      {
            if(isalpha(s[-1]))
            {
            if((s[-1]=='o') || (s[-1]=='O'))
                {
                oCtr  ;
                }
            }

    }
      {
            if(isalpha(s[-1]))
            {
            if((s[-1]=='p') || (s[-1]=='P'))
                {
                pCtr  ;
                }
            }

    }
      {
            if(isalpha(s[-1]))
            {
            if((s[-1]=='q') || (s[-1]=='Q'))
                {
                qCtr  ;
                }
            }

    }
      {
            if(isalpha(s[-1]))
            {
            if((s[-1]=='r') || (s[-1]=='R'))
                {
                rCtr  ;
                }
            }

    }
      {
            if(isalpha(s[-1]))
            {
            if((s[-1]=='s') || (s[-1]=='S'))
                {
                sCtr  ;
                }
            }

    }
      {
            if(isalpha(s[-1]))
            {
            if((s[-1]=='t') || (s[-1]=='T'))
                {
                tCtr  ;
                }
            }

    }
      {
            if(isalpha(s[-1]))
            {
            if((s[-1]=='u') || (s[-1]=='U'))
                {
                uCtr  ;
                }
            }

    }
      {
            if(isalpha(s[-1]))
            {
            if((s[-1]=='v') || (s[-1]=='V'))
                {
                vCtr  ;
                }
            }

    }
      {
            if(isalpha(s[-1]))
            {
            if((s[-1]=='w') || (s[-1]=='W'))
                {
                wCtr  ;
                }
            }

    }
      {
            if(isalpha(s[-1]))
            {
            if((s[-1]=='x') || (s[-1]=='X'))
                {
                xCtr  ;
                }
            }

    }
      {
            if(isalpha(s[-1]))
            {
            if((s[-1]=='y') || (s[-1]=='Y'))
                {
                yCtr  ;
                }
            }

    }
      {
            if(isalpha(s[-1]))
            {
            if((s[-1]=='z') || (s[-1]=='Z'))
                {
                zCtr  ;
                }
            }

    }
    cout<<"\nThere are "<<aCtr<<" words that end with A or a."<<endl;
    cout<<"\nThere are "<<bCtr<<" words that end with B or b."<<endl;
    cout<<"\nThere are "<<cCtr<<" words that end with C or c."<<endl;
    cout<<"\nThere are "<<dCtr<<" words that end with D or d."<<endl;
    cout<<"\nThere are "<<eCtr<<" words that end with E or e."<<endl;
    cout<<"\nThere are "<<fCtr<<" words that end with F or f."<<endl;
    cout<<"\nThere are "<<gCtr<<" words that end with G or g."<<endl;
    cout<<"\nThere are "<<hCtr<<" words that end with H or h."<<endl;
    cout<<"\nThere are "<<iCtr<<" words that end with I or i."<<endl;
    cout<<"\nThere are "<<jCtr<<" words that end with J or j."<<endl;
    cout<<"\nThere are "<<kCtr<<" words that end with K or k."<<endl;
    cout<<"\nThere are "<<lCtr<<" words that end with L or l."<<endl;
    cout<<"\nThere are "<<mCtr<<" words that end with M or m."<<endl;
    cout<<"\nThere are "<<nCtr<<" words that end with N or n."<<endl;
    cout<<"\nThere are "<<oCtr<<" words that end with O or o."<<endl;
    cout<<"\nThere are "<<pCtr<<" words that end with P or p."<<endl;
    cout<<"\nThere are "<<qCtr<<" words that end with Q or q."<<endl;
    cout<<"\nThere are "<<rCtr<<" words that end with R or r."<<endl;
    cout<<"\nThere are "<<sCtr<<" words that end with S or s."<<endl;
    cout<<"\nThere are "<<tCtr<<" words that end with T or t."<<endl;
    cout<<"\nThere are "<<uCtr<<" words that end with U or u."<<endl;
    cout<<"\nThere are "<<vCtr<<" words that end with V or v."<<endl;
    cout<<"\nThere are "<<wCtr<<" words that end with W or w."<<endl;
    cout<<"\nThere are "<<xCtr<<" words that end with X or x."<<endl;
    cout<<"\nThere are "<<yCtr<<" words that end with Y or y."<<endl;
    cout<<"\nThere are "<<zCtr<<" words that end with Z or z."<<endl;
    
    return 0;
}

CodePudding user response:

Use the back() function for std::string:

You can use it like this:

std::string str ("Testing");
cout << str.back()

The output will be: g

CodePudding user response:

Here's a suggestion of almost a complete rewrite of your code. Yet, it still considers ASCII input. The term "character" or "letter" might certainly be interpreted differently in languages like Japanese or Chinese. You don't just have 26 letters there.

Please look at this code, understand how much shorter it is than the code you posted and then dive into the things you don't understand (google it).

#include <string>
#include <sstream>
#include <array>
#include <iostream>

int main(void)
{
    std::array<int,'Z'-'A' 1> counters{0}; // 26 counters
    std::string s;               
    std::stringstream fileIn ("Hello world");  // I use a string instead of a file for demo purpose     
    while (fileIn>>s)
    {
        if (s.empty()) continue;
        char c = toupper(s.back());
        if ('A' <= c && c <= 'Z')
            counters[c-'A']  ;
    }
    for (char c='A'; c<='Z'; c  )
    {
        std::cout << "There are "<< counters[c-'A'] <<" words that end with " << c << std::endl;
        // std::cout << std::format("There are {} words that end with {}", counters[c-'A'], c) << std::endl; // C  20
    }    
}

CodePudding user response:

A few issues ...

  1. Using 26 separate counters vs. an array obscures many things (bugs).
  2. You only loop for A, so all other counters will be 0.
  3. Doing s[-1] causes an exception

Here is some refactored code. Please excuse the use of the printf:

#include <string>
#include <iostream>
#include <fstream>
#include <cassert>
#include <cstring>
#include <cstdio>
using namespace std;

int
main(void)
{
    int Ctr[26] = { 0 };
    string inputFileName;               // Declare variables
    string s;                           // for storage
    ifstream fileIn;                    // and file handling

    cin >> inputFileName;
    fileIn.open(inputFileName.data());
    assert(fileIn.is_open());

    while (fileIn >> s) {
#if 0
        char chr = s[-1];
#else
        size_t len = s.length();
        char chr = s[len - 1];
#endif

        if (isalpha(chr)) {
            chr = tolower(chr);
            Ctr[chr - 'a']  = 1;
        }
    }

    for (int idx = 0;  idx < 26;    idx) {
        int cnt = Ctr[idx];
        if (cnt) {
            int chr = idx   'a';
#if 0
            cout << "\nThere are " << cnt <<
                " words that end with " << tolower(chr) << " or "
                << toupper(chr) << endl;
#else
            printf("There are %d words that end with %c or %c\n",
                cnt,tolower(chr),toupper(chr));
#endif
        }
    }

    return 0;
}

In the above code, I've used cpp conditionals to denote old vs. new code:

#if 0
// old code
#else
// new code
#endif

#if 1
// new code
#endif

Note: this can be cleaned up by running the file through unifdef -k


Here is some test input I used:

Able Baker esac delta

Here is the program output:

There are 1 words that end with a or A
There are 1 words that end with c or C
There are 1 words that end with e or E
There are 1 words that end with r or R

UPDATE:

Looks awesome, easy to understand compared to mine :), how can I print the letters that have 0 words were found as well? – Jake Adams

A few options:

  1. The TL;DR: Change if (cnt) { into if (1) {
  2. Just remove the if (cnt) { and its corresponding } [and reindent the remaining code].
  3. Add a command line option (e.g. -a).

Here's a version that uses a command line option:

#include <string>
#include <iostream>
#include <fstream>
#include <cassert>
#include <cstring>
#include <cstdio>
using namespace std;

int opt_a;                              // 1=print all counts

int
main(int argc,char **argv)
{
    int Ctr[26] = { 0 };
    string inputFileName;               // Declare variables
    string s;                           // for storage
    ifstream fileIn;                    // and file handling

    --argc;
      argv;

    // decode command line options
    for (;  argc > 0;  --argc,   argv) {
        char *cp = *argv;
        if (*cp != '-')
            break;

        cp  = 2;
        switch (cp[-1]) {
        case 'a':  // show all counts [even those that are zero]
            opt_a = ! opt_a;
            break;
        }
    }

    cin >> inputFileName;
    fileIn.open(inputFileName.data());
    assert(fileIn.is_open());

    while (fileIn >> s) {
        size_t len = s.length();
        char chr = s[len - 1];

        if (isalpha(chr)) {
            chr = tolower(chr);
            Ctr[chr - 'a']  = 1;
        }
    }

    for (int idx = 0;  idx < 26;    idx) {
        int cnt = Ctr[idx];

        if (cnt || opt_a) {
            int chr = idx   'a';
            printf("There are %d words that end with %c or %c\n",
                cnt,tolower(chr),toupper(chr));
        }
    }

    return 0;
}

Here is the output using ./myprogram -a:

There are 1 words that end with a or A
There are 0 words that end with b or B
There are 1 words that end with c or C
There are 0 words that end with d or D
There are 1 words that end with e or E
There are 0 words that end with f or F
There are 0 words that end with g or G
There are 0 words that end with h or H
There are 0 words that end with i or I
There are 0 words that end with j or J
There are 0 words that end with k or K
There are 0 words that end with l or L
There are 0 words that end with m or M
There are 0 words that end with n or N
There are 0 words that end with o or O
There are 0 words that end with p or P
There are 0 words that end with q or Q
There are 1 words that end with r or R
There are 0 words that end with s or S
There are 0 words that end with t or T
There are 0 words that end with u or U
There are 0 words that end with v or V
There are 0 words that end with w or W
There are 0 words that end with x or X
There are 0 words that end with y or Y
There are 0 words that end with z or Z
  • Related