-1

At the end of this question you will find a piece of code that I am trying to write to read a file called words.txt with the following strings:

uno dos tres cuatro cinco seis siete ocho nueve diez

The aim of the code is to be able to store the strings in a two-dimensional array with dynamic memory allocation. This means it would need to work with any file that has strings.

I would need to check:

  • Why the code is not working.
  • How can I make it so that it stores whatever number of words the file has.

Thank you very much guys!

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

int main()
{

char c, *mystring[20];
int i = 0;
FILE *fich;

setlocale(LC_CTYPE,"spanish");
identifica();
    
fich = fopen("words.txt", "r");

do
{
    mystring[i] = malloc (20 * sizeof(char));
    fscanf("%s", mystring[i]);
    printf ("%s", mystring[i]);
}
while ((c=fgetc(fich))!=EOF);

return 0;
}
Henry
  • 697
  • 1
  • 6
  • 16
  • What are the problems ***you*** have with the code you show? What are your own thoughts on it? Please take some time to refresh [the help pages](http://stackoverflow.com/help), take the SO [tour], read [ask], as well as [this question checklist](https://codeblog.jonskeet.uk/2012/11/24/stack-overflow-question-checklist/). – Some programmer dude Jun 22 '20 at 19:02

1 Answers1

1
  • You forgot to pass fich to fscanf(). (This is why your code won't work)
  • Checking if fscanf() is successful should be performed.
  • You can use realloc() for dynamic re-allocation.
  • You should increment i for storeing all strings.
  • Maximum length of string to read should be specified to avoid buffer overrun.

Try this:

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

int main()
{

    char **mystring = NULL;
    int i = 0;
    FILE *fich;

    setlocale(LC_CTYPE,"spanish");
    identifica();
        
    fich = fopen("words.txt", "r");

    for (;;)
    {
        char* next = malloc (20 * sizeof(char));
        if (fscanf(fich, "%19s", next) == 1)
        {
            printf ("%s", next);
            mystring = realloc(mystring, sizeof(*mystring) * (i + 1));
            mystring[i] = next;
            i++;
        }
        else
        {
            free(next);
            break;
        }
    }

    return 0;
}
MikeCAT
  • 73,922
  • 11
  • 45
  • 70
  • Good use of `sizeof(*mystring)`. Recommend similar use in `next = malloc (20 * sizeof(char))` like `next = malloc(sizeof *next * 20)` – chux - Reinstate Monica Jun 22 '20 at 19:05
  • `next = malloc (20 * sizeof(char))` can be just `next = malloc (20)` because `sizeof(char)` must be 1, according to the specification. – MikeCAT Jun 22 '20 at 19:07
  • True about `malloc (20)` for this learner code. Coding `malloc(sizeof *next * 20)` does provide reduced code maintenance as code later perhaps evolves to `whar_t *`. – chux - Reinstate Monica Jun 22 '20 at 19:11
  • thank you very much for this @MikeCAT!! :-) Just a couple of questions: what is the meaning of `for (;;)`? Also, why do you use malloc like this: `char* next = malloc (20 * sizeof(char));` instead of like this: `next = (char*) malloc (20 * sizeof(char));`? Thank you!! – Henry Jun 22 '20 at 19:32
  • `for (;;)` means an infinite loop (until it is broken by `break`, `return`, etc). For the 2nd question, read this: [c - Do I cast the result of malloc? - Stack Overflow](https://stackoverflow.com/questions/605845/do-i-cast-the-result-of-malloc) – MikeCAT Jun 22 '20 at 19:34
  • Thank you, @MikeCAT! Really appreciate it! For the `Malloc` question, I will read it more thoroughly, but using my currently limited knowledge, I guess it is just better practice to do what you just did :D : `char* next = malloc (20 * sizeof(char));` – Henry Jun 22 '20 at 19:40