0

I'm writing a function, which receives an empty array of pointers, the amount of words the the function should scan at most(size) (btw it can scan less than size amount of words), and the maximum length of a word(which I should ensure a word doesnt surpass).

Here is my code (I'm using C & the lines with arrows give an error):

void read_words(char* words[], int size, int max_str_len)
{
    int i=0;

    while( (i<size ) && (scanf("%s", & *words[i]) != EOF ))
    {
    
1->      if(strlen(*words[i]) > max_str_len )       
        {
2->          *words[i][max_str_len-1] = '\0';         
        }
    }
}

after getting a bunch of errors I realised that the errors come from the fact that the pointers array only points to the first char of the sequence (meaning only the first letters of the words).

(the first line arrow also gave mr the following error: error: passing argument 1 of 'strlen' makes pointer from integer without a cast)

So the question is, how can I fix it? how do I get the entire word or get to the end of it? if I change it to " *words[i] + max_str_len " does it fix the problem? but in that case I might get the value of a different variable sitting in the memory...

any help is much appreciated :)

6
  • Tip: Makes sense to do the i<size first and then scanf(). Commented Jun 7, 2021 at 16:50
  • *words[i].strlen() does not look like C. Did you mean strlen(words[i])? Commented Jun 7, 2021 at 16:51
  • '/0' certainly should be '\0'. Commented Jun 7, 2021 at 16:52
  • I assume max_str_len is (one greater than) the maximum number of characters that each word can hold. If you write more than that number into each word (which scanf will happily do), the behavior will be undefined. Attempting to truncate the string after the fact by writing a null character at the end will not avoid the problem. Commented Jun 7, 2021 at 17:13
  • 1
    An array element is accessed with array[index], not *array[index] as you're doing everywhere in your code. Commented Jun 7, 2021 at 17:32

1 Answer 1

1

You cannot just allow scanf to write arbitrarily long strings into each word, or you will overflow the buffer by writing max_str_len or more characters. Instead, you need to limit how much scanf will write with something like:

char fmt[32];
sprintf(fmt, "%%%ds", max_str_len - 1);
while( (i < size) && (scanf(fmt, words[i]) == 1) ){
   ...

In general, you should never use %s without a maximum field width as a conversion specifier in a scanf format string, since scanf can easily overflow the bounds of the array that it is writing to. If buf has N characters allocated, the format string should look like %Ms where M == N - 1 to allow space for the null terminator. In the example above, we use sprintf to generate the desired format string.

Note that if any of the strings in the input exceed the maximum length, those strings will be split into more than once word in your array. You'll need to decide how you want to deal with that situation and add the appropriate logic.

Sign up to request clarification or add additional context in comments.

6 Comments

The argument to scanf should be words[i], not words + i. There are also numerous other issues with OP's code.
@interjay Thanks for pointing that out! Edited.
thank you for your help, but in the same sense of the problem above, I'm still getting the same errors in a different function: let's say the function scanned size amount of words, and I want to write a while loop to print them all, what would the code be? I tried but it's the same problem that i had at first, each pointer in the array only point to the first letterof each word not the entire word...
That's how strings work. If you write char buf[] = "abcedfg"; char *aptr = buf; printf("%s\n", aptr), then aptr points to the a at the start of buf, and printf writes the whole string.
that's the problem , it's not printing, the program gets terminated the second it gets to the line: printf("%s \n", *words[i]);
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.