# Thread: FGETS from text to array

1. We wont be doing anything past this little bit dealing with text i/o from files, we already have our last project which is dealing with a whole different ball park.

He just had a multi-dimensional array in his "guide" to help students work through the project, but as you said, a third array seems meaningless and i agree with adding the \0 .. forgot to put that in

2. Definitely drop the third dimension then. I had a bit of a play with this and knocked together a working program with a 3d array, but I found the third dimension quite awkward. I made some mistakes that lead to NULL words being in the array, as you described earlier. So I bet you were just incrementing the word number (j) when you shouldn't have been, or not resetting k.

I imagine it'll be easier with 2 dimensions. Good luck

3. Yeah I dropped the third dimensionally , made it SOO much easier to work with... but ran into a snag

trying to find unique words but my logic is flawed again, any tips?

textArray carries all the words in the text file and i need to search through text array and put the words into uArray, if uarray already has the word, then move on

any help would be great. below is my code:

Code:
```
int i, j, count = 1;

strcpy(uArray[0], textArray[0]);
for(i = 0; i < 500; i++){
for(j = 0; j < count ; j++){
if(strcmp(uArray[j], textArray[i]) != 0){
strcpy(uArray[count], textArray[i]);
count++;
break;
}

}
}```

4. If you sort the words, any duplicates will be adjacent to each other. So finding unique word(s) is a matter of stepping through the list, comparing each word with every other word. You should end up with a list of unique words.

5. Sorting is a good idea! I think for a data set of this size you probably won't lose or gain a lot by doing it one way over the other, but for llarger amounts of input data you probably should be thinking of alternatives to re examining all the elements in nArray.

So... what you're trying to do should work, and would have been my first thought too.

Code:
```
int i, j, count = 1;

strcpy(uArray[0], textArray[0]);```
So far so good.

Code:
`     for(i = 0; i < 500; i++){`
Where did this 500 come from? I remember your arrays being quite a lot smaller. Style suggestion: #define MAX_WORD_LENGTH and maybe MAX_WORDS to avoid 'magic' constants appearing in your code.

Code:
```           for(j = 0; j < count ; j++){
if(strcmp(uArray[j], textArray[i]) != 0){
strcpy(uArray[count], textArray[i]);
count++;
break;
}

}```
This is where your logical error is. You're definitely on the right track - The idea is right but the implementation is not quite there. For example if you had

"cat dog cat" in textArray
cat goes into uArray
dog considered ... dog != cat so dog added to uArray
cat considered. Cat == cat for uArray[0]. But then j is incrememnted and the compare is tried again: Is uArray[1] - "dog" a duplicate of cat" -- no, add it again. Whoops. Got too many cats.

You've got a "break" in there for when the word is added. That's good, but also, finding a duplicate is also time for "break" -- there's nothing else we can do with the word. I suggest something like this

Code:
```	bool seen = false;
for(j = 0; j < count ; j++)
{
seen = false; // reset "seen" for new word
// if strings equal...
if(strcmp(uArray[j], textArray[i]) == 0)
{
seen = true;
// break - we don't want to add this word to uarray
break;
}

// this is outside of the 'j' loop so can only be executed once for each word now
if (!seen)
{
strcpy(uArray[count], textArray[i]);
count++;
}
}```

6. First glance I noticed a problem with the code, it doesn't increment i at all..

I think I get it. Is this the final code you are suggesting?

Code:
```void get_Uwords(){
int i, j, count = 1;

strcpy(uArray[0], textArray[0]);
for(i = 0; i < 500; i++){
bool seen = false;
for(j = 0; j < count ; j++)
{
seen = false; // reset "seen" for new word
// if strings equal...
if(strcmp(uArray[j], textArray[i]) == 0)
{
seen = true;
// break - we don't want to add this word to uarray
break;
}

// this is outside of the 'j' loop so can only be executed once for each word now
if (!seen)
{
strcpy(uArray[count], textArray[i]);
count++;
}
}
}
}```
if thats the code, my program is crashing with this code implemented

