简体   繁体   中英

Dynamically allocated unknown length string reading from file (it has to be protected from reading numbers from the file) in C

My problem is such that I need to read string from file. File example:

Example 1 sentence

Example sentence number xd 595 xd 49 lol

but I have to read only the string part, not numbers. I guess I have to use fscanf() with %s for it but let me know what you guys think about it. The part where my problem begins is how to read the string (it is unknown length) using malloc() , realloc() ? I tried it by myself, but I failed (my solution is at bottom of my post). Then I need to show the result on the screen.

PS I have to use malloc()/calloc() , realloc() <-- it has to be dynamically allocated string:) ( char * )

Code I've tried:

    int wordSize = 2;
    char *word = (char *)malloc(wordSize*sizeof(char));
    char ch;

    FILE* InputWords = NULL;
    InputWords = fopen(ListOfWords,"r"); /* variable ListOfWords contains name of the file */

    if (InputWords == NULL)
    {
      printf("Error while opening the file.\n");
      return 0;
    }

    int index = 0;
    while((ch = fgetc(InputWords)) != -1)
    {
      if(ch == ' ')
      {
        printf("%s\n", word);
        wordSize = 2;
        index = 0;
        free(word);
        char* word = (char *)malloc(wordSize*sizeof(char));
      }
      else
      {
        wordSize++;
        word = (char *)realloc(word, wordSize*sizeof(char));
        strcpy(word,ch);
        index++;
      }
    }
  fclose(InputWords);

For your code, you have something have to improve:

  1. fgetc return the int type not char . So change char ch to int ch ;
  2. As the comment of @pmg use EOF (may be any negative value) instead of -1`
  3. strcpy(word,ch); you try to copy character ( ch ) to character pointer ( word ).
  4. Do not cast malloc or realloc function: Do I cast the result of malloc? .

For solving your question, i propose you use the strtok function to split string by space character, then test each word is number or not. If the word is not a number, you can use strcat to concatenate the word to the old sentence.

The complete code:

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

int is_number(char *str) {
    if (strlen(str) == 0)
       return -1;
    for(int i =0; (i < strlen(str)) && (str[i] != '\n') ; i++) {
        if(!isdigit(str[i]))
            return -1;
    }
    return 1;
}

int main()
{
    FILE *fp = fopen("input.txt", "r");
    char line[256];

    if(!fp) return -1;
    char **sentence;
    int i = 0;
    sentence = malloc(sizeof(char *));
    if(!sentence) return -1;
    while(fgets(line, 256, fp)) {
        char * token = strtok(line, " ");
        size_t len = 0;
        sentence = realloc(sentence, sizeof(char *) * (i+1));
        if(!sentence) return -1;
        while(token != NULL) {
            if (is_number(token) != 1) {

                sentence[i] = realloc(sentence[i], len + 2 + strlen(token)); // +2 because 1 for null character and 1 for space character
                if (!sentence[i]) {
                    printf("cannot realloc\n");
                    return -1;
                }
                strcat(strcat(sentence[i], " "), token);
                len = strlen(sentence[i]);
            }
            token = strtok(NULL, " ");
        }
        if(len > 0)
           i++;
    }

    for(int j = 0; j < i; j++) {
        printf("line[%d]: %s", j, sentence[j]);
    }

    for(int j = 0; j < i; j++) {
        free(sentence[j]);
    }
    free(sentence);
    fclose(fp);
    return 0;
}

The input and output:

$cat input.txt
Example 1 sentence
Example sentence number xd 595 xd 49 lol

./test

line[0]:  Example sentence                                                                                                                                  
line[1]:  Example sentence number xd xd lol

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM