Hi everyone.

I want to read a file and store each word in an array. I also want to know how many words there are in the file. After I do this, I want to reverse the words from two different files and see if they are anagrams.

Here is what i have so far...

makeWordList: identify the words and store in an array
getWordList: returns the list of words
getNumWords: returns the number of words found
findAnagrams: compares two word list and see if any word from one list is the reverse of the word in the other list. for example blah and halb

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


extern void makeWordList (char*fileName);
extern char **getWordList ();
extern int getNumWords ();
extern void findAnagrams (char*fileName1, char*fileName2);

char words [CHAR_LIMIT + 1]; /*global so I can use it in other method*/

void makeWordList(char*fileName);

{ 
  FILE *inputFile;
  char ch;
  int index = 0;

  inputFile = fopen (fileName, "r");
  ch = fgetc (inputFile);
  while (ch != EOF) {
    if (ch != '\n') {
      if (index >= CHAR_LIMIT) {
        printf ("Character limit reached. Exiting program.\n");
        exit (0);
      }
      words[index] = ch;
      index++;
    }
    else {
      words[index] = '\0';
      index++;
    }
    ch = fgetc (inputFile);
  }
  fclose (inputFile);
}



void printWordList (char *fileName)
{
  char **words;
  int i, numWords;

  makeWordList (fileName);
  words = (char**) getWordList ();
  numWords = getNumWords ();
  printf ("Words in file %s\n", fileName);
  for (i=0; i<numWords; i++) {
    printf ("  %s\n", words[i]);
  }
}

int main (int argc, char **argv) 
{
  printWordList ("ex2test1.txt");
  printWordList ("ex2test2.txt");
  printWordList ("ex2test3.txt");
  findReversals ("ex2test2.txt", "ex2test3.txt");
}

Edited 7 Years Ago by Samyx: n/a

Sorry, I should had paid attention.

How can I return the list of words? and how do I find an anagram?

Edited 7 Years Ago by Samyx: n/a

Sorry, I should had paid attention.

How can I return the list of words? and how do I find an anagram?

You made words[] global, so you don't have to return it or pass it. You do have a potential problem in that you declare a local variable with the same name on line 44. Could get confusing.

Your function void makeWordList(char*fileName); should have the array as a parameter. You pass in an initially empty array, the function fills it, when the function returns, the caller has some data.

void makeWordList(char*fileName, char ** words )

Couple of points. The semicolon at the end of your function header must be removed, else the compiler sees that as a prototype and the code following will be seen as an error.

Second, I'd have the function return a count of words actually read in - there may be fewer than your list can hold. And, returning a count of 0 would indicate an empty list, so you don't go processing stuff that's not there.

Anagram - your description and example indicate you're looking for reversed words, which are not the same as anagrams. As you test the pairs of words, make a copy of one, reverse it end for end, then do a simple string comparison. There are many discussions here and elsewhere on the web of how to reverse a string.

Your function void makeWordList(char*fileName); should have the array as a parameter. You pass in an initially empty array, the function fills it, when the function returns, the caller has some data.

void makeWordList(char*fileName, char ** words )

Couple of points. The semicolon at the end of your function header must be removed, else the compiler sees that as a prototype and the code following will be seen as an error.

Second, I'd have the function return a count of words actually read in - there may be fewer than your list can hold. And, returning a count of 0 would indicate an empty list, so you don't go processing stuff that's not there.

Anagram - your description and example indicate you're looking for reversed words, which are not the same as anagrams. As you test the pairs of words, make a copy of one, reverse it end for end, then do a simple string comparison. There are many discussions here and elsewhere on the web of how to reverse a string.

if I do the

void makeWordList(char*fileName, char ** words )

my array wont be global. I need it to be global so I can use it in my next method getWordList that is gonna return a list of words.

Declare the array in main( ). Pass it as parameter to every function that needs it.

Use of global variables is something to be avoided. It may not be a big problem in small programs, but as complexity grows, use of global variables can lead you into all kinds of problems. Any function that can modify the global, eventually will, and you'll have no control of what's going on.

A function should be able to stand on its own - you see what goes in via the parameter list, you know what goes out via the return or, in this case, reference parameters. No hidden communications.

You made words[] global, so you don't have to return it or pass it. You do have a potential problem in that you declare a local variable with the same name on line 44. Could get confusing.

I am having a problem with my global array, it says that is not declared or something, I don't think the program is recognizing its size. How can I declare a global array without identifying its size?

Declare the array in main( ). Pass it as parameter to every function that needs it.

Use of global variables is something to be avoided. It may not be a big problem in small programs, but as complexity grows, use of global variables can lead you into all kinds of problems. Any function that can modify the global, eventually will, and you'll have no control of what's going on.

A function should be able to stand on its own - you see what goes in via the parameter list, you know what goes out via the return or, in this case, reference parameters. No hidden communications.

How can I declare an array in Main when I don't know its size?

