1

Im doing this exercise that requires to read a string and print out the length of each word. Thing is supposedly we arent supposed to know how many words this sting has.

In this case for example its 4

viVa la VIDA loca

This is the part of the code i have made.

int textStats(char* filename);

int main()
{
    FILE*file;
    file=fopen("file","r");
    if(file==NULL)
    {
        printf("Error in opening the file ");
        exit(1);
    }
    textStats(file);
}

int textStats(char* filename)
{
    int i,j;

    int n=0;
    int N=20;
    char str[N];


    while(fscanf(filename,"%c",&str[n])!=EOF)
    {
        n++;
    }
    for(i=0; i<n; i++)
    {
        printf("%c",str[i]);
    }
    
    i=j=0;
    int count[]={0};
    while(str[i]!='\0')
    {
        if(isalpha(tolower(str[i])))
        {
            count[j]++;
        }
        if(isspace(str[i])|| str[i]=='\0')
        {
            j++;
        }
        i++;
    }

    for(i=0;i<j;i++)
    {
        printf("word %d with count %d\n",i+1,count[i]);
    }
}

What i dont understand why is it that if i initialize count[]={0} it will print errors but if i initialize it to count[]={0,0,0,0} it will return a correct value?

ndim
  • 35,870
  • 12
  • 47
  • 57
Severjan Lici
  • 371
  • 1
  • 10
  • Your code shouldn't even build. What do you think `fscanf(filename, ...)` will do? Why do you pass a string as argument? – Some programmer dude Sep 10 '22 at 11:51
  • `int count[]={0};` -> the size of `count` array is `1`. Either specify the array dimension explicitly or provide as many initialiser in `{}` to ensure that the array will have enough number of elements. – H.S. Sep 10 '22 at 11:52
  • As for your question, C doesn't have "vectors" or dynamic arrays. If you don't know the size of an array you need to use pointers and dynamic allocation and reallocation. – Some programmer dude Sep 10 '22 at 11:52
  • @Someprogrammerdude some other stuff that i omitted from the code here. – Severjan Lici Sep 10 '22 at 11:53
  • 1
    A very important point of a [mre] is that it demonstrates the problem you ask about, and *only* the problem you ask about. Any other errors will be distracting, and make it harder to see the code you actually want us to see. – Some programmer dude Sep 10 '22 at 11:54
  • @Someprogrammerdude so then its impossible to initialize the array to 0 if i dont know its size? Aside from pointers? – Severjan Lici Sep 10 '22 at 11:54
  • 1
    That's correct, if you don't know the size beforehand, then you can't declare the array. With that said, C have [*variable-length arrays*](https://en.wikipedia.org/wiki/Variable-length_array) which means if you can calculate the length, then you can do that and then create the array using a normal variable as the size. You can't initialize the array at declaration, but you could call `memset` to set all bytes in the array to zero afterward. – Some programmer dude Sep 10 '22 at 11:56

2 Answers2

2

Firstly, you don't need to store each word's length in an array. You can just print them out whenever you finish reading 1 word

{
    FILE*file;
    file=fopen("file","r");
    if(file==NULL)
    {
        printf("Error in opening the file ");
        exit(1);
    }
    textStats(file);
}

int textStats(char* filename)
{
    int i,j;

    int n=0;
    int N=20;
    char str[N];


    while(fscanf(filename,"%c",&str[n])!=EOF)
    {
        n++;
    }
    for(i=0; i<n; i++)
    {
        printf("%c",str[i]);
    }
    
    i=j=0;
    int count=0;
    while(str[i]!='\0')
    {
        if(isalpha(tolower(str[i])))
        {
            count++;
        }
        if(isspace(str[i])|| str[i]=='\0')
        {
            j++;
            printf("word %d with count %d\n",j,count);
            count = 0;
        }
        i++;
    }
}

If you really want to store each word's length inside an array, you can explore the use of dynamically growing array

0

int count[]; is invalid, it's attempting to declare an array of incomplete size. int count[] = {0} creates an array matching the initializer list, in this case an array of 1 int items.

Lundin
  • 195,001
  • 40
  • 254
  • 396