Nick
Nick

Reputation: 213

Truncating a string while storing it in an array in c

I am trying to create an array of 20 character strings with a maximum of 17 characters that are obtained from a file named "words.dat". After that the program should truncate the string only showing the first 17 characters and completely ignore the rest of that string. However

My question is: I am not quite sure how to accomplish this, can anyone give me some insight on how to accomplish this task?

Here is my current code as is:

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

    #define WORDS 20
    #define LENGTH 18

    char  function1(char[WORDS][LENGTH]);

int main( void )
{

    char word_array [WORDS] [LENGTH]; 

    function1(word_array);

    return ( 0 ) ;

}

char function1(char word_array[WORDS][LENGTH])
{
    FILE *wordsfile = fopen("words.dat", "r");
    int i = 0;

    if (wordsfile == NULL)
        printf("\nwords.dat was not properly opened.\n");
    else
    {
        for (i = 0; i < WORDS; i++)
        {
            fscanf(wordsfile, "%17s", word_array[i]);
            printf ("%s \n", word_array[i]);
        }
        fclose(wordsfile);
    }
    return (word_array[WORDS][LENGTH]);
}

words.dat file:

Ninja
 DragonsFury
  failninja
   dragonsrage
    leagueoflegendssurfgthyjnu
     white
      black
       red
        green
         yellow
          green
           leagueoflegendssughjkuj
            dragonsfury
             Sword
              sodas
               tiger
                snakes
                 Swords
                  Snakes
                   sage

Sample output:

blahblah@fang:~>a.out
Ninja 
DragonsFury 
failninja 
dragonsrage 
leagueoflegendssu 
rfgthyjnu 
white 
black 
red 
green 
yellow 
green 
leagueoflegendssu 
ghjkuj 
dragonsfury 
Sword 
sodas 
tiger 
snakes 
Swords 
blahblah@fang:~>

What will be accomplished afterwards with this program is:

After function1 works properly I will then create a second function name "function2" that will look throughout the array for matching pairs of words that match "EXACTLY" including case . After I will create a third function that displays the 20 character strings from the words.dat file that I previously created and the matching words.

Upvotes: 1

Views: 771

Answers (2)

zubergu
zubergu

Reputation: 3706

In your loop change

fscanf(wordsfile, "%17s", word_array[i]);

to

fscanf(wordsfile, "% 17s%*[^\n]\n", word_array[i]);

What it basically does is:

  1. %17s, this is obvious, reads max 17 characters and puts it in your word_array
  2. %*[^\n], this reads all characters that are not \n and drops them (*)
  3. \n reads the new line character

I tested it by replacing this one line in your code and worked fine.

As others mentioned, look at returning value from your call to function1. It's basically word_array[20][18], which is twice off the array limits. It's 19th character of 21st element of word_array. And you have none of them. This function would work the same way if it didn't return any value.

Upvotes: 2

paddy
paddy

Reputation: 63471

A few things to note. First, I suggest you have function1 return a count of how many words were read, rather than the character at word_array[WORDS][LENGTH] which is at a memory location you don't have access to. So change the function to return an int:

int function1(char word_array[WORDS][LENGTH])

To handle the possibility that the file might contain less than WORDS words, you need to know when fscanf fails, and when it does, break from the loop.

if( 1 != fscanf(wordsfile, "%17s", word_array[i]) ) break;

To ignore the remainder of words longer than 17 characters, you can just read one at a time until you encounter a whitespace character or EOF.

int c;
do { c = fgetc(wordsFile); } while( c != EOF && !isspace(c) );

Putting it all together:

int function1(char word_array[WORDS][LENGTH])
{
    FILE *wordsfile = fopen("words.dat", "r");
    int c, i = 0;

    if (wordsfile == NULL)
    {
        printf("\nwords.dat was not properly opened.\n");
    }
    else
    {
        for (i = 0; i < WORDS; i++)
        {
            if( 1 != fscanf(wordsfile, "%17s", word_array[i]) ) break;

            /* eat remaining characters of long words */
            do { c = fgetc(wordsFile); } while( c != EOF && !isspace(c) );
        }
        fclose(wordsfile);
    }

    /* Return the number of words read */
    return i;
}

Upvotes: 1

Related Questions