Preventing buffer corruption of inputted array of char - c

I want to ask how to prevent a corruption in the array buffer, This is my code.
#include <stdio.h>
#define buffSize 20
void clrscr() {
for(int i = 0; i < 25; ++i)
putchar('\n');
}
int main() {
char arr1[buffSize];
char arr2[buffSize];
do {
clrscr();
printf("String 1 :\n");
scanf("%[^\n]", &arr1); fflush(stdin);//prompt first string
} while(strlen(arr1) > buffSize);
do {
clrscr();
printf("String 1: %s\n\n", arr1);//The problem is here
printf("String 2 : ");
scanf("%[^\n]", &arr2); fflush(stdin);
} while(strlen(arr2) > buffSize);
return 0;
}
Say that we have inputted the first arr of char correspondingly to the buffSize, then we input the second arr of char which has inputs that exceeds the limitation of the buffSize. The arr1 will be assigned with some of the characters that was inputted above the arr2 size. How to prevent this ?

fflush(stdin) is undefined behavior, it is generally only defined for output streams.
Try this instead :
while ((c = getchar()) != '\n' && c != EOF);
If you are trying to limit the number of characters that scanf() attempts to read, you can use :
scanf("%19[^\n]", arr2);
Note that the number specified in scanf() must be one less than your buffer size to save room for '\0' and it should be arr1 and arr2, no &. Array names are already pointers to the beginning of the array.

Related

How to check the length of input char array (%s) using scanf() in C

I need to check the length of an input using the function scanf().
I'm using an array of char (%s) to store the input, but I wasn't able to check the length of this input.
this below is the code:
#include <stdio.h>
char chr[] = "";
int n;
void main()
{
printf("\n");
printf("Enter a character: ");
scanf("%s",chr);
printf("You entered %s.", chr);
printf("\n");
n = sizeof(chr);
printf("length n = %d \n", n);
printf("\n");
}
it's giving me back that "length n = 1" for the output in each case I've tried.
How can I check the length of the input in this case?
Thank You.
to check the length of input char array (%s) using scanf()
Do not use the raw "%s", use a width limit: 1 less than buffer size.
Use an adequate sized buffer. char chr[] = ""; is only 1 char.
Use strlen() to determine string length when the input does not read null characters.
char chr[100];
if (scanf("%99s", chr) == 1) {
printf("Length: %zu\n", strlen(chr));
}
Pedantic: Use "%n" to store the offset of the scan if code might read null characters (this is rarely or nefariously encountered).
char chr[100];
int n1, n2;
if (scanf(" %n%99s%n", &n1, chr, &n2) == 1) {
printf("Length: %d\n", n2 - n1);
}
sizeof is a compile time unary operator which can be used to compute the size of its operand.if you want to calculate the length of the string the you have to use strlen().like this
#include <stdio.h>
#include <string.h>
int main()
{
char Str[1000];
printf("Enter the String: ");
if(scanf("%999s", Str) == 1) // limit the number of chars to sizeof Str - 1
{ // and == 1 to check that scanning 1 item worked
printf("Length of Str is %zu", strlen(Str));
}
return 0;
}

why does the statements inside loop condition execute when condition is false in c programming?

