I can not use scanf to enter a name in stdnames array.
when compiled it had no error , but as soon as i enter a name and
then press enter to write the other name it gives an error and shuts the program.
How should I go about it ?
int main(int argc, char* argv[])
{
float marks[50];
/*char *stdnames[100]={"Arvind Thillainathan","Robert Lang"};*/
//I want to stores names like the above one
char *stdnames[100];
int totalNames = 0;
int i = 0, w=0,h=0;
printf("How many names do you want to enter ??\n");
scanf("%d",&totalNames);
assert(totalNames != 0);
for(int count = 0; count < totalNames; count++)
{
printf("Enter name of student\n");
scanf("%s",stdnames[count]);
//From here the problem starts
}
getres(marks,totalNames);
for(i = 0; i < totalNames; i++)
{
int v = 1;
printf("\n");
printf("IELTS Marks of %s\n\n",stdnames[i]);
for(h = w; h < w+5; h++)
{
if(v==1)
{
printf("Listening : %0.1f\n", marks[h]);
}
else if(v==2)
{
printf("Reading : %0.1f\n", marks[h]);
}
else if(v==3)
{
printf("Writing : %0.1f\n", marks[h]);
}
else if(v==4)
{
printf("Speaking : %0.1f\n", marks[h]);
}
else
{
printf("Overall : %0.1f\n\n", marks[h]);
}
v++;
//if(h==10)
//{
// break;
//}
}
w+=5;
}
return 0;
}
By
char *stdnames[100];
you got an array of (pointers to char).
The NEXT BIG QUESTION is
Who will allocate memory for each of these pointers?
A small answer would be - You have to do it yourself like below :
stdnames[count]=malloc(100*sizeof(char)); // You may replace 100 with desired size
or
stdnames[count]=malloc(100); // sizeof(char) is almost always 1
You need to put this line before the scanf statement.
Note: Don't forget to free the allocated memory once these variables become irrelevant. Do it like :
free(stdnames[count]);
Related
I have created a password checker in c programming but it is not working can anyone please check it and say what is wrong in this.
#include<stdio.h>
#include<stdbool.h>
int main() {
int otp[4]; //array for storing the true password entered by user at first
int pto[4]; //array for storing password for login
int count = 4,i;
bool pass = true;
printf("enter a new password: ");
for (int i = 0; i < count; i++) {
scanf("%d", & otp[i]); //for storing the true password
}
printf("\n\n --- Login page --- ");
printf("\nenter your password : ");
for (i = 0; i < count; i++) {
scanf(" %d", & pto[i]); //asking for password for login
}
for (i = 0; i < count; i++) { //check for password
if (otp[i] == pto[i]) {
pass = true;
} else {
pass = false;
}
}
while (pass == false) { //if password is wrong
printf("\n---- password din't match ----\nenter your password again : ");
for (i = 0; i < count; i++) {
scanf(" %d", & pto[i]);
}
for (i = 0; i < count; i++) {
if (otp[i] == pto[i]) {
pass = true;
} else {
pass = false;
}
}
}
printf("\n Your password is correct!");
return 0;
}
And should I use int or char to store passwords,if i use int also that part works if char also it works but sometimes it wont work,
This loop ultimately only cares if the last value in each array match or not.
for (i = 0; i < count; i++) {
if (otp[i] == pto[i]) {
pass = true;
} else {
pass = false;
}
}
For example, comparing { 1, 2, 3, 4 } and { 4, 4, 4, 4 } would result in pass being true after the loop, despite the obvious differences.
Instead, set the flag to false, and break from your loop as soon as a mismatch occurs.
bool matching = true;
for (size_t i = 0; i < length; i++) {
if (array_one[i] != array_two[i]) {
matching = false;
break;
}
}
If a mismatch never occurs, the flag will remain true afterwards.
Usually passwords are text that is hashed (with a salt) before being stored. Password verification is done by comparing hashes. For example, take a look at the man 3 crypt library function.
The use of a fixed-length series of plain integers for a 'password' is atypical, but for a toy program it is fine.
Here is an example program to study.
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#define KEY_LENGTH 4
void get_key(int *key, size_t length) {
for (size_t i = 0; i < length; i++) {
if (1 != scanf("%d", &key[i])) {
fprintf(stderr, "Could not read integer input.\n");
exit(EXIT_FAILURE);
}
}
}
bool match_key(int *one, int *two, size_t length) {
for (size_t i = 0; i < length; i++)
if (one[i] != two[i])
return false;
return true;
}
int main(void) {
int key[KEY_LENGTH];
int user_key[KEY_LENGTH];
printf("Set the key (%d integers): ", KEY_LENGTH);
get_key(key, KEY_LENGTH);
puts("--- LOGIN ---");
while (1) {
printf("Enter the key (%d integers): ", KEY_LENGTH);
get_key(user_key, KEY_LENGTH);
if (match_key(key, user_key, KEY_LENGTH))
break;
puts("Key mismatch. Retrying...");
}
puts("Welcome to the system.");
}
Since you didn’t specify your problem (besides “it’s not working”), I’ll do my best to list all the possible issues.
Reading integers
scanf("%d", & otp[i]);
Will read a single decimal integer into a position in otp. If the password is 1024, the first time through the loop (iteration) will read 1024 into otp[0]. In the second iteration, scanf() will wait until another number is available on standard input. Once it’s available, it will read it into otp[1], and so on. This scanf() loop really reads in 4 different integers, separated by newlines. It would be much easier to do only one scanf() for one integer, like this:
int main() {
int otp;
int pto;
bool pass = true;
printf("enter a new password: ");
scanf("%d", &otp);
You could also scan a 4-character string by using char arrays:
int main() {
char otp[5]; //4 digits and 1 NUL-terminator
char pto[5];
bool pass = true;
printf("enter a new password: ");
scanf("%4s", otp);
Password-checking logic error
As #Oka explained, your checker has a logic error. If using an integer, you could simply check
if (opt == pto) {
//correct
} else {
//incorrect
}
If using a char array (string), you could use
if (!strcmp(otp, pto)) {
//correct
} else {
//incorrect
}
You would have to #include <string.h> for strcmp().
Standard output buffer
The “enter a new password: ” prompt is not printed until the stdout buffer is flushed. This usually only happens when a newline is printed. You have to
fflush(stdout);
right after printing the prompt if you want it to appear.
My professor asked me to make a Codebreaker game in C. (User is breaking the code by guessing original code. original code is given as a cmd-line arg.After every attempt;(b, w): the number of correct colors in the correct positions (b) and the number of colors that are part of the code but not in the correct positions (w) are printed as Feedback.)Only standard input and output is allowed. I got it working, but the arrays Secret_Code2 and guess2 goes out of bounds. It has some strange behaviours like changing int variables causes changes in arrays even they are independent. I'm aware that C does not check array bounds, is there any improvements that i can make?
Here is my code;
#include <stdio.h>
#define Max_Attempts 12
char *Sectret_CODE = NULL;
int main(int argc,char **argv)
{
//Definitions
printf("Available Colors: (B)lue (G)reen (O)range (P)urple (R)ed (Y)ellow\n\n");
//Getting input and validating
if(argc != 2)
{
fprintf(stderr,"Invalid input\n");
return 1;
}
Sectret_CODE = argv[1];
int i = Max_Attempts;
int Won = 0;
while (i > 0 && !Won)
{
int b = 0, w = 0, t=0;
char guess[4];
char Sectret_CODE2[4];
char guess2[4];
printf("No. guesses left: %i\n",i);
printf("Enter Your Guess: ");
scanf("%s",guess);
//printf("%s",guess);
for(int j = 0; j < 4; j++)
{
//printf("%s,%s\n",Sectret_CODE2,guess2);
if(Sectret_CODE[j] == guess[j])
{
b++;
}
else
{
Sectret_CODE2[t] = Sectret_CODE[j];
guess2[t] = guess[j];
t++;
printf("%s,%s,%i\n",Sectret_CODE2,guess2,t);
}
}
int s = t;
//printf("%i",t);
Sectret_CODE2[t] = '\0' ;
guess2[t] = '\0' ;
if(b == 4)
{
printf("You Won\n");
Won = 1;
return 0;
}
else
{
for(int j = 0; j < s; j++)
{
for(int k = 0; k < s;k++)
if(Sectret_CODE2[j] == guess2[k])
{
w++;
break;
}
}
}
printf("Feedback: %i,%i\n",b,w);
i--;
}
if(!Won)
{
printf("You Lose!\n");
}
}
You aren't allocating space for the terminating null character in your character arrays. Each array needs to hold up to 4 values, plus a terminating null character. So you need to declare them to hold 4+1 = 5 characters. Otherwise writing the null character can write past the end of the arrays.
Also, inside your loop, you are attempting to print those arrays using printf with %s before null-terminating them. You need to null-terminate them, at the proper point, before printing them with %s.
I made a program that asks the user to enter a name if they select option 2 and it stores that name in the string, if the user selects option 3 then it will display that name. Now for option 4 it needs to alphabetize the names in order, so when i select option 3 again to view the names it would show them in alphabetical order. My friend told me to use strcpy(), and i attempted it but not too successfully.
This is my code:
//This is my code:
#include<stdio.h>
#include<string.h>
int main() {
int i = 0;
int j = 0;
while (1) {
int num;
char name[500][100],t[100];
printf("\nPress 1 to see author info\n");
printf("Press 2 to enter a name\n");
printf("Press 3 to view names\n");
printf("Press 4 to alphabatize names\n");
scanf("%d", &num);
char arr[100];
if (num == 1)
{
printf("----------------\n");
printf("name\n");
printf("132\n");
printf("----------------\n");
}
if (num == 2)
{
printf("Enter the name (no spaces)\n");
scanf("%s", arr);
strcpy(name[i], arr);
i++;
}
if (num == 3)
{
printf("\n******************************");
for (int j = 0; j<i; j++)
{
printf("\n%s\n", &name[j]);
}
printf("\n\n\n******************************");
}
if (num == 4)
{
for (i = 1; i < j; i++) {
for (j = 1; j < i; j++) {
if (strcmp(name[j - 1], name[j]) > 0) {
strcpy(t, name[j - 1]);
strcpy(name[j - 1], name[j]);
strcpy(name[j], t);
}
}
}
;
}
return(0)
system("pause");
}
If Barmar doesn't want to make the comment an answer:
As noted: the i you use in the outer loop is the total, you cannot use it, you need a fresh one, say k. Sorted alphabetically gives:
int k;
if (num == 4) {
for (j = 0; j < i; j++) {
for (k = 0; k < i - j - 1; k++) {
if (strcmp(name[k], name[k + 1]) > 0) {
strcpy(t, name[k]);
strcpy(name[k], name[k+1]);
strcpy(name[k+1], t);
}
}
}
}
I used a slightly different approach for the bubble sort, that's how I learned it, hope you can make sense of it.
Note: copying the full strings is not the best way to do it but I don't know if you already learned about pointers.
Modified your code. It seems that for this situation, switch case would be prettier and that your loop will never end. With what #Barmar said, your loop has a return 0; therefore terminates prematurely. I have changed some elements of your codes too as some of them are suited to be undisturbed etc. etc.
Change List
Besides the implementation of switch case
Name and position of char arrays. For t[100], since it is a temporary object/variable I moved it into case (4) (Refer to line 63
in the modified code) so that the creation happens on demand instead
of the original code where creation is made early. Renamed t to temp.
As for arr, I've renamed it so that it is clearer (nameIn to indicate
name Input)
Name of num. To make it easier to understand the code, I've set it to nameCount, to indicate the number of name, or the size.
Restructured loops so that their counters do not modifiy nameCount by any means and only use it as a mean of comparison.
Added exit condition for the loop to terminate, -1 as well as a default case should invalid input is provided. (Does not check for
alphabet input)
Modified Code
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
int main()
{
int nameCount = 0, num = 0;
while (num != -1)
{
char nameIn[100];
char name[100][100];
printf("\nPress 1 to see author info\n");
printf("Press 2 to enter a name\n");
printf("Press 3 to view names\n");
printf("Press 4 to alphabatize names\n");
scanf("%d", &num);
switch(num)
{
case (1):
{
printf("----------------\n");
printf("name\n");
printf("132\n");
printf("----------------\n");
break;
}
case (2):
{
printf("Enter the name (no spaces)\n");
scanf("%s", nameIn);
strcpy(name[nameCount], nameIn);
nameCount++;
break;
}
case (3):
{
printf("\n******************************");
for (int ctr = 0; ctr<nameCount; ctr++)
{
printf("\n%s\n", &name[ctr]);
}
printf("\n\n\n******************************");
break;
}
case (4):
{
for (int ctrLv1 = 0; ctrLv1 < nameCount-1; ctrLv1++)
{
printf("\nhere here");
for (int ctrLv2 = ctrLv1+1; ctrLv2 < nameCount; ctrLv2++)
{
printf("\nif fail?\n\n\n");
if (strcmp(name[ctrLv1], name[ctrLv2]) > 0)
{
char temp[100] = "";
strcpy(temp, name[ctrLv1]);
strcpy(name[ctrLv1], name[ctrLv2]);
strcpy(name[ctrLv2], temp);
}
}
}
break;
}
case (-1):
{
printf("\nExiting...\n");
break;
}
default:
{
printf("Invalid input");
break;
}
}
}
return(0);
}
i want to write code in c language to delete any character in string s1 which matches any character in the string s2 . using only for loops. that is my trial has failed -_- .
for example if s1="ahmed" and s2="omnia" should edit s1 to >> s1="hed"
#include <stdio.h>
#include <stdlib.h>
int i,j;
int k;
int counter=0;
int main()
{
char s1[100];
char s2[10];
char temp[100];
printf("\n enter string 1: ");
scanf("%s",s1);
printf("\n enter string 2: ");
scanf("%s",s2);
printf("\n%s",s1);
printf("\n%s",s2);
for(j=0;j<9;j++)
{
for(i=0;i<9;i++)
{
if(s1[i]!=s2[j]&&s1[i]!='\0')
{
temp[counter++]=s1[i]; //add unique items to temp
k=counter; //size
temp[counter]='\0';
}
}
}
for(i=0;i<k;i++)
{
s1[i]=temp[i];
}
printf("\nstring 1 after delete : ");
printf("%s",s1);
return 0;
}
how can i compare one item with nested items then achieve a condition ??
Why are you including the null character statements inside the if statement?
Try these two statements after the two for loops, like this. And please indent your code.
for(j=0;j<strlen(s1);j++) //Why is it 9 in your code? It should be the respective lengths
{
for(i=0;i<strlen(s2);i++)
{
if(s1[i]!=s2[j]&&s1[i]!='\0')
{
temp[counter++]=s1[i];
}
}
}
k=counter;
temp[counter]='\0';
and include:#include<string.h>
I don't see any coding errors here, only your logic is flawed.
This should work
for (j = 0; j < 9; j++)
{
for (i = 0; i < 9; i++)
{
if (s1[j] == s2[i] && s1[i] != '\0')
{
break;
}
else if (i == strlen(s2))
{
temp[counter++] = s1[j];
}
}
}
temp[counter] = '\0';
for (i = 0; i < counter; i++)
{
s1[i] = temp[i];
}
printf("\nstring 1 after delete : ");
printf("%s", s1);
In your original code you kept reading the original string from the beginning, instead of advancing the iterator each time.
So in the first iteration you compared 'ahmed' against 'omnia' which is fine.
In the second iteration though, you compared 'ahmed' against 'omnia', instead of 'hmed' against 'omnia', and that's why you got a large repetition of the original string in your output.
Also, I'd memset the memory of s1 and s2 first to 0.
This has stumped me for a few days now. I have tried searching but have turned up mostly just definitions for struct...
In an if loop I set 2 struct variables, but neither of them come out correct. guests[x].plusone is stuck at 0 and guests[x].plusonefood is simply empty. If I set them (with the same line) outside of the loop, however, there are no issues. My compiler shows no warnings or errors. What am I missing?
This is my first project with C, so please point out anything else you notice, too.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct guestinfo
{
char name[50];
short int plusone;
char food[50];
char plusonefood[50];
};
char temp[5];
char setfood (int f)
{
char foodtemp[f];
int x;
for (x=0; x < f; x++)
{
printf("Food option %d:\n", (x+1));
fgets(&foodtemp[x],100,stdin);
}
return *foodtemp;
}
int main ()
{
int number_of_rsvp=0;
int number_of_food=0;
printf("Number of food choices:\n");
fgets(temp,5,stdin);
number_of_food = atoi (temp);
while (number_of_food <= 0)
{
printf("Please enter a number greater than 0\n");
fgets(temp,5,stdin);
number_of_food = atoi (temp);
}
char food [50] [number_of_food];
**food = setfood(number_of_food);
printf("Number of RSVPs:\n");
fgets(temp,5,stdin);
number_of_rsvp = atoi (temp);
while (number_of_rsvp <= 0)
{
printf("\nPlease enter a number greater than 0\n");
fgets(temp,5,stdin);
number_of_rsvp = atoi (temp);
};
struct guestinfo guests[number_of_rsvp];
int x;
int f;
for (x=0; x < number_of_rsvp; x++)
{
// add input validation to this section
printf("Guest Number %d:\n\nGuest Name:\n", (x+1));
fgets(guests[x].name,50,stdin);
printf("Food Choice #:\n");
fgets(temp,3,stdin);
f = atoi(temp);
f--;
*guests[x].food = food [50] [f];
printf("Plus One? Y/N\n");
fgets(temp,3,stdin);
}
if (strchr (temp,'Y') != NULL || strchr (temp,'y') != NULL) //This loop
{
guests[x].plusone = 1;
printf("Plus one food choice #:\n");
fgets(temp,3,stdin);
f = atoi(temp);
f--;
*guests[x].plusonefood = food [50] [f];
}
else if (strchr (temp,'N') != NULL || strchr (temp,'n') != NULL)
{
guests[x].plusone = 0;
};
FILE *guestlist = fopen ("guestlist.txt","w");
// debugging
printf("%d\n",guests[0].plusone);
printf("%s\n",guests[0].plusonefood);
for (x=0; x < number_of_rsvp; x++)
{
fprintf(guestlist,"Guest Number %d:\n\nName: %s\nFood Choice: %s\n",(x+1),guests[x].name,guests[x].food);
switch (guests[x].plusone)
{
case 1:
{
fprintf(guestlist,"Plus One: Yes\n\tPlus One Food: %s\n\n",guests[x].plusonefood);
break;
}
case 0:
{
fprintf(guestlist,"Plus One: No\n\n");
break;
}
default:
{
break;
}
}
}
fclose (guestlist);
printf("Printing Guest List...\n");
return 0;
}
The problem is that you are accessing an invalid memory place.
The array has number_of_rsvp elements.
Your for() loop interates over the variable x up to the value number_of_rsvp and exits.
After that, the value of x is equal to number_of_rsvp.
Since the index of the array only can go from 0 to number_of_rsvp - 1, the element guests[x], which is guests[number_of_rsvp], is out-of-bound.