Dappa jack
Dappa jack

Reputation: 145

how to read each word in a string from a textfile

My code is as shown below:

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

int main()
{
    FILE *fp = fopen("text.txt", "r");
    char c;
    int d = 0;
    char arr[2000];

    do {
        c = fgetc(fp);
        d = d + 1;

        if (c == '\n') {
            arr[d] = ' ';
        } else
            arr[d] = c;
    } while (c != EOF);

    int z = strlen(arr);
    arr[0]= '\0';

    for (int i = 0;i < z; i++) {
        arr[i] = arr[i +1];
    }

    fclose(fp);

    return 0;
}

the code reads a string from a textfile and ands them to an array arr[2000](there are a lot of words in the text file). I wanted to ask if anybody knows a way for the code to read the textfile by each word separated by a space not by character.

So for example if i had an array arr with string : "Jack is a boy"

arr[0] would equal "Jack" not "J"

p.s(The reason for the for loop at the end that removes index 0 is because i keep getting a "(" character at the beginning of the array)

any help would be much appreciated.

Upvotes: 0

Views: 508

Answers (3)

David C. Rankin
David C. Rankin

Reputation: 84551

There are three additional subtle issues you will want to look at:

int c = 0;  /* note: 'c' should be 'int' */

While char will work for normal characters, you will run into problems if you attempt to read a file containing multi-byte characters.

When you open a file with fopen, you need to check that the file is really open before you attempt to read from it. A simple test is all that is required:

if (!fp) {  /* validate file open succeeded */
    fprintf (stderr, "error: file open failed 'text.txt'.\n");
    return 1;
}

(note: if (!fp) is just shorthand for if (fp == NULL))

The next is the way you read c, assign it to array, and then test if c = EOF. What gets added to the array when c is EOF?

You need to test whether c = EOF before you assign c to arr and not assign it in the case of EOF (which is -1 generally). A quick change to your loop will work:

/* test c before you add it to the array */
while ((c = fgetc (fp)) != EOF)
{
    if (c == '\n') {
        arr[d++] = ' ';
    } else
        arr[d++] = c;
}
arr[d] = 0; /* null-terminate, note '\0' = 0 */

Upvotes: 2

R Sahu
R Sahu

Reputation: 206577

You said:

So for example if i had an array arr with string : "Jack is a boy"

arr[0] would equal "Jack" not "J"

To do that, arr[0] needs to be a pointer to a null terminated string. That means, arr has to be an array of pointers, not an array of chars.

char* arr[SOME_SIZE] = {0}; // Make SOME_SIZE large enough for your needs.

Now you have to figure out where to store the characters that you read from the file. You can use the method used in Easiest way to get file's contents in C to read the entire contents of the file. Assuming you got the code to read the contents of the file, let's you have:

char* fileContents = readFileContents("text.txt");

and now, fileContents points to an array that looks like:

+---+---+---+---+---+---+---+---+---+---+---+---+---+----+
| J | a | c | k |   | i | s |   | a |   | b | o | y | \0 |
+---+---+---+---+---+---+---+---+---+---+---+---+---+----+

Now, you'll need to traverse that array and make sure that:

  1. arr[0] - arr[3] point to the right locations in the array.
  2. The whitespace characters are replace by the null character so that arr[0] - arr[3] point to a null terminated string.
arr[0]              arr[1]       arr[2]   arr[3]
|                    |            |        |
v                    v            v        v
+---+---+---+---+----+---+---+----+---+----+---+---+---+----+
| J | a | c | k | \0 | i | s | \0 | a | \0 | b | o | y | \0 |
+---+---+---+---+----+---+---+----+---+-- -+---+---+---+----+

I hope that gives you enough information to implement the functionality you need.

Upvotes: 7

You get your extra character at the start because you start filling your array at arr[1].

Furthermore, you can make life even easier by using the fread function: size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream); to read in a whole block of text at once. You can then separate it into words at your leisure.

Now if you also want to have an array "containing" all the separate words, you should look into an array of pointers to char, or char *array[100] (for an appropriate size of course). C doesn't handle strings automatically (as you seem to expect from the last bit of your question "arr[0] would equal "Jack" not "J"".

Upvotes: 4

Related Questions