سؤال

This is the code:

void main()
{   char strvek[500];

    printf("Mata in ett stort tal: ");
    scanf("%s", &strvek);

    size_t len1 = strlen(strvek);
    printf("%d",&len1);
}

The program ends up Printing the memory adress of len1. I want to store the length of the string in len1. If "hello" is entered I want to have the integer 5 for example.

هل كانت مفيدة؟

المحلول

There are thee issues with your code:

  • scanf does take addresses, but since strvek is an array, it "decays" to a pointer when passed to a function
  • Users can type more characters than your buffer holds for a buffer overflow, and
  • printf does not need an address for ints (your code has undefined behavior)

Here is how you fix the first two problem:

scanf("%499s", strvek); // Limit the size to 499 chars + '\0'; no ampersand in front of strvec

Here is how you fix the last problem:

printf("%d", len1); // No ampersand

It may be a little hard at first to remember when to use an ampersand with I/O functions. Generally, remember that scanf needs an ampersand except for strings, and printf does not need an ampersand except the %p format specifier (in which case you need to convert the pointer to void*).

نصائح أخرى

Because you are printing the address of the len1 in the output. Simply write:

printf("%d",len1);

What people have failed to mention in other answers (so far) is the reason why scanf wants you to pass addresses of values, while printf wants you to pass the values themselves.

In some sense, there's no technical reason why printf could not have been designed to take the addresses to values to print. If that were the convention, printf would simply go look up what is at that address (using the pointer dereference operator, *)...and print it.

Two things though:

  • That dereference is an "extra step" which is not needed; because just having a copy of the value itself is enough to transmit the information to printf. C likes to avoid extra steps when it can.
  • An address-based convention would prohibit using printf on literal values, which don't have addresses. You can't write printf("Value is %d", &10); and have it print Value is 10. This could be worked around by making a variable to store the value in and passing the address of the variable... but as I just said, C likes to avoid extra steps.

Yet with scanf, there is a technical reason why an address is required, and not a value. It needs to receive a place to put the data, such that the caller can look at that data later.

Think about reading in integers, for example. If you passed in an integer value of zero (instead of the address of an integer variable) and that's all scanf had to go on...how would it ever get the value it read back to you?

(In the particular example here, with an array of characters, there is a subtle issue regarding the lack of necessity of the address operator: see How come an array's address is equal to its value in C?...but ignore that and focus on the integer example for the concept. :-P)

It shall be

char strvek[500];

[...]

scanf("%s", strvek);

Even better do

scanf("%499s", strvek);

to prevent overflowing the buffer.

When scanning in a "string", that is a char array, passing to scanf() the array itself, lets the array decay to a pointer to its 1st element, which make it unnecessary to use the & (address of) operator.


To print out a size_t typed variable do:

size_t len = ...;
printf("%zu", len1);

printf("%d",&len1) prints the address while printf("%d",len1) prints the length itself. The & operator means "address of"

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top