I am having a problem with my global array, it says that is not declared or something, I don't think the program is recognizing its size. How can I declare a global array without identifying its size?

You should (almost) never use global variables. It's very dangerous to do so!
But the reason your code won't compile is: char words [CHAR_LIMIT + 1]; . What is "CHAR_LIMIT" and where is it declared? Also note that when you declare CHAR_LIMIT, it has to be a "const", else your compiler will still not like it.

How do you know the size when you declare it globally?

Your constant CHAR_LIMIT is not declared anywhere, so it doesn't exist. Thus, you cannot use that to set the array size.

And, you are declaring a 1D array of char, putting all the words read in into it one character at a time. Not a correct or efficient method. By placing the NULL ( '\0') at the first point you read in an endline, everything else you store to that array will be ignored when displayed or compared.

You need a 2D array of char to store multiple words.

You need a 2D array of char to store multiple words.

If you want to do it the C-way then, yes Vmanes is right. But since you (OP) posted this question in the C++-forum, I highly recommend that you use std::strings and std::vectors for this program. It will make your life a lot easier because you don't have to worry about how big the vector (array) needs to be declared etc.

Here's a sample program:

#include <iostream> 
#include <string>
#include <vector>
using namespace std;

int main(){
    vector<string> my_vec;
    my_vec.push_back("first name");
    my_vec.push_back("second name");
    my_vec.push_back("third name");

    cout << "Vector now has " << my_vec.size() << " values in it:\n";
    for (unsigned i = 0; i < my_vec.size(); i++)
        cout << "Value of key " << i << " is: " << my_vec.at(i) << '\n';
}

Run it and see what I mean ;)

How do you know the size when you declare it globally?

Your constant CHAR_LIMIT is not declared anywhere, so it doesn't exist. Thus, you cannot use that to set the array size.

And, you are declaring a 1D array of char, putting all the words read in into it one character at a time. Not a correct or efficient method. By placing the NULL ( '\0') at the first point you read in an endline, everything else you store to that array will be ignored when displayed or compared.

You need a 2D array of char to store multiple words.

I don't know the size, thats why I am having problems when declaring CHAR_LIMIT. I know the size of my array would be equivalent to the number of words in the file. Should I count the number of words first and then store it in array?
My professor said I should store the words in an array first and the return the size of the array, which would be the same as the number of words.

My main program has to look like this:

void printWordList (char *fileName)
{
  char **words;
  int i, numWords;

  makeWordList (fileName);
  words = (char**) getWordList ();
  numWords = getNumWords ();
  printf ("Words in file %s\n", fileName);
  for (i=0; i<numWords; i++) {
    printf ("  %s\n", words[i]);
  }
}

int main (int argc, char **argv) 
{
  printWordList ("ex2test1.txt");
  printWordList ("ex2test2.txt");
  printWordList ("ex2test3.txt");
  findReversals ("ex2test2.txt", "ex2test3.txt");
}

You should (almost) never use global variables. It's very dangerous to do so!
But the reason your code won't compile is: char words [CHAR_LIMIT + 1]; . What is "CHAR_LIMIT" and where is it declared? Also note that when you declare CHAR_LIMIT, it has to be a "const", else your compiler will still not like it.

My professor wants me to use global variables so I can see how it works and affect the program :/

I didn't declare CHAR_LIMIT because I don't know the size of the array. thats what I am trying to figure out right now. Any thoughts?

My professor wants me to use global variables so I can see how it works and affect the program :/

I didn't declare CHAR_LIMIT because I don't know the size of the array. thats what I am trying to figure out right now. Any thoughts?

Are you sure he said global VARIABLE and not global CONSTANT?

CHAR_LIMIT would be a constant, and that's OK to use.
Declaring the array of words in global scope is a variable, and generally not the way to do things.

As to how big t make CHAR_LIMIT, does the assignment give any size scope? When I make such assignments, I tell the students their program must be able to handle up to some specified limit. A good program will properly handle 0 to that limit items, and in best case, indicate there may be more data in file than program supports.

"The method makeWordList (char *fileName). As we said above, this method will take in a file name, read from the file and identify the words in the file. These words should be stored in a global array for use in the next method"

This is what the instruction say :/

Ok, if that's what he says to do, you do it.

You'll need to declare the array(s) in global scope (outside all functions). Again, it must be a 2D array, where each row will hold one word.

Ok, if that's what he says to do, you do it.

You'll need to declare the array(s) in global scope (outside all functions). Again, it must be a 2D array, where each row will hold one word.

Given that it's a 2-D array, what does CHAR_LIMIT represent? Are we thinking something like this?

const int MAX_NUM_WORDS = 100;
const int MAX_CHAR_PER_WORD = 50; // includes null term.
const int CHAR_LIMIT = MAX_NUM_WORDS * MAX_CHAR_PER_WORD;
char words[MAX_NUM_WORDS][MAX_CHAR_PER_WORD];

That defines everything (doesn't actually USE CHAR_LIMIT), but doesn't go with the original line:

char words [CHAR_LIMIT + 1];

And the line above doesn't go with lines like this:

words = (char**) getWordList ();

I'd get clarification on whether it's a 1-D or a 2-D array and what CHAR_LIMIT represents. It's gotta be a 2-dimensional array with lines like the one above.

And using parameters with the same name as the global variable always confuses me:

void makeWordList(char*fileName, char ** words )

And if words[][] is global, why bother even passing the parameter? Why not make the function this?

void makeWordList(char*fileName)

Maybe it's one of those assignments where the professor tells you to do it one way, then you do it, and he says "That was a really bad way of doing it; now I'm going to show you the right way?"

It gotta be a char**, thats means it is an array of array right?

I am getting an error saying that I cannot convert from char to char[50]

words[index] = ch;

Assuming you have words[NUMWORDS][WORDLIMIT], then using a single index relates to a give row, a 1D array of char.

So, you cannot assign a single char to that string. And you cannot use the assignment operator ( = ) to do any string assignments.

You can assign a single char to a given position in that string.

Look at the following sample uses

#include <iostream>
#include <cstring>
using namespace std;

void foo( char *s );

int main( )
{
	char words[10][50] = { "" };  //ten words, max 49 char per word
	  //all initialized as empty strings

	words[1][0] = 'a';  //change a single character
	
	strcpy( words[2], "hello" );  //assign a full word

	cout << words[1] << endl;
	cout << words[2] << endl;

	foo( words[2] );
	cout << words[2] << endl;
	return 0;
}

void foo ( char *s )
{
	cout << s << endl;

	strcpy( s, "new words!" );
}

What is wrong with this code?

const int MAX_NUM_WORDS = 100;
const int MAX_CHAR_PER_WORD = 50; 
const int CHAR_LIMIT = MAX_NUM_WORDS * MAX_CHAR_PER_WORD;
char words[MAX_NUM_WORDS][MAX_CHAR_PER_WORD];
int index=0;

void makeWordList (char *fileName)
{ 
  FILE *inputFile;
  char ch;
 
  inputFile = fopen (fileName, "r");
    
  ch = fgetc (inputFile);
  while (ch != EOF) {

    if (ch != '\n') {
      if (index >= CHAR_LIMIT) {
        printf ("Character limit reached. Exiting program.\n");
        exit (0);
      }
      words[index] = ch;
      index++;
    }
    else {
      words[index] ='\0';
      index++;
    }
    ch = fgetc (inputFile);
  }
  fclose (inputFile);
}

Edited 7 Years Ago by Samyx: n/a

words[index] ='\0'; -- see my previous comments

You need an index for the word being filled, and an index for the character of that word.

When you get to the endline, set the word index to plus 1, reset the character index back to 0.

And I go back to my first comment, this is a C++ forum. Is your class in C or C++? This is really an easy assignment using the C++ input methods.

This is what I have so far:

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


int const max_words = 30;
int const max_char = 20;

int wordcount=0;
int charcount=0;
char wordlist[max_char][max_words];

void makeFileList(char*fileName) 
{
	FILE *inputFile;
	
	int spacecount =0;
	char ch;

	inputFile = fopen(fileName, "r");
	ch=fgetc(inputFile);
	  while (ch!=EOF){
		  while (charcount<=max_char && wordcount<=max_words){
			if ((ch>=48 && ch<=57)||(ch>=65 && ch<=90)||(ch>=97 && ch<=122)){
				wordlist[charcount][wordcount]=ch;
				spacecount=0;
				charcount+=1;
			}
			else if (spacecount==0){
				wordlist[charcount][wordcount]='\0';
				wordcount+=1;
				charcount=0;
			}
			spacecount+=1;
		  }
	  }  
		  
	  fclose(inputFile);
  }

How can I return the list but using a different method? for example

char **getWordList()

It's a C class :/
I am newbie newbie in this .

You're in the wrong forum then. This is the C++ forum. Start a thread in the C forum.

How can I return the list but using a different method? for example

char **getWordList()

Well what's this function supposed to do? I imagine it's just this?

char **getWordList()
{
    return words;
}

words is a char**, right? The function takes no parameters. What else could this function do?

I think you should probably go back to the original spec and start from there. Most of this thread has been trying to clarify whether this is C or C++, why words[][] is global, and why it would be, and whether it's a 1-D array or a 2-D array.

How can I return the list but using a different method?

You're asking "how". I'm asking "what" and "why". What's the overall goal of the project? Have you been told to use a variable called CHAR_LIMIT and what is it supposed to represent? Do you have to have the function char **getWordList() ? What exactly is it supposed to do?

I'd say your best bet is to clarify in your head what exactly you're trying to do and start a new thread in the C forum with the entire project specification.

This article has been dead for over six months. Start a new discussion instead.