comparing strings in a structure pointer in C - c

#include <stdio.h>
#include<stdlib.h>
#include<string.h>
struct person {
char user[50];
char password[50];
int amount;
};
int i=0;
int h=0;
int *n=&h;
struct person *p = NULL;
void adduser();
int main()
{
int x;
printf("Welcome to the bank\n");
printf("what would you like to do\n");
printf("type 1 to add a user\n");
printf("type 2 to add to balance\n");
printf("type 3 to take from balance\n");
printf("type 4 to check from balance\n");
scanf("%d%*c",&x);
if(x==1){
adduser();
}
else if (x == 2){
printf("2");
}
else if (x == 3){
printf("3");
}
else if (x == 4){
printf("4");
}
else{
main();
}
}
void adduser(){
struct person *temp = realloc(p, *n * sizeof(struct person));
if (temp != NULL)
p = temp;
printf("n=%d\n",*n-1);
printf("enter your new username\n");
scanf("%s",&(p+*n)->user);
int o=*n-1;
for (i;i<=o;i++)
{
if(strcmp((p+*n)->user,(p+i)->user) == 0)
{
printf("user already exists");
adduser();
}
}
printf("enter your new password\n");
scanf("%s",(p+*n)->password);
*n+=1;
main();
}
hello I'm a beginner with C I'm trying to see i have string the user input similar to one in my structure using this code.
for (i;i<=o;i++)
{
if(strcmp((p+*n)->user,(p+i)->user) == 0)
{
printf("user already exists");
adduser();
}
}
my code is supposed ask the user to enter their new user(at least what i posted) and checks if a similar user exists but my loop gets ignored i don't know what to do with it . i feel like my problem lies elsewhere but i cant figure it out. Also i might have done fundamental mistakes because I'm very new to structures and pointers.
i tried searching online for solutions but i couldn't find a similar situation.

