Do we need check SIZE in for loop?

Hello,

Can I remove i < SIZE ? I think string1[i] != '\0' is enough condition. because absolutely string size isn't more than 20


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include <stdio.h>
#define SIZE 20

int main(void) {
   char string1[SIZE] = ""; 
   char string2[] = "string literal"; 

   printf("%s", "Enter a string (no longer than 19 characters): ");
   scanf("%19s", string1); 


   printf("string1 is: %s\nstring2 is: %s\n", string1, string2);
   puts("string1 with spaces between characters is:");     

   
   for (size_t i = 0; i < SIZE && string1[i] != '\0'; ++i) {
      printf("%c ", string1[i]);                            
   }                                                        

   puts("");
} 
What happens when you remove SIZE (as well as &&) from the for loop?
@George P
Thank you for your reply, In this example, nothing because scanf cannot get more than 19 characters.
Your entered string will always contain a terminating '\0', regardless of the overall defined size of the string.

You could strlen the size of string1 and loop on that value instead.

FYI, C11 introduced scanf_s to prevent potential buffer overruns.
https://en.cppreference.com/w/c/io/fscanf

I know that MSVC complains mightily about using scanf, recommending using scanf_s

line 9 rewritten for scanf_s is scanf_s("%19s", string1, SIZE);
FYI, C11 introduced scanf_s to prevent potential buffer overruns.

But remember that those "safe" functions are optional, not all compilers implement them.


I know that MSVC complains mightily about using scanf, recommending using scanf_s

What exactly do those warnings say with the current compiler?

Edit: Also note that not all of the C standard functions are implemented in MSVC and some of those MSVC functions have different function signatures than the standard functions.

See: https://docs.microsoft.com/en-us/cpp/overview/visual-cpp-language-conformance?view=msvc-170#note_O
Last edited on
The warning is an error:
Error  C4996  'scanf': This function or variable may be unsafe. Consider using scanf_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.

consider, if C allows it, char string1[SIZE] = {0};
so that all the letters are zeroed. Then if you do something that leaves off the end of string zero it was already there.
Note O is very specific about different function signatures, scanf_s is not one that differs with MS implementation vs. C11.

scanf_s uses the same signature regardless of the compiler, if it is available.

The safe functions shouldn't be optional IMO. If they are in the standard they should be required to be implemented.
When dealing with null-terminated c-style strings, it is common to use pointer:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include <stdio.h>
#define SIZE 20

int main(void) {
	char string1[SIZE] = {};
	char string2[] = "string literal";
	char form[7] = {};

	printf("Enter a string (no longer than %i characters): ", SIZE - 1);
	snprintf(form, sizeof(form), "%%%is", SIZE - 1);
	scanf(form, string1);

	printf("string1 is: %s\nstring2 is: %s\n", string1, string2);
	puts("string1 with spaces between characters is:");

	for (char* s = string1; *s; ++s)
		printf("%c ", *s);

	putchar('\n');
}


note also that the format used for scanf is now set to the size used for string1
@seeplus, creating a format string on the fly is what I was grasping for, unable to catch it at the moment. Bypassing the need for safe functions.

I am not as knowledgeable in C compared to C++, so a lot of the more bullet-proof ways to do things I don't know.

Thanks for the tip. :)

I still believe if the C standard includes the safe functions they shouldn't be optional for implementation.

Using them is a whole 'nother topic.
I still believe if the C standard includes the safe functions they shouldn't be optional for implementation.

Well everyone has their own opinions.

Since the "safe" functions are only part of Annex K and not part of the general standard the standards body must have had a reason to add Annex K and not add them to the general standard.

IMO, Annex K was a compromise to try to bring MSVC into actually supporting modern standard C. At the time MSVC only truly supported parts of C90.

With printf() etc, you can use * for a format width to get a width value from the specified args, but you can't do this with scanf() as * means skip an input.
Last edited on
Topic archived. No new replies allowed.