简体   繁体   中英

Finding a vertical word from a .txt file in C++

I am working on a small project and I am trying to put a set of letters (5 rows, 5 columns) from a .txt file into an array, then finding the vertical word "DOG." Not only do I have to find it, but I have to determine the position of the word also. I am having so much trouble getting it to complete this task.

1) It doesn't matter if I take the word DOG out or not. My code still says it finds the word.

2) It always displays the same position if I move the word DOG to another spot on the puzzle.

3) It just doesn't work...

Can any of you help?

Please keep in mind, this is my 2nd week of C++. I am currently taking an intro college course on this language so no hate. I am only trying to learn. I spent probably a total of 12 hours on this code.

#include <iostream>
#include <fstream>

using namespace std;

int main() {
  char puzzle[25];
  ifstream fin;
  fin.open("words.txt");

  int rows {5};
  int cols {5};

  for (int i=0;i<rows*cols;i++) fin >> puzzle[i];
  fin.close();

/***********
 This is what I believe the array looks like and the values of each position.

 * 0   1   2  3   4
 * 5   6   7  8   9
 * 10  11  D  13  14
 * 15  16  O  18  19
 * 20  21  G  23  24
************/

string s = "DOG";
cout << s.size() << endl;
int foundpos {-1};

for (int i=0; i<rows*cols; i++) {
  if (puzzle[i]==s[0]) {
        foundpos=i;
        for (int j=5; j<s.size(); j+5) {
          if (puzzle[i+j]!=s[j]) {
                foundpos=-1;
                break;
          }
        }
 }

     if (foundpos>0) {
        cout << s << " was found at pos " << foundpos << endl;
        cout << s << " found on row " << foundpos << endl;
        cout << s << " found on column " << foundpos << endl;
        break;
     }
 }

 if (foundpos==-1) cout << s << " not found." << endl;

 return 0;
}

===============================================================

Now here is the .txt file.

YRUVG RTSDC IFDYU EPOWE PWGHT

Your problem is here:

for (int j=5; j<s.size(); j+5) {
          if (puzzle[i+j]!=s[j]) {
                foundpos=-1;
                break;
          }
        }

Your idea: when you get the first letter of given string, you try to check the next letter of same column is same with the next letter of given string. But, you ran the loop from 5, note that s.size() = 3 , so your loop does NOT run. Then, the foundpos is not set to -1 . That's why you always see 8 in print log.

Fix:

for (int j=1; j<s.size(); j++) {
          if (puzzle[i+j*5]!=s[j]) {
                foundpos=-1;
                break;
          }
        }

There were a few other caveats that you would need to address that I was unable to include in the comments. Since you are reading all characters into a single array which you want to represent as a 2D array, you will need to index puzzle[i][j] as puzzle[i + j * STRIDE] .

The primary approach is to loop over each character is puzzle checking whether the first character in your search term is the current character. If it is, you check:

  1. Do enough character remain between i and rows*col for the rest of the search term to exist in a column? If not, you can conclude your string is not found;
  2. If enough character remain, set a found = true flag and loop over the remaining characters in your search term (eg from j = 1 to term.size() ) checking puzzle[i + j * STRIDE] != term[j] if a non-matching term is found, set found = false and break the term loop; and
  3. finally check the found flog. If it has survived as found == true at this point, your search term has been found and you can simply output the indexes for the search term and return.

For example, putting it altogether in a short example, you could do:

#include <iostream>
#include <fstream>
#include <string>
#include <cctype>   /* for isspace() */

#define STRIDE 5    /* define const for stride */

int main (int argc, char **argv) {

    char puzzle [STRIDE*STRIDE] = {0}, c;   /* puzzle and char */
    size_t psize = STRIDE*STRIDE, n = 0;    /* puzzle size & char count */
    std::string fname = argv[1],            /* filename */
                term = argc > 2 ? argv[2] : "DOG";  /* search term */
    std::ifstream f;    /* file stream */

    if (argc < 2) { /* validate at least filename given as arg */
        std::cerr << "error: insufficien input.\n"
                << "usage: " << argv[0] << "infile\n";
        return 1;
    }

    f.open (argv[1]);   /* open file */
    if (!f.is_open()) { /* validate file open for reading */
        perror (("error file open failed " + fname).c_str());
        return 1;
    }

    while (n < psize && f >> c) /* read file into puzzle */
        if (!isspace (c))
            puzzle[n++] = c;
    f.close();                  /* close file */

    if (n < psize) {    /* validate psize characters read */
        std::cerr << "error: only " << n << "characters read.\n";
        return 1;
    }

    for (size_t i = 0; i < psize; i++) {    /* loop over each char */
        if (puzzle[i] == term[0]) {         /* if matches 1st in term */
            size_t tlen = term.size(),      /* get term size */
                    found = 1;              /* set found flag true */
            if (i + (tlen - 1) * STRIDE >= psize)   /* enough chars left? */
                break;
            for (size_t j = 1; j < tlen; j++)   /* loop 1 to term len */
                if (puzzle[i + j * STRIDE] != term[j]) { /* next !found? */
                    found = 0;      /* set found flag false */
                    break;          /* break loop */
                }
            if (found) {    /* if found, output term & indexes, return */
                std::cout << "found " << term << " at indexes " << i;
                for (size_t j = 1; j < tlen; j++)
                    std::cout << ", " << i + j * STRIDE;
                std::cout << '\n';

                return 0;
            }
        }
    }

    /* only reachable if not found */
    std::cout << "'" << term << "' not found.\n";
    return 1;
}

Example Input File

$ cat dat/vertword.txt
YRUVG
RTSDC
IFDYU
EPOWE
PWGHT

Example Use/Output

$ ./bin/verticalfind dat/vertword.txt
found DOG at indexes 12, 17, 22

$ ./bin/verticalfind dat/vertword.txt RIEP
found RIEP at indexes 5, 10, 15, 20

$ ./bin/verticalfind dat/vertword.txt MOP
'MOP' not found.

Look things over and let me know if you have further questions.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM