user4332856
user4332856

Reputation:

how to make a char into one word in C

I am currently collecting input from a file but my program separates each letter into the char array instead of each word. How can I change my code to get each word?

char c, fileName[20];
FILE *f;

void getFile() {    
    f = fopen(fileName, "r");

    while((c = fgetc(f)) != EOF) {
        printf("%c",c);
    }
    fclose(f);
}

Upvotes: 1

Views: 3160

Answers (4)

user3121023
user3121023

Reputation: 8286

You can use a scanset with fscanf or sscanf. This scanset, %29[a-zA-Z], reads lower and upper case English characters and stops when it encounters a character not in the set. The 29 limits the maximum number of characters to read so as to not overwrite the buffer, word[30]. When fscanf fails, the else will read one character from the file and give fscanf another try at reading another word.
This also uses the command line to pass in the file to read as argv[1].

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

int main( int argc, char *argv[])
{
    char word[30] = {'\0'};
    int ch = 0;
    FILE *pf = NULL;

    if ( argc != 2) {//command requires program name and a file name
        printf ( "useage: program filename\n");
        return 1;
    }

    if ( ( pf = fopen ( argv[1], "r")) == NULL) {
        perror ( "could not open file");
        return 1;
    }

    while ( 1) {
        if ( ( fscanf ( pf, "%29[a-zA-Z]", word)) == 1) {
            printf ( "%s\n", word);
        }
        else {
            if ( ( ch = fgetc ( pf)) == EOF) {//read one character and check for end of file
                break;
            }
            //could do something here with the value of ch if needed
        }
    }
    printf ( "--DONE--\n");

    return 0;
}

This will allocate an array for each word. As words are added the array is expanded using realloc.

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

int main( int argc, char *argv[])
{
    char **words = NULL;//pointer for words
    char **temp = NULL;
    char word[30] = {'\0'};
    int ch = 0;
    int each = 0;
    int found = 0;
    int count = 0;
    int wordsize = 0;
    FILE *pf = NULL;

    if ( argc != 2) {//command requires program name and a file name
        printf ( "useage: program filename\n");
        return 1;
    }

    if ( ( pf = fopen ( argv[1], "r")) == NULL) {
        perror ( "could not open file");
        return 1;
    }

    while ( 1) {
        if ( ( fscanf ( pf, "%29[a-zA-Z]", word)) == 1) {
            found = 0;
            for ( each = 0; each < wordsize; each++) {
                if ( strcmp ( words[each], word) == 0) {
                    found = 1;
                    break;
                }
            }
            if ( found == 0) {
                wordsize += 1;// increment number of words
                temp = realloc ( words, wordsize * sizeof ( char *));//reallocate for another word
                if ( temp != NULL) {
                    words = temp;
                    words[wordsize - 1] = malloc ( strlen ( word) + 1);//malloc for the word itself
                    if ( words[wordsize - 1] != NULL) {
                        strcpy ( words[wordsize - 1], word);
                    }
                    else {
                        printf ( "malloc failed\n");
                        wordsize -= 1;
                        break;
                    }
                }
                else {
                    printf ( "realloc failed\n");
                    wordsize -= 1;
                    break;
                }
            }
            printf ( "%s\n", word);
        }
        else {
            if ( ( ch = fgetc ( pf)) == EOF) {//read one character and check for end of file
                break;
            }
            //something could be done with ch if needed
        }
    }
    printf ( "--DONE Reading file--\n");
    for ( each = 0; each < wordsize; each++) {// print each word
        printf ( "%s\n", words[each]);
    }
    count = 0;
    printf ( "Enter a word to search for\n");
    if ( ( scanf ( "%29[a-zA-Z]", word)) == 1) {
        for ( each = 0; each < wordsize; each++) {
            if ( strcmp ( words[each], word) == 0) {
                printf ( "Found %s at index %d\n" word, each);
                count++;
            }
        }
        printf ( "Found %s %d times\n" word, count);
    }
    for ( each = 0; each < wordsize; each++) {//release memory
        free ( words[each]);
    }
    free ( words);


    return 0;
}

Upvotes: 1

Iharob Al Asimi
Iharob Al Asimi

Reputation: 53016

  1. First problem fgetc() returns an int you cannot store EOF in a char variable.
  2. You should check if fopen() didn't return NULL.

You can use this technique to read words like this

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

#define MAX_BUFFER_SIZE 256

char **load_words_from_file(const char *filename)
{
    size_t wordcount;
    size_t charcount;
    char   buffer[MAX_BUFFER_SIZE];
    int    chr;
    FILE  *file;
    char **words;
    void  *pointer;

    file = fopen(filename, "r");
    if (file == NULL)
        return NULL;
    wordcount = 0;
    charcount = 0;
    words     = NULL;
    while ((chr = fgetc(file)) != EOF)
    {
        /* it's a white space or it exceeded buffer size, it's a word delimiter */
        if ((isspace(chr) != 0) || (charcount >= sizeof(buffer) - 1))
        {
            /* 'nul' terminate 'buffer' for strcpy() and strlen() */
            buffer[charcount] = '\0';
            pointer           = realloc(words, (1 + wordcount) * sizeof(char *));
            if (pointer == NULL) /* failure, free allocated memory and return NULL */
                goto failure;
            words            = pointer;
            words[wordcount] = malloc(1 + charcount);
            charcount        = 0; /* reset character count */
            if (words[wordcount] == NULL)
                goto failure;
            strcpy(words[wordcount], buffer);

            wordcount += 1;
        }
        else
        {
            /* store the character and count it */
            buffer[charcount] = (char)chr;
            charcount        += 1;
        }
    }
    pointer = realloc(words, (1 + wordcount) * sizeof(char *));
    if (pointer == NULL)
        goto failure;
    words            = pointer;
    words[wordcount] = NULL; /* this will let you know when to stop fetching words */

    fclose(file);
    return words;
failure:
    for (size_t i = 0 ; i < wordcount ; ++i)
        free(words[i]);
    free(words);
    return NULL;
}

int
main()
{
    const char *filename = "your-file-name-here";
    char      **words    = load_words_from_file(filename);
    size_t      counter  = 0;

    if (words == NULL)
    {
        printf("no words found in the file\n");
        return -1;
    }
    while (words[counter] != NULL)
    {
        printf("%zuth word: %s\n", 1 + counter, words[counter]);
        free(words[counter]); /* this program will not use it again */
        counter += 1;
    }
    free(words);
    return 0;
}

the strtok() method would also work, but it's harder to understand.

Note the use of goto, it's a benign usage, although some people think that goto is always harmful, that's not true, using it like this makes the program adhere to the DRY priniciple.

Upvotes: 0

Jurica Penjgušić
Jurica Penjgušić

Reputation: 100

You could use char * fgets ( char * str, int num, FILE * stream ); Then use char *strtok(char *str, const char *delim) for example

#include <stdio.h>

 int main()
{
 FILE * pFile;
 char mystring [100];
 const char delimters[2] = " ,:";
 char *token;

 pFile = fopen ("myfile.txt" , "r");
 if (pFile == NULL) perror ("Error opening file");
 else {
   if ( fgets (mystring , 100 , pFile) != NULL )

    /* get the first token */
     token = strtok(mystring, delimiters);

  /* walk through other tokens */
  while( token != NULL ) 
 {
    printf( " %s\n", token );

  token = strtok(NULL, delimiters);
 }

   fclose (pFile);
  }
 return 0;
}

Upvotes: 1

user590028
user590028

Reputation: 11728

Use fscanf(3) instead

char word[256], *p;
while(fscanf(f, "%s", &word) != EOF) {
     printf("%s\n", word);
     /* break down word into individual chars */
     for(p=word; *p; p++) {
         printf("%c ", *p);
         }
     printf("\n");
     }

Upvotes: 0

Related Questions