I am just running a code to find the length of a given string input by the user in C programming language. I used a loop condition to determine the length but statements inside loop executes when the condition is false also. The code I have tried in c is:
#include <stdio.h>
#define ArrayLength 50
int StringLengthCount();
int main() {
printf("Hello, World!\n");
/*Question: Find inserted string's length, without build in function*/
int c=StringLengthCount();
printf("Your inserted string's length is:%d",c);
return 0;
}
int StringLengthCount(){
printf("\n");
printf("Please enter a sentence to find its length of character:");
char array1[ArrayLength];
fgets(array1,ArrayLength,stdin);
printf("Your inserted string is:%s\n",array1);
int i=0;
int count=0;
while(array1[i]!='\0'){
count++;
printf("%d character is %c",count,array1[i]);
printf("\n");
i++;
}
printf("\n");
printf("Your inserted string's total character i.e string length is:%d",count);
}
I am expecting the result 2 for a sample string input "we", but it gives result 3.
The output result in CLion compiler is given below
enter image description here
Can you kindly tell me why it happens?
If by "statements inside loop executes when the condition is false also" you mean that you see an extra character every time you execute remember that also the line feed (LF alias \n) character that you use to enter your string is part of the acquired string.
So even the empty string has one character that is \n or 0x10.
Your check should be something like this:
while (array1[len] != '\0' && array1[len] != '\n' )
And you function, as suggested in the comments, should have a return and could use just one variable like this:
int StringLengthCount() {
printf("\n");
printf("Please enter a sentence to find its length of character:");
char array1[ArrayLength];
fgets(array1, ArrayLength, stdin);
printf("Your inserted string is:%s\n", array1);
int len = 0;
while (array1[len] != '\0' && array1[len] != '\n' ) {
printf("%d character is %c", len + 1, array1[len]);
printf("\n");
len++;
}
printf("\n");
printf("Your inserted string's total character i.e string length is:%d\n\n",
len);
return len;
}
The function fgets will also read the newline character, so you need to change the condition in the while-loop from str[i] != '\0' to str[i] != '\n'. I have also implemented the suggested changes by Devolus.
#include <stdio.h>
#include <stdlib.h>
#define LEN 50
void string_length();
int main(void)
{
string_length();
return EXIT_SUCCESS;
}
void string_length(void)
{
printf("Enter a string: ");
char str[LEN];
fgets(str, LEN - 1, stdin);
printf("Your entered string is: %s\n", str);
int i = 0;
while (str[i] != '\n') {
printf("The %d. character is '%c'.\n", i + 1, str[i]);
++i;
}
printf("\nThe string's length is %d.\n", i);
}

The size of a string

#include <stdio.h>
int stringLength (char *text)
{
int count = 0;
while (*text != '\0')
{
count++;
text++;
}
return count;
}
int main()
{
char str[25];
int length;
printf("ENter string: ");
scanf("%s", &str);
length = stringLength(str);
if (length > 25)
{
printf("Invalid\n");
printf("Enter string: ");
scanf("%s", &str);
}
printf("Your string is: %s and its %d long", str, length);
return 0;
}
If the first input is wrong (over 25) it will remember that number (length) and when I input another string it will add the numbers together. How do I fix it so it goes from beginning? So it counts the next string from start?
You can't in this way. Your code has at least two problems:
You don't have to use the & when you pass a string to scanf, because str is already a pointer (search the equivalence pointer and array in C).
If you insert more than 25 what is happening is a buffer overflow and your program presents an undefined behavior after the scanf. You may want to consider a different and safer approach to read from keyboard (e.g. fgets)
char str[25];
Can only contain a string of 24 char + NULL. Use a width specifier to limit input to 1 less than buffer size when scanning strings into scanf().
Replace the if() branch with a while() loop:
length = stringLength(str);
while(length > 24)// an array of 25 elements can only accommodate 24 characters + NULL
{
printf("Invalid\n");
printf("Enter string: ");
//use input limiter of 24 for char str[25];
scanf("%24s", str);//remove & (for all scanf scanning a string)
length = stringLength(str);
}

How do I read the number of characters from a input in C?

I am trying to read the number of characters including, the spaces.
I use the scanf function to check for chars using %c. Also on a side note, how would I go about storing the input into an array?
#include <stdio.h>
int main(void) {
char n, count= 0;
while (scanf("%c", &n) != EOF) {
count = count+1;
}
printf("%d characters in your input \n", count);
return 0;
}
When I test input (with spaces) such as
abcdefg
it doesn't print anything.
Defining a MAX_CHAR and checking that in loop would protect you against invalid memory write.
Remember that last byte of an array should be left for '\0', if you want to print or use the char array.
#include <stdio.h>
#define MAX_CHAR 100
int main(void) {
char n[MAX_CHAR]={0}, count= 0;
while((count!=MAX_CHAR-1)&&(scanf("%c",&n[count])==1))
{
if((n[count]=='\n')){
n[count]=0;
break;
}
count++;
}
printf("%d characters in your input [%s]\n", count, n);
return 0;
}
scanf does return EOF when it reaches the end of the file. But in order for you to see that happening, you should give your program a file input when you call it like this:
./a.out < input.txt
Inside input.txt you could put any text you want. But if you want to work in the command line, you should read until you find a \n
#include <stdio.h>
int main(void) {
char n, count = 0;
scanf("%c", &n);
while (n != '\n') {
count = count+1;
scanf("%c", &n);
}
printf("%d characters in your input \n", count);
return 0;
}
If you want to store the input in an array, you must know the size of the input (or at least the maximum size possible)
#include <stdio.h>
int main(void) {
char n, count = 0;
char input[100]; //the max input size, in this case, is 100
scanf("%c", &n);
while (n != '\n') {
scanf("%c", &n);
input[count] = n; //using count as the index before incrementing
count = count+1;
}
printf("%d characters in your input \n", count);
return 0;
}
Furthermore, if don't know the size or max size of the input, you'd have to dynamically change the size of the input array. But I think that would be a little advanced for you right now.
Your printf doesn't print anything because runtime doesn't reach to it. Your code looping for ever in while loop
while (scanf("%c", &n) != EOF) {
count = count+1;
}
because scanf won't return EOF in this case

