0

I'm having problems with some codes in C:

char opt, name[10], path[25];
printf("Things\nMore things\n");
printf("Even more things\n");
printf("\nChar: ");
scanf("\n%c",&opt);
printf("\nTask name: ");
scanf("%s",name);
printf("Name: %s\n", name);
printf("\nFolder name: ");
scanf("%s",path);
printf("Name: %s\n", name);
printf("Path: %s\n", path);

This is the code that makes trouble in a "clean" mode. The problem is that, when size of data is bigger than 10 or 25, then, instead of cutting the string, it mixes "name" and "path". It has even put part of "path" into "name" in some cases. Is this undefined behaviour, or I am missing something?

3
  • Yup, writing past the end of an array is undefined behavior, as you suspect. scanf has no automatic "stop reading when the array is full". How can it when it doesn't know the size of the array? There are ways to change the format to e.g. %10s to address this, but the rules are icky. Read your friendly scanf man page! Commented May 29, 2013 at 13:13
  • PS: the newlines should be at the end of the printf strings, not at the beginning; otherwise the stdout stream may not be flushed and you'll wait for a prompt. (Or add fflush(stdout)). Commented May 29, 2013 at 13:16
  • This is very similar to other questions about overflows when using functions in the (*)scanf family, e.g., stackoverflow.com/q/16593175/1281433 . Commented May 29, 2013 at 13:18

7 Answers 7

2

If you want to limit user input to exact amount of chars, try

scanf("%24s",path);

It should prevent buffer-overloading for your char arrays.

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

1 Comment

Thank you for your solution, is not perfect, but is enough for my purpose!
2

You need to tell scanf how many bytes your input string can take. You also need to tell scanf to discard all the input up to the end of the line. Since your prompts do not end with a newline, you should flush the output.

printf("\nChar: ");
fflush(stdout);
scanf("\n%c%*[^\n] ",&opt);
printf("\nTask name: ");
fflush(stdout);
scanf(" %9[^\n]%*[^\n] ", name);
printf("\nFolder name: ");
fflush(stdout);
scanf(" %24[^\n]%*[^\n] ", path);

1 Comment

This solution works, but does strange things when pressing enter to show end of input, so I'll apply the solution posted by Pablo Lemurr, which is enough for my purpose. Thanks!
1

You are causing the buffer overrun when you try to write more than 10 chars in name and more than 25 chars in path.

In this particular case, name and path are allocated on stack and path is after name. But as stack is top down, if you write more in path you may write into space for name.

Read up on wikipedia Buffer overflow

Comments

1

If you don't want to have any problems, replace your scanf of the strings to:

fgets(name, 10, stdin);

where the second argument is the size of your array. That way even if you try to write more characters, they are ignored.

Comments

1

scanf doesn't know the size of your variables (especially with strings variable). It simply put bytes in a memory space and you have to check by yourself if there's an overflow.

There's not segfault due to the data structure alignment.

Comments

0

it simply overload the Name to Path since they occupy space in memory near each other.

Comments

0

You should specify the max size to read when using scanf to avoid buffer overrun:

scanf("%10s", name);

Comments

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.