so basically I want to create a program that asks for an username and a password in order to enter the actual program. I tried doing something like that but when I type the first username and password it doesn't let me go through. On the other hand when I type the second username and password it does work. Can someone explain me why?
#include<stdio.h>
#include<string.h>
#define MAX 100
#define LEN 40
int names(char listName[][LEN]);
void pass(char listPass[][LEN]);
int main()
{
char name[LEN];
char password[LEN];
char listName[MAX][LEN];
char listPass[MAX][LEN];
int i;
names(listName);
pass(listPass);
printf("Enter username: ");
scanf("%s", name);
printf("Enter password: ");
scanf("%s", password);
for(i = 0; i< 2; i++)
{
if (strcmp(listName[i], name) == 0 && strcmp(listPass[i], password) == 0)
{
printf("Access granted\n");
break;
}
else
{
printf("Access denied\n");
break;
}
}
getch();
}
int names(char listName[][LEN])
{
int i;
strcpy(listName[i], "Vince");
strcpy(listName[i], "Jeremy");
}
void pass(char listPass[][LEN])
{
int i;
strcpy(listPass[i], "aBc2xyz8");
strcpy(listPass[i], "fa7saC12");
}
Compile with warnings enabled and you'd see that the variable i is used uninitialized here:
int names(char listName[][LEN])
{
int i;
strcpy(listName[i], "Vince");
strcpy(listName[i], "Jeremy");
}
void pass(char listPass[][LEN])
{
int i;
strcpy(listPass[i], "aBc2xyz8");
strcpy(listPass[i], "fa7saC12");
}
What you have now is undefined behaviour, i.e. anything can happen. More likely you'd just get a random crash.
You meant strcpy(listName[0], "Vince");, strcpy(listName[1], "Jeremy");
However, what you'd really want to do is to define these variables *out of main, and initialize them there. Also, allow for varying length passwords and usernames by using an array of pointers to char. For example:
char *listName[MAX] = { "Vince", "Jeremy" };
char *listPass[MAX] = { "aBc2xyz8", "fa7saC12" };
int main(void) { ...
Or even better, use a structure for user data:
struct user_data {
char *username, *password;
};
struct user_data users[MAX] = {
{ "Vince", "aBc2xyz8" },
{ "Jeremy", "fa7saC12" }
};
In names() and pass() you use i uninitialized, both strcpy operations are going to copy to the same array index.
Following code is not what you intended:
int names(char listName[][LEN])
{
int i;
strcpy(listName[i], "Vince");
strcpy(listName[i], "Jeremy");
}
void pass(char listPass[][LEN])
{
int i;
strcpy(listPass[i], "aBc2xyz8");
strcpy(listPass[i], "fa7saC12");
}
You should initialize i and increment it between the statements, or simply use:
int names(char listName[][LEN])
{
strcpy(listName[0], "Vince");
strcpy(listName[1], "Jeremy");
}
void pass(char listPass[][LEN])
{
strcpy(listPass[0], "aBc2xyz8");
strcpy(listPass[1], "fa7saC12");
}
Related
I have been trying to compare a structure variable and a string variable. But I am getting this error.
#include<stdio.h>
#include<string.h>
int main()
{
struct details {
char number[20];
} det[10];
int inp, i=0;
char aad;
int b;
puts("Give The Number To Display The Pass Status");
scanf("%s", &aad);
for(b=0;b<i;b++)
{
if(det[i].number==aad)
{
printf("Hello");
}
}
return 0;
}
Pls try to fix my error
after you look in the comments this will be the answer
#include<stdio.h>
#include<string.h>
#define SIZE 20 // add size for aad
int main()
{
struct details {
char number[20];
} det[10];
int inp, i = 0;
char aad[SIZE]; // must be array (can be with pointer, use malloc)
int b;
puts("Give The Number To Display The Pass Status");
scanf("%s", &aad);
for (b = 0; b < i; b++)
{
if (strcmp(det[b].number, aad) == 0) // strcmp to compare strings
{
printf("Hello");
}
}
return 0;
}
I am trying to free the memory allocated by my getSongInfo function, I have tried using a pointer to the function call but I get an error "cannt assign int to type int*" error. Any help would be great as the current way I have seems like it may work, but I might be completely wrong. Thanks!
Original Attempt:
int *memPtr = NULL
memPtr = getSongInfo(&fillPtr[arrayCounter], tempArtist[counter], tempSong[counter]);
Gives error!
Current Attempt:
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#pragma warning(disable:4996)
int getSongInfo(struct songInfo *pFillInfo, char *artistName, char *songName);
void printSongInfo(struct songInfo songList[10]);
struct songInfo {
char *songArtist;
char *songTitle;
};
int main(void)
{
struct songInfo *fillPtr;
struct songInfo songList[10];
fillPtr = &songList[0];
char tempArtist[10][30];
char tempSong[10][30];
int *memPtr = NULL;
int i = 0;
int counter = 0;
int arrayCounter = 0;
while (counter != 10)
{
printf("Please enter the artist name: ");
fgets(tempArtist[counter], sizeof(tempArtist[counter]), stdin);
tempArtist[counter][strcspn(tempArtist[counter], "\n")] = 0;
printf("Please enter the song name: ");
fgets(tempSong[counter], sizeof(tempSong[counter]), stdin);
tempSong[counter][strcspn(tempSong[counter], "\n")] = 0;
getSongInfo(&fillPtr[arrayCounter], tempArtist[counter], tempSong[counter]);
printf("Song and Artist Captured! \n");
counter++;
arrayCounter++;
}
printSongInfo(fillPtr);
free(fillPtr->songArtist);
free(fillPtr->songTitle);
}
int getSongInfo(struct songInfo *pFillInfo, char *artistName, char *songName)
{
pFillInfo->songArtist = (char*)malloc(strlen(artistName) + 1);
pFillInfo->songTitle = (char*)malloc(strlen(songName) + 1);
strcpy(pFillInfo->songArtist, artistName);
strcpy(pFillInfo->songTitle, songName);
return 1;
}
void printSongInfo(struct songInfo songList[10])
{
int counter = 0;
while (counter != 10)
{
printf("%-35s %-35s\n", songList[counter].songArtist, songList[counter].songTitle);
counter++;
}
}
Your getSongInfo function does not return a pointer, so attempting to put the return value into a variable and then free it is pointless. The pointers in question are inside the struct songInfo, specifically, the fillPtr variable (which is actually redundant, since songList and fillPtr point to the same location).
In addition, please be aware that strcspn will not always return a valid index. If it does not find a match, it will return the length of the first argument.
I think this is more like what you are trying to do:
int main(void)
{
const int numSongs = 10;
struct songInfo songList[numSongs];
char tempArtist[30];
char tempSong[30];
int i;
int newline_idx;
for (i = 0; i < numSongs; ++i)
{
printf("Please enter the artist name: ");
fgets(tempArtist, sizeof(tempArtist), stdin);
newline_idx = strcspn(tempArtist, "\n");
if (newline_idx < sizeof(tempArtist))
tempArtist[newline_idx] = 0;
printf("Please enter the song name: ");
fgets(tempSong, sizeof(tempSong), stdin);
newline_idx = strcspn(tempSong, "\n");
if (newline_idx < sizeof(tempSong))
tempSong[newline_idx] = 0;
getSongInfo(&songList[i], tempArtist, tempSong);
printf("Song and Artist Captured! \n");
}
for (i = 0; i < numSongs; ++i)
{
free(songList[i].songArtist);
free(songList[i].songTitle);
}
}
You might consider separating the code for free()ing each struct into its own function.
You might also consider heeding that compiler warning instead of ignoring it, as Bodo commented. Careless handling of strings from stdin is dangerous.
i am receiving a default char array (first/last) in guest_init (and i need to initialize the values such that guest have default values ) is my following code correct? as when i run this g->first_name is always being assigned garbage. need some help.
struct guest {
char last_name[30];
char first_name[30];
};
struct auditorium_seating {
struct guest **seating;
};
void guest_init_default(struct guest *g)
{
*g->first_name = "???";
*g->last_name = "???";
}
void guest_init(struct guest *g, char *info)
{
strcpy(g->first_name, strtok(info, "/"));
strcpy(g->last_name, strtok(NULL, "\0"));
}
void auditorium_seating_init(int rowNum, int columnNum, struct auditorium_seating *a)
{
a->seating=malloc((sizeof(a->seating[rowNum][columnNum])));
char string_arr[30]="aaa/bbb";
for (int i = 0; i<rowNum; i++)
{
for (int j = 0; j<columnNum; j++)
{
//guest_init_default(a->seating);
guest_init(a->seating,string_arr);
}
}
}
auditorium_seating_init being called from main.
void main() {
struct auditorium_seating auditorium_seating;
struct guest temp_guest;
int row, col, rowNum, columnNum;
char guest_info[30];
printf("Please enter a number of rows for an auditorium seating.");
scanf_s("%d", &rowNum);
printf("Please enter a number of columns for an auditorium seating.");
scanf_s("%d", &columnNum);
auditorium_seating_init(rowNum, columnNum, &auditorium_seating);
printf("Please enter a guest information or enter \"Q\" to quit.");
}
Enable your compiler warnings: *g->first_name = "???"; is wrong.
And strtok(NULL, "\0")); is wrong too.
You probably want this:
#include <string.h>
#include <stdio.h>
struct guest {
char last_name[30];
char first_name[30];
};
void guest_init(struct guest *g, char *info)
{
strcpy(g->first_name, strtok(info, "/"));
strcpy(g->last_name, strtok(NULL, "/"));
}
int main()
{
struct guest g;
char info[] = "Foo/Bar";
guest_init(&g, info);
printf("Last Name = %s\n", g.last_name);
printf("First Name = %s\n", g.first_name);
}
There may be more errors related to struct auditorium_seating *a, but you didn't post that code.
No, you must copy data to your structure, as you allocated memory inside it.
Read compiler errors and use it to fix your program.
I have come across this wierd and mysterous (at least to me) error that I am finding a very hard time finding. It gives me an error at the line where I call my function input(student_list1[MAX], &total_entries); where the compiler says:
incompatible type for agument 1 in 'input'
What am I doing wrong here? I sense it something very simple and stupid but I have gone through the code several times now without any avail.
#define MAX 10
#define NAME_LEN 15
struct person {
char name[NAME_LEN+1];
int age;
};
void input(struct person student_list1[MAX], int *total_entries);
int main(void)
{
struct person student_list1[MAX];
int total_entries=0, i;
input(student_list1[MAX], &total_entries);
for(i=0; i<total_entries; i++)
{
printf("Student 1:\tNamn: %s.\tAge: %s.\n", student_list1[i].name, student_list1[i].age);
}
return 0;
} //main end
void input(struct person student_list1[MAX], int *total_entries)
{
int done=0;
while(done!=1)
{
int i=0;
printf("Name of student: ");
fgets(student_list1[i].name, strlen(student_list1[i].name), stdin);
student_list1[i].name[strlen(student_list1[i].name)-1]=0;
if(student_list1[i].name==0) {
done=1;
}
else {
printf("Age of student: ");
scanf("%d", student_list1[i].age);
*total_entries++;
i++;
}
}
}
struct person student_list1[MAX] in the function argument is actually a pointer to struct person student_list1.
student_list1[MAX] you passed is a (out of bound) member of the array struct person student_list1[MAX]. Valid array index shoudl be between 0 to MAX - 1.
Change it to:
input(student_list1, &total_entries);
Note that here the array name student_list1 is automatically converted to a pointer to student_list1[0].
There are many things wrong with the code; this is my attempt at making it somewhat more robust:
#include <stdio.h>
#include <string.h>
#define MAX 10
#define NAME_LEN 15
// use a typedef to simplify code
typedef struct person {
char name[NAME_LEN];
int age;
} person_t;
// size qualifier on student_list is redundent and person_t* does the same
void input(person_t *student_list, int *total_entries);
int main(void)
{
person_t student_list[MAX];
int total_entries, i;
// pass array and not the non-existent 'student_list[MAX]' element
input(student_list, &total_entries);
for(i=0; i<total_entries; i++)
{
// age is an int, not a string so use %d
printf("Student 1:\tName: %s.\tAge: %d.\n", student_list[i].name, student_list[i].age);
}
return 0;
} //main end
void input(person_t *student_list, int *total_entries)
{
int done = 0, i = 0;
*total_entries = 0;
while (i < MAX) {
printf("Name of student: ");
// use NAME_LEN instead of strlen(list[i].name) because latter is
// probably not initialized at this stage
if (fgets(student_list[i].name, NAME_LEN, stdin) == NULL) {
return;
}
// detect zero-length string
if (student_list[i].name[0] == '\n') {
return;
}
printf("Age of student: ");
scanf("%d", &student_list[i].age);
// read the newline
fgetc(stdin);
*total_entries = ++i;
}
}
input(student_list1[MAX], &total_entries); shoud be input(student_list1, &total_entries);.
In C,
void input(struct person student_list1[MAX], int *total_entries);
equals
void input(struct person *student_list1, int *total_entries);
Here is my code:
#define MAX_SET_LENGTH 255
typedef struct{
char name;
char *elemetns;
}Set;
void createSet();
int getString();
void filter(char raw[],int *length);
void menu();
void del_duplicate(char *s,int n);
void displyAllSets();
Set sets[26];
int setCount=0;
int main(){
menu();
}
void menu(){
int input;
do{
printf("\n1.Create Set.\n");
printf("2.display all Sets.\n");
printf("0.Exit.\n");
scanf("%d",&input);
switch(input){
case 0:
break;
case 1:
createSet();
break;
case 2:
displyAllSets();
break;
default:
printf("Error input,please input again\n");
}
}while (input!=0);
}
void displyAllSets(){
int i;
for(i=0; i<setCount; i++) {
printf("\n%c->{%s}\n",sets[i].name,sets[i].elemetns);
}
}
void createSet(){
if(setCount<26){
printf("Please input the set's elements:\n");
char elements[MAX_SET_LENGTH];
int s_length = getString(elements,MAX_SET_LENGTH);
filter(elements,&s_length);
del_duplicate(elements,s_length);
if(s_length > 0){
elements[s_length]='\0';
Set set;
set.elemetns = elements;
set.name = 'a'+ setCount;
sets[setCount++]=set;
displyAllSets();
}else{
printf("No illegal input!\n");
}
}else{
printf("It's limit to 26");
}
}
int getString(char s[],int max_length){
char c;
int i=0;
getchar();
while((c=getchar())!='\n')
s[i++]=c;
return (i>=max_length ? max_length : i);
}
void filter(char raw[],int *length){
char string[*length];
int i=0,j=0;
int deletedCount=0;
for(;i<*length;i++){
string[i]=raw[i];
}
for(i=0;i<*length;i++){
if(string[i]>='A' && string[i]<='Z'){
raw[j++]=string[i];
}else{
deletedCount++;
}
}
*length-=deletedCount;
raw[j]='\0';
}
void del_duplicate(char raw[],int length){
int i=0,j;
for(;i<length && length>0;i++){
for(j=i+1;j<length;){
if(raw[i]==raw[j]){
int delFrom=j;
while(delFrom<length){
raw[delFrom]=raw[delFrom+1];
delFrom++;
}
j=i+1;
length--;
}else{
j++;
}
}
}
}
Everything looks good when calling createSet();
but, after calling printf("\n1.Create Set.\n") in do-while block, the array sets has been modified. Can anyone help?
after pressing F6
Can you see that left bottom window, sets[0].elements gets changed, what's happening?
You are storing the address of a local variable on this line:
set.elemetns = elements;
That is undefined behaviour. Don't do it!
If you want to copy the string, do one of the following:
Change the structure to store a char array and use strncpy to copy the string; or
Duplicate the string (and remember to free it later): set.elemetns = strdup(elements);
In a completely separate issue, you have implemented a function getString that seems to do roughly what fgets does. You should use fgets instead.