This code is clearly in error:
struct person *temp = realloc(p, *n * sizeof(struct person));
since we're almost immediately going to do:
scanf("%s",&(p+*n)->user);
this really needs to read
struct person *temp = realloc(p, (*n + 1) * sizeof(struct person));
In addition,
for (i;i<=o;i++)
is clearly wrong and should be
for (i=0;i<=o;i++)
and as dxiv points out, i really should be declared in this for loop rather than as a global.
Incidentally, are you having trouble with loops? I don't see that recursive call of main() much. It's really clever, but this code works well only if compiled with optimizations on (which in turn is harder to debug). I'd advise replacing
else{
main();
}
and the other calls to main() with an infinite loop around all of main() (which eventually will have a loop exit condition or a conditional break; statement on the input ladder.

Related

Violation of access with pointers and scanf

The following code is supposed to insert the name of a good, whether it's getting stored or sent away (with just a single letter, like i for in or o for out) and in conclusion how much of that item is getting moved.
Then the program should end whenever I write the END phrase.
Problem is, I am finding a violation of access while trying to save the number of items, and cannot seem to find where I am doing something wrong.
#define MAX 20
#define END "FINE"
typedef struct type_struct {
char name[MAX];
char move[2];
int quantity;
struct type_struct* next;
}type;
void insert(type* p) {
type* aux;
aux = p;
while (aux != NULL)
aux = aux->next;
aux = malloc(sizeof(type));
printf("name of good: ");
scanf("%s", aux->name);
getchar();
printf("in or out?: ");
scanf("%c", aux->move);
printf("quantity: ");
scanf("%d", aux->quantity);
printf("\n");
}
int main(void) {
type* phrase=NULL;
char fine[5];
strcpy(fine, END);
do {
insert(phrase);
} while ((strcmp(phrase, fine) == 0));
}
It should be very simple, however, I am clueless and hope you might give me a hand

Not able to write a string to a *char[]

I've been at this for hours with little progress made. I need to know why exactly my program is crashing when scanf() is called. The error message: "Segmentation fault; core dumped" leads me to believe that I'm not allocating memory to the dynamic array correctly. If this is the case could someone tell me how I can correctly allocate memory to add one struct to the array?
#include <stdio.h>
#include <stdlib.h>
/*
*
*/
enum Subject{
SER = 0, EGR = 1, CSE = 2, EEE = 3
};
struct Course{
enum Subject sub;
int number;
char instructor_name[1024];
int credit_hours;
}*course_collection;
int total_courses = 0;
int total_credits = 0;
void course_insert();
void resizeArray();
int main(int argc, char** argv) {
int choice = 0;
while(choice != 4){
printf("Welcome to ASU, please choose from the menu"
"choices.\n\n");
printf("_____________________________________________\n\n");
printf("Menu:\n 1.Add a class\n 2. Remove a class\n"
" 3.Show classes\n 4.Quit");
printf("\n\nTotal credit hours: %d\n\n", total_credits);
printf("\n\n_________________________________________");
scanf("%d", &choice);
if(choice == 1){
resize_array(total_courses);
course_insert();
}
else if(choice == 3)
print_courses();
}
return (EXIT_SUCCESS);
}
void resize_array(int total_courses) {
course_collection = malloc(total_courses +
sizeof(course_collection));
}
void print_courses() {
int i;
for(int i = 0; i < total_courses; i++){
printf("\nInstructor: %s\n\n",
course_collection[i].instructor_name);
}
}
void course_insert(){
printf("\n\nEnter the instructor's name\n\n");
scanf("%s" , course_collection[total_courses].instructor_name);
total_courses++;
}
//will crash just after scanf();
//must press 1 & enter for correct output
After entering a few instructor names I choose the third option from the menu and that should iterate through the array and print each instructor's name but all I get are blanks lines and the last instructor name I imputed.
UPDATE
#user3545894 I've tried this and it seems to work fine but I still get the issue with the output not being correct. I should be able to iterate through the array and print the strings in each subscript.
The problem came from malloc(total_courses + sizeof(course_collection))
You only allocate array of pointer of course_collection.
You need allocate memory for whole the struct Course
It should be malloc(total_courses * sizeof(struct Course))
User this malloc(total_courses + sizeof(struct Course)) instead of malloc(total_courses + sizeof(course_collection))
segmentation fault due to memory allocation mostly for arrays
arr[n] we use it till '0' to 'n-1' { carefully observe not 'n'}

Adding records with pointers to arrays

I have to create a program which adds records to a simple phone book. The code is below, but it doesn't work - function ends and then it stucks on declaring struct record x and doesn't want to display my added record - the program breaks down. When I put this part of code on the end of the function (but instead of "struct record x = array[0];" I put "struct record x = (*array)[0]") it works - record is printed. So I guess the problem is something about pointers, but I'm struggling and I really couldn't find out what's wrong. I remember that few weeks ago I created a program which was very similar but it was adding a new record to an array of integers, with fixed values and it was working well, so maybe there's something with structures that I don't know about. Thanks for any help!
I know the program isn't done yet and I know that I didn't make any action for temp_array == NULL, it'll be done after I found out what's going on.
struct record {
char f_name[SIZE];
char name[SIZE];
long int phone;
};
int add_record(struct record** array, int n)
{
struct record* temp_array = malloc((n+1) * sizeof(struct record));
if (temp_array == NULL)
{
free(temp_array);
return -1;
}
int i;
for (i=0; i < n; i++)
{
temp_array[i] = (*array)[i];
}
struct record new_record;
printf("\nAplly data.");
printf("\nFirst name: "); /*fgets(new_record.f_name, SIZE, stdin);*/ scanf("%s", &new_record.f_name);
printf("Surname: "); /*fgets(new_record.name, SIZE, stdin);*/ scanf("%s", &new_record.name);
printf("Phone number: "); scanf("%d", &new_record.phone);
temp_array[n] = new_record;
free (*array);
*array = temp_array;
//struct record x = (*array)[0];
//puts(x.f_name); puts(x.name); printf("%d", x.phone);
return 0;
}
main()
{
struct record* array; int n = 0;
int choice;
printf("\n1. Add record\n2. Delete record\n3. Find record\n0. Exit\n\nChoose action: ");
scanf("%d", &choice);
switch(choice) {
case 0: printf("\nKsiazka zostala zamknieta.\n"); return;
case 1: add_record(&array, n); n++; break;
case 2: return;
case 3: return;
default: printf("Wrong choice.\n\n"); return;
}
struct record x = array[0];
puts(x.f_name); puts(x.name); printf("%d", x.phone);
}
struct record* array=NULL;, and use %ld for long int – BLUEPIXY

Why does strcpy read extra characters?

I just have a question(s) about making a binary tree, as this code doesn't work, it places nodes where they shouldn't go, and although it never crashes its leaking memory like a busted pipe. The idea was a simple guessing game where it simply tries to guess what you are thinking about, and when it gets it wrong you enter a question and answer to help it learn. Relevant code:
I guess my primary problem is char *guess will sometimes store only fragments of the original string passed to getnew(). The next would be the logic in traverse(), as it will jump to the "no" condition regardless of user input.
struct binary {
unsigned long ID;
char *guess;
char isAns;
struct binary *yes;
struct binary *no;
};
typedef struct binary Node;
void traverse(Node **top)
{
if(*top)
{
char ans[128] = "ok";
char ans2[128] = "ok";
if((*top)->isAns=='y')
{
fprintf(stdout,"Is it %s (y/n)? ",(*top)->guess);
}
else
{
fprintf(stdout,"%s (y/n)? ",(*top)->guess);
}
while(!fgets(ans,128,stdin));
if((*top)->isAns=='y')
{
if(ans=="y")
{
printf("Successful string of guesses!\n");
}
else
{
printf("Enter another question to figure out the difference: ");
while(!fgets(ans,128,stdin));
Node *q=getnew(ans,'n');
printf("Enter the right answer: ");
while(!fgets(ans2,128,stdin));
push1(top,q,'n');
(*top)->yes = getnew(ans2,'y');
}
}
else
{
if(ans=="y")
{
if((*top)->yes)
{
traverse(&(*top)->yes);
}
else
{
printf("Null node for top->yes\n");
printf("Enter an answer: ");
while(!fgets(ans,128,stdin));
(*top)->yes=getnew(ans,'y');
}
}
else
{
if((*top)->no)
{
traverse(&(*top)->no);
}
else
{
printf("Null node for top->no\n");
printf("Enter an answer: ");
while(!fgets(ans,128,stdin));
(*top)->no=getnew(ans,'y');
}
}
}
}
else
{
char ques[128] = "ok";
char ans[128] = "ok";
printf("Node is null\n");
printf("Put in a question and answer to yes condition\n");
printf("Enter question: ");
while(!fgets(ques,128,stdin));
printf("Enter answer for yes condition: ");
while(!fgets(ans,128,stdin));
(*top) = getnew(ques,'n');
(*top)->yes=getnew(ans,'y');
}
printf("\n\n");
}
Node * getnew(char *msg, char isAns)
{
Node *nnew = malloc(sizeof(Node));
nnew->ID=clock();
nnew->guess=malloc(sizeof(msg));
strcpy(nnew->guess,msg);
nnew->isAns=isAns;
nnew->yes=0;
nnew->no=0;
return nnew;
}
I appreciate any help.
nnew->guess=malloc(sizeof(msg)); only allocates enough memory for a pointer.
Instead of:
nnew->guess=malloc(sizeof(msg));
strcpy(nnew->guess,msg);
use:
nnew->guess=strdup(msg);
You probably want to use strdup
C strings are char * pointers, therefore `sizeof(msg) == sizeof(char*) == 8 or 4". Not what you want.
nnew->guess=malloc(sizeof(msg));
strcpy(nnew->guess,msg);
Should be
nnew->guess = strdup(msg);
Or
nnew->guess=malloc(strlen(msg) + 1);
strcpy(nnew->guess,msg + 1);
The +1 is for the nul termintor (assuming you want it).
I see where guess is malloced but I don't see where it's freed. That would definitely cause memory leaks.
as a side note, I've just spun up a quick program to check into the
nnew->guess=malloc(sizeof(msg));
it looks like this
char str[10] = "string";
printf("%d", sizeof(str));
and surprisingly, it printed 10,
but that method of allocation still makes me uneasy.

How to fill an array in C with user input values, when the array is of unknown length [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Dynamic array using ANSI C
I am trying to fill an array with the values that the user is typing. However, I do not know in advance how many values will my array have, or how many values the user will type in. The user types in a value at a time, the value is stored in the array, and then the user is again prompted to type in another value, and so forth, until he types in a negative number. When the user types in a negative number, the program prints out all the positive values that the user has entered so far (NOT the negative one, as it is essentially only used for termination of the program).
My problem is:
1) how to declare the array without knowing in advance how big it will be?
2) how to scan for the user input? For example, I am thinking something like this for scanning the input and assigning the values to the array (this is just a part of the code, not all of it, I just want to know if this part of the code will work when I have completed the program):
...
int working = 0;
int i = 0;
do
{
printf("Enter a positive value \n");
scanf("%d",&x);
if (x >= 0)
{
&array[i] = x;
i++;
}
else
{
printf("You have entered a negative number \n");
working = 1;
}
} while (working = 0);
Is this code correct (of course, it is not a complete program)? Also, how do I declare the array, without knowing how big it will be (I have no way of knowing in advance how many positive values the user will type in before he types in a negative one)
You can allocate an initial array for user input and save it's size into a variable so then you can reallocate the array when it's full. Or you could use linked list to save input, so later you could calculate needed element count and allocate the array.
int arraySize = 256; // Or whatever
int *array = malloc(arraySize * sizeof(int));
if (!array)
{
fprintf(stderr, "Master, please buy more RAM, I can't allocate memory\n");
return;
}
int numberOfElements = 0;
for(;;)
{
printf("Enter a positive value:\n");
scanf("%d",&x);
if (x >= 0)
{
if (numberOfElements == arraySize)
{
arraySize *= 2; // Or whatever strategy you need
array = realloc(array, arraySize * sizeof(int));
if (!array)
{
fprintf(stderr, "Master, please buy more RAM, I can't allocate memory\n");
break;
}
}
array[numberOfElements++] = x;
}
else
{
printf("You have entered a negative number \n");
break;
}
}
Something like. Sorry for the possible mistakes, don't check it.
Better use linked list, array won't help you here.
Check this out if you are not familiar with it - http://cslibrary.stanford.edu/103/LinkedListBasics.pdf
int dataarray [2];
int no;
int count =0;
while(1)
{
printf("Enter No's = ");
scanf("%d",&no);
if(no<0)
break;
*(dataarray+count)=no;
count++;
}
you can use the count further to know how many elements in array.
you can get elements from this array by pointers link
no = *(dataarray+count)
You can use a linked list structure for that. There can be many possible implementations (simple linkedlist, double linkedlist ,etc) if you google you can find many pages about this. Here is an example (not necessarily the most optimized form, but just to give you an idea)
#include <stdio.h>
#include <stdlib.h>
struct datalist
{
int value;
struct datalist *next;
};
typedef struct datalist *linkedList;
void addToList(linkedList *param_valueList, const int param_newValue)
{
if (*param_valueList == NULL)
{
linkedList newItem = (linkedList)malloc(sizeof(struct datalist));
newItem->value = param_newValue;
newItem->next = NULL;
*param_valueList = (linkedList)malloc(sizeof(linkedList));
*param_valueList = newItem;
}
else
{
linkedList newList = (linkedList)malloc(sizeof(struct datalist));
newList->value = param_newValue;
newList->next = NULL;
linkedList tmpList = *param_valueList;
while (tmpList->next != NULL)
tmpList = tmpList->next;
linkedList *listPtr = &tmpList;
(*listPtr)->next = newList;
}
}
void printList(const linkedList param_valueList)
{
linkedList tmpList = param_valueList;
while (tmpList != NULL)
{
printf("%d\n", tmpList->value);
tmpList = tmpList->next;
}
}
int main(int argc, char *argv[])
{
int inputNmbr = 0;
linkedList numberList = NULL;
while (1)
{
printf("print a number: ");
scanf("%d", &inputNmbr);
if (inputNmbr > 0)
addToList(&numberList, inputNmbr);
else
break;
}
printf("Here are the numbers you entered:\n");
printList(numberList);
return 0;
}
Regards,

Resources