How to set the character limit on C - c

I want my user to enter the input which I have set only for each and every declaration, but when I tried running the program it still proceeds, for example, name the ic_size the limit character is only 12 character input, but if I put more than 12 it just accepts it as nothing wrong. Here's the coding I tried:
void login_register()
{
const name_size = 80;
char name[name_size];
const ic_size = 12;
char ic[ic_size];
const no_size = 12;
char no[no_size];
const nationality_size = 20;
char nationality[nationality_size];
const email_size = 50;
char email[email_size];
int select;
int Day =0;
int bed_tax =0;
double RM;
double room_price=0;
double service_tax = 0;
double total = 0;
char term,check;
printf("\n Please enter your name : ");
while(gets(name))/* same as scanf ("%s",name) %s mean print the corresponding argument in string*/
{
if(!isalpha && sizeof(name) > name_size) // restrict user input can only be alphabeth and must not exceed array size
{
printf("\n Please enter a valid input");
}
else
{
break;
}
}
printf(" Please enter your IC number : ");
while(gets(ic))
{
if(isdigit && sizeof(ic) < ic_size) // restrict user input can only be numerical and must not excedd array size
{
printf("\n Please enter a valid input");
}
else
{
break;
}
}
printf(" Please enter your phone number : ");
while(gets(no))
{
if(isdigit && sizeof(no) < no_size)
{
printf("\n Please enter a valid input");
}
else
{
break;
}
}
printf(" Please enter your nationality : ");
while(gets(nationality))/* same as scanf ("%s",nationality) %s mean print the corresponding argument in string*/
{
if(!isalpha && sizeof(nationality) > nationality_size) // restrict user input can only be alphabeth and must not exceed array size
{
printf("\n Please enter a valid input");
}
else
{
break;
}
}
printf(" Please enter your email : ");
while(gets(email))/* same as scanf ("%s",email) %s mean print the corresponding argument in string*/
{
if(!isalpha && sizeof(email) > email_size) // restrict user input can only be alphabeth and must not exceed array size
{
printf("\n Please enter a valid input");
}
else
{
break;
}
}

Rather than gets(), which has no limit on user input, consider fgets().
Shift design goal to:
Allow unlimited input per line, but only save up to N characters of input.
Let user know if too much entered. Try again if needed.
I recommend a helper function that prompts, reads input, and handles long lines.
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
// 'size' is the size of the array 'destination' points to.
int get_user_input(const char *prompt, size_t size, char *destination) {
char buf[size + 2]; // size + \n + 1 extra
do {
fputs(prompt, stdout);
if (fgets(buf, sizeof buf, stdin) == NULL) {
*destination = '\0';
return 0; // End of file
}
char *end_of_line = strchr(buf, '\n');
if (end_of_line) {
*end_of_line = '\0'; // Lop off \n
} else {
// get rest of line
scanf("%*[^\n]"); // Read everything up to a \n and toss
scanf("%*1[\n]"); // Read a \n and toss
}
} while (strlen(buf) >= size);
strcpy(destination, buf);
return 1;
}
Now read as needed. Recall that name_size = 12 means up to 11 characters are saved as 1 more is needed to save the null character. Adjust name_size as needed.
int main(void) {
const int name_size = 12;
char name[name_size];
const int nationality_size = 20;
char nationality[nationality_size];
get_user_input("Please enter your name: ", sizeof name, name);
printf("Name <%s>\n", name);
get_user_input("Please enter your nationality: ", sizeof nationality, nationality);
printf("Nationality <%s>\n", nationality);
}

Related

How can i make a code in C that asks the user to create a password with at least 3 characters and one uppercase letter properly?

So I'm very new to programming and i have to make a code that asks the user their firs name and last name, and then to create a password with at least 3 characters and one uppercase letter and I'm very lost, my code has many issues and i don't think it makes a whole lot of sense, here it is:
#include <stdio.h>
#include <string.h>
int main()
{
char name[20], last_name[20];
printf("Please, enter your name and last name:\n");
printf("Name: ");
scanf("%s", name);
printf("Last name: ");
scanf("%s", last_name);
char userInput[64];
char pass = 0;
char password[25];
int i;
int x;
size_t length = 0;
while( pass == 0 ) {
length = 0;
pass = 0;
printf("\nPlease, create a password:\n ");
fgets(userInput, 63, stdin);
length = strlen(userInput);
if( length < 4) {
printf("The password must have at least 3 characters\n");
continue;
}
scanf(" %s", password);
for (i = 0; i < 25; i++) {
if (isupper(password[i])) {
break;
}
else if (password[i] == '\0') {
printf("\nPlease, enter at least one uppercase letter\n");
break;
}
}
}
return 0;
}
the "Please, enter your name and last name" repeats itself the first time it appears and i don't know why, and when the password doesn't have an uppercase it doesn't ask the user to create a new password, how can i fix any of this?
any help is much appreciated

How do I reallocate a array of structures in a function

I am trying to allocate a dynamic array of Country objects for my school project. I have malloc'd the array in main() function and I am reallocating it in a add_country() function. but it seems to give me realloc invalid ponter error. Could someone help? This is the minimal reproducable code.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int count = 0;
typedef struct test_Country
{
char name[20];
int gold;
int silver;
int bronze;
} test_Country;
test_Country *addtest_Country(test_Country test_Country_obj, test_Country*array)
{
int flag = 0;
printf("%s\n", "before realloc");
test_Country *new_array;
new_array = realloc(array, sizeof(test_Country *) * (count + 1));
printf("%s\n", "after realloc");
//array[count].name = (char *)malloc(strlen(test_Country_obj.name) + 1);
if (count == 0)
{
strcpy(new_array[0].name, test_Country_obj.name);
}
else
{
for (int i = 0; i < count; i++)
{
if (strcasecmp(new_array[i].name, test_Country_obj.name) == 0)
{
printf("%s", "test_Country already added\n");
flag = 1;
break;
}
}
}
if (flag == 0)
{
strcpy(new_array[count].name, test_Country_obj.name);
test_Country_obj.gold = 0;
test_Country_obj.silver = 0;
test_Country_obj.bronze = 0;
new_array[count] = test_Country_obj;
count = count + 1;
}
flag = 0;
return new_array;
}
int main()
{
char choice;
test_Country *array = malloc(sizeof(test_Country));
test_Country test_Country_obj;
printf("%s", "Enter your choice : ");
scanf("%s", &choice);
//fgets(ptr, 80, stdin);
//sscanf(ptr, "%c %s %d %d %d", &choice, test_Country_obj.name, &test_Country_obj.gold, &test_Country_obj.silver, &test_Country_obj.bronze);
//printf("%s", &choice);
while (choice != 'E')
{
printf("%s", "Enter test_Country name : ");
scanf("%s", test_Country_obj.name);
array = addtest_Country(test_Country_obj, array);
//printf("%d%s", count, "is count");
printf("%s", "Enter your choice : ");
scanf("%s", &choice);
}
}
I cant seem to understand what is wrong.
char choice;
scanf("%s", &choice);
is bad. choice has only room for one character, so it can hold only strings upto zero characters. (the one-character room is for terminating null-character). Trying to store strings longer than zero character leads to dangerous out-of-range write and it may destroy data around that.
To avoid out-of-range write, you should allocate enough elements and specify the maximum length to read. The maximum length should be the buffer size minus one for terminating null-character.
char choice[16]; /* allocate enough elements */
scanf("%15s", choice); /* specify the maximum length */
After that, choice in the while and switch should be replaced with choice[0] to judge by the first character. Another way is using strcmp() to check the whole string.

taking string with spaces does not work in my function

I want to my function take input string with any spaces. But my taking input line is not working somehow and prints 1 without taking my input. I even tried fgets and gets function to avoid this but result is the same. Can anyone help me? Line 16 is taking input part.
double setup_tree(char object[20], char parentobject[20]) {
double total;
int i;
double val;
char input[100];
char answer[101];
char names[20][20];
int numcounts[20];
int objectnumber;
if (parentobject[0] == ' ') {
printf("Define %s\n", object);
} else {
printf("Define %s in %s\n", object, parentobject);
}
scanf("%[^\n]%*c", input);
printf("1");
remove_more_than_one_space(answer, input);
objectnumber = define_typeof_description(answer);
if (objectnumber == 0) {
//printf("0lalol ");
sscanf(answer, "%lf", total);
return total;
}
total = 0;
parse_the_answer(answer, names, numcounts, objectnumber);
printf("1lalol");
for (i = 0; i < objectnumber; i++) {
val = setup_tree(names[i], object);
total += (numcounts[i]) * val;
}
return total;
}
Your problem most probably comes from scanf() reading a pending newline left in stdin by a previous call to scanf().
You can avoid this with scanf(" %[^\n]%*c", input);
Also note that you should protect against invalid input with scanf(" %99[^\n]%*c", input);

Newbie here. C function problem during execution

Edit: Since I understand that I need to provide more info to make it clear for you guys, I added the main function and the getchoice and also two images of the program running. My problem is that after entering the endword, I want to see the menu first and then make a choice, whereas it prompts me to give an input without showing the menu.
This function is part of a bigger program, but this is where a problem occurs.
It reads words inputed, places them into an array, until the keyword ****END is entered. However, when this keyword is entered, it doesn't go immediatelly in the specified if clause (you will see that in the code). I'm a newbie and it could be something really obvious, but any help is greatly appreciated.
#include <string.h>
#define M 50
#define N 15
void getText(char a[M][N])
{
int i, j;
char temp[N];
for (i = 0; i < 50; i++) {
for (j = 0; j < 15; j++) {
if (i == 49 && j == 14) {
printf("Maximum length of text reached.\n");
}
scanf("%s\n", temp);
if (strcmp(temp, "****END") == 0) {
printf("You entered the endkey.\n");
return;
}
strcpy(a[i], temp);
}
}
}
int main(){
int input;
while(1){
input = getChoice();
if(input == 1){
getText(text);
}
else if(input == 2){
getDictionary();
}
else if(input == 3){
correctText();
}
else if(input == 4){
saveText();
}
else if(input == 5){
getStats();
}
else if(input == 6){
break;
}
}
return 0;
}
int getChoice(){
int temp;
printf("Choose function:\n1: Enter text\n2: Enter dictionary\n3: Correct text\n4: Save text\n5: Get text statistics\n6: Exit program\n");
scanf("%d", &temp);
return temp;
}
Entered the endword and now it waits for input instead of showing the menu.
I inputed 2 for the second program function, then it showed the menu and proceeded to function 2.
Apart from the unnecessary double-nested loop, this line
scanf("%s\n", temp);
should be
scanf("%s", temp);
Usually, you should not try to match trailing whitespace with scanf, and the format specifier %s automatically filters out leading whitespace (but note that %c does not).
There are other faults and the code presented was originally incomplete, but notably the input length for %s must be restricted to prevent buffer overflow.
#include <stddef.h> // size_t
#include <ctype.h> // isspace()
#include <stdio.h> // scanf(), puts()
#include <string.h> // strcmp()
// see https://stackoverflow.com/questions/2653214/stringification-of-a-macro-value
#define STRINGIFY(x) #x
#define STRING(x) STRINGIFY(x)
#define LINES 50
#define COLS 15
char const *end = "****END";
// throw away everything until a newline is found
void clear(FILE *stream)
{
int ch;
while ((ch = getc(stream)) != EOF && ch != '\n');
}
size_t getText(char dst[LINES][COLS + 1])
{
size_t i = 0;
for (; i < LINES; i++) {
char temp[COLS + 1] = { 0 };
scanf("%" STRING(COLS) "s", temp); // "%15s" at runtime.
int ch;
// if the next character is not whitespace ...
if ((ch = getchar()) != EOF && !isspace(ch)) {
puts("Warning: Input too long, was truncated!");
clear(stdin);
}
if (strcmp(temp, end) == 0) {
puts("You entered the endkey.");
return i;
}
strcpy(dst[i], temp);
}
return i;
}
int main(void)
{
// COLS + 1 ... we need space for the terminating newline character.
char foo[LINES][COLS + 1];
size_t n = getText(foo);
for (size_t i = 0; i < n; ++i)
puts(foo[i]);
}
The %s conversion specifier should never be used without specifying a width to limit the characters that get stored:
char foo[10];
scanf("%9s");

Validating User Input String

Here's part of the description of the assignment: The program must stop
accepting input when the user enters the word done. Assume that no word is
more than 20 letters long.
I have to validate that if a word is more than 20 characters thy will get an error message and have to retype again. Also when I type done, the program should end. Im not sure how to write these statements correctly. When I run it and type more then 20 characters it gives me an error - Expression: L("Buffer is too small" &&0)
Here's my Code so far:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAXCHAR 20
int charcount(char []);
int main()
{
char message[MAXCHAR];
int numofchar;
printf("Enter any word to display how many characters that word has.\nA word CANNOT be more than 20 charatcers long.\n");
printf("When you are finished type the word done.\n");
do
{
printf("\nEnter a word: " );
gets_s(message, MAXCHAR);
numofchar = charcount(message);
while ( numofchar > MAXCHAR)
{
printf("The word enterd is more then 20 characters. Try again.\n");
printf("Enter a word: " );
gets_s(message, MAXCHAR);
}
printf("The word %s has %d characters.\n", (message),numofchar);
} while ( (message,MAXCHAR) != 'done');
printf("\nEnd of program.\n");
system ("PAUSE");
return 0;
}
int charcount (char list[])
{
int i, count = 0;
for(i = 0; list[i] != '\0'; i++)
count++;
return(count);
}
To detect an error, you simply need to check the return value of get_s:
http://msdn.microsoft.com/en-us/library/5b5x9wc7%28v=vs.90%29.aspx
int main()
{
char message[MAXCHAR], *s;
int numofchar;
...
do
{
printf("\nEnter a word: " );
s = gets_s(message, MAXCHAR);
if (!s) {
<< some error handling code goes here >>
...

Resources