How to limit input length with scanf

In this program I have taken a dimensional character array of size[3][4],
as long as I enter a 3 characters for each row it will work well.
For example: if I enter abc abd abd I get the same output but if i enter more letters in the first or second or 3rd row I get an error.
How should I check for null character in 2 dimensional?
# include <stdio.h>
#include <conio.h>
# include <ctype.h>
void main()
{
int i=0;
char name[3][4];
printf("\n enter the names \n");
for(i=0;i<3;i++)
{
scanf( "%s",name[i]);
}
printf( "you entered these names\n");
for(i=0;i<3;i++)
{
printf( "%s\n",name[i]);
}
getch();
}
As pointed out by #SouravGhosh, you can limit your scanf with "%3s", but the problem is still there if you don't flush stdin on each iteration.
You can do this:
printf("\n enter the names \n");
for(i = 0; i < 3; i++) {
int c;
scanf("%3s", name[i]);
while ((c = fgetc(stdin)) != '\n' && c != EOF); /* Flush stdin */
}
How should I chk for null character in 2 dimensional ... [something has eaten the rest part, I guess]
You don't need to, at least not in current context.
The problem is in your approach of allocating memory and putting input into it. Your code has
char name[3][4];
if you enter more that three chars, you'll be overwriting the boundary of allocated memory [considering the space of \0]. You've to limit your scanf() using
scanf("%3s",name[i]);
Note:
change void main() to int main(). add a return 0 at the end.
always check the return value of scanf() to ensure proper input.
EDIT:
As for the logical part, you need to eat up the remainings of the input words to start scanning from the beginning of the next word.
Check the below code [Under Linux, so removed conio.h and getch()]
# include <stdio.h>
# include <ctype.h>
int main()
{
int i=0; char name[3][4];
int c = 0;
printf("\n enter the names \n");
for(i=0;i < 3;i++)
{
scanf( "%3s",name[i]);
while(1) // loop to eat up the rest of unwanted input
{ // upto a ' ' or `\n` or `EOF`, whichever is earlier
c = getchar();
if (c == ' ' || c == '\n' || c == EOF) break;
}
}
printf( "you entered these names\n");
for(i=0;i<3;i++)
{
printf( "%s\n",name[i]);
}
return 0;
}
(Cringing after reading the answers to date.)
First, state the problem clearly. You want to read a line from stdin, and extract three short whitespace separated strings. The stored strings are NUL terminated and at most three characters (excluding the NUL).
#include <stdio.h>
void main(int, char**) {
char name[3][4];
printf("\n enter the names \n");
{
// Read tbe line of input text.
char line[80];
if (0 == fgets(line, sizeof(line), stdin)) {
printf("Nothing read!\n");
return 1;
}
int n_line = strlen(line);
if ('\n' != line[n_line - 1]) {
printf("Input too long!\n");
return 2;
}
// Parse out the three values.
int v = sscanf(line, "%3s %3s %3s", name[0], name[1], name[2]);
if (3 != v) {
printf("Too few values!\n");
return 3;
}
}
// We now have the three values, with errors checked.
printf("you entered these names\n%s\n%s\n%s\n",
name[0], name[1], name[2]
);
return 0;
}
you might consider something on the order of scanf( "%3s%*s",name[i]);
which should, if I recall correctly, take the first three characters (up to a whitespace) into name, and then ignore anything else up to the next white space. This will cover your long entries and it does not care what the white space is.
This is not a perfect answer as it will probably eat the middle entry of A B C if single or double character entries are mode. strtok, will separate a line into useful bits and you can then take substrings of the bits into your name[] fields.
Perhaps figuring out the entire requirement before writing code would be the first step in the process.

Resources