not sure why

7. Oh dear. No, that was meant more to just be a suggestion as to how you could do it. I haven't put any effort into making sure it's safe....

It might be crashing because of the < 500 loop condition, obviously that should be adjusted appropriately if your array is smaller

8. I did make that change, i made a counter when storing the words to be used in this function.. so if it only stores 137 words it will only loop 137 times in that function. So it works well that way.

9. Its actually hanging up on the 6th word or something, thats why its crashing.

by hanging up i mean, it doesn't change words and keeps checking the same words over and over again

10. You should initialize count to 0, since at first go, there are 0 words in uArray (remember, 0 is the first element of an array in C). Also:
Code:
`            // this is outside of the 'j' loop so can only be executed once for each word now`
That statement is not true. That code is inside the 'j' loop (look at your braces and indentation). It should be moved outside.

Lastly, how are you passing any arguments to get_Uwords? Can we get a full code listing to see how you call this function? Please don't tell me you're using globals for this. Read why you shouldn't here: Global Variables Are Bad.

11. i'm not using global variables, i'm simply taking the function that gets the words and sending back an int value from that function to a variable in the main function. From there i'm sending the size to the other functions.

also sending the arrays as pointers to the functions.

12. as for the count to 0, remember we are intializing the first array element uArray, copied from textArray.

so 1 is fine. since we know that is already in the array.

13. Originally Posted by Oonej
i'm not using global variables, i'm simply taking the function that gets the words and sending back an int value from that function to a variable in the main function. From there i'm sending the size to the other functions.

also sending the arrays as pointers to the functions.
Glad you're not using globals. But I don't see you actually sending the size or uArray or textArray to get_Uwords, and those variables are not declared locally in that function either, so that function shouldn't even compile as shown. Please show me the full code that you're using and that causes errors on the 6th word. It's quite possible an error elsewhere is manifesting itself in this function (are you sure the program locks up in this function? How do you know?). Also, you didn't mention whether you actually moved that if (!seen) block outside of the j loop where it belongs.

Originally Posted by Oonej
as for the count to 0, remember we are intializing the first array element uArray, copied from textArray.

so 1 is fine. since we know that is already in the array.
Ahh, yes, I missed that. Sorry.

14. I can't post my full code, since i can't delete it and had people from my class taking my work on the last several projects.. not looking to get into trouble for posting full code, but i can post this segment.

Code:
```int main(void){
int total_words = 1;
char textArray[400][21];
char uArray[400][21];

//missing code here.. not relevant to the part im working on.
total_words = get_words(textArray);
get_Uwords(total_words, textArray, uArray);
// more missing code
}```
Code:
```void get_Uwords(int total_words, char (*textArray)[21], char (*uArray)[21]){
int i, j, count = 1, g = 0;

printf("%d", total_words);

strcpy(uArray[0], textArray[0]);

for(i = 0; i < total_words; i++){
g = 0;
for(j = 0; j < count ; j++)
{
g = 0; // reset "seen" for new word
// if strings equal...
if(strcmp(uArray[j], textArray[i]) == 0)
{
g = 1;
// break - we don't want to add this word to uarray
break;
}

// this is outside of the 'j' loop so can only be executed once for each word now
if (g == 0)
{
strcpy(uArray[count], textArray[i]);
count++;
}
}
}

}```
I didn't want to do bool's so I simply made a similar type int validator.

15. I hacked together my own get_words and your program crashed on larger input files (more than 50 or 100words or so). get_Uwords is not descriptive, since U could be uppercase, or unique or any other U word. Try calling it get_unique_words. Never sacrifice clarity in the name of saving a few keystrokes. It looks like you're trying to only get unique words from textArray, but you still have a problem. For the third and final time, move the following code outside your 'j' loop:
Code:
```// this is outside of the 'j' loop so can only be executed once for each word now
if (g == 0)
{
strcpy(uArray[count], textArray[i]);
count++;
}```