I'm creating a "phonebook" program for school. Basically I have to get a user to input the names and phone numbers of their contacts into two different arrays. I got that part down, but after I have to give the user an option to search the contacts either via name or phone number and I'm running into some issues.
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>
#include <stdbool.h>
int main()
{
int arraysize;
printf("How many phone numbers will you be entering: ");
scanf("%d", &arraysize);
int * phoneNumbers = malloc(arraysize);
char * names = malloc(arraysize);
for (int i = 0; i < arraysize; ++i)
{
printf("Please enter the name of person %d: ", i + 1);
scanf("%s", &names[i]);
printf("Please enter %s's phone number: ", &names[i]);
scanf("%d", &phoneNumbers[i]);
}
char * searchOption;
printf("Would you like to seach via name or phone number? ");
scanf("%s", &searchOption);
if (strcmp(searchOption, "name") == 0)
{
char * searchName;
int element;
bool stop = false;
while (stop = false)
{
searchName = NULL;
printf("\nPlease enter the name you wish to search for: ");
scanf("%s", &searchName);
for (int i = 0; i < arraysize; ++i)
{
if (strcmp(searchName, names[i]) == 0)
{
element = i;
stop = true;
break;
}
}
if (stop = false)
{
printf("\nname not found, please search again!");
}
}
}
I'm pretty sure it's crashing at the strcmp() call but I have no idea why
The problem is, in
scanf("%s", &searchOption);
you're doing it wrong.
You need to
First allocate memory to searchOption pointer (or make it an array).
pass searchOption, not &searchOption to scanf().
Same issue appears for char * searchName; also later in the code.
The crash is not directly caused by the strcmp() call.
This line is at fault:
scanf("%s", &searchOption);
First of all, there is a type mismatch. For %s you have to pass an argument of type char*, not char** as you did. To fix this, remove the take-address (&) operator.
Additionally, you need to allocate memory to scan into. The scanf function doesn't do that for you. As a quick and dirty fix, you can simply make searchOption an array. Replace its declaration with
char searchOption[100];
or such to fix this. You also want to limit the number of characters scanf() attempts to read:
scanf("%100s", searchOption);
so there can't be a buffer overflow.
An even better approach is to use fgets() instead of scanf(). The fgets() function is suited better for what you want to do. Read the manual for how to use fgets().
As Alter Mann said, the same problem occurs a second time further down. You need to repair that, too.
Also i think in strcmp you have used "name" whereas you declared it as names before.If you correct this maybe program works
Related
please take a look at the code below.
#include <stdio.h>
#include <conio.h>
struct str {
char st[1];
char rule[20];
} production_rules[30];
int main () {
int n;
printf("Enter number of productions: ");
scanf("%d", &n);
printf("Enter the productions\n");
for (int i = 0; i < n; i++) {
printf("Enter the non terminal: ");
scanf("%s", production_rules[i].st);
printf("Enter the RHS of the production Rule: ");
scanf("%s", production_rules[i].rule);
}
printf("the production rules are \n");
for (int i = 0; i < n; i++) {
printf("%s -> %s\n", production_rules[i].st, production_rules[i].rule);
}
return 0;
}
I am getting the following output
Enter number of productions: 1
Enter the productions
Enter the non terminal: A
Enter the RHS of the production Rule: abc
the production rules are
Aabc -> abc
Expected Output:
Enter number of productions: 1
Enter the productions
Enter the non terminal: A
Enter the RHS of the production Rule: abc
the production rules are
A -> abc
The problem is in the last line of the output. I don't understand why the char array is being concatenated. Can some one help me with this problem
There is no issue in your struct, but just the way you use printf, as you put %s to print the element "st", whilst you should use "%c" instead.
In fact, "st" is just a char[1], not a proper string, so it doesn't contain the string termination character '\0'.
As your struct is stored in memory as a buffer of consecutive char, the "%s" makes the "printf" stop when the termination string character is found, so at the end of the element "rule", and that's reason of your output.
So, just replace %s with %c when printf of st and it will work. Your code should appear like this:
for (int i = 0; i < n; i++) {
printf("%c -> %s\n", production_rules[i].st, production_rules[i].rule);
}
As mentioned in the comments, the problem was: not having a sufficient number of rooms in that character array. It is because the null-terminator character is always put at the end of the string, so it requires extra space.
In the current situation, your requirement is only a single character. So, you can change it into a char in the struct definition:
struct str {
char st;
char rule[20];
} production_rules[30];
And use it this way:
scanf(" %c", &production_rules[i].st);
Notice that an extra whitespace character is given here because it is necessary. Otherwise, it would simply ignore the input from being given.
Another method to solve this issue is to increase the length of the array by one. Suppose, you need 3 numbers as char[] then you need a length of 4 (extra one).
I'm trying to create a program which will take information from 10 racers. The program will get and store the first name, last name, age, gender (m/f), and time for their race (hh:mm:ss). To do this I planned to have an array of structures containing each of the above elements for each racer. I then came across the problem of asking "Please enter the name of the first racer" because the word "first" needs to be changed to "second", "third" and so on... A loop wouldn't be able to do that. So I decided to then make an array of strings, where the first element of the array would be the word "first" and so on. So then I could use a loop to print the right word for each racer by accessing each element of the places array.
I'm not very experienced with strings, and arrays of strings, I searched online for some help and came up with the following program, it uses an array of characters with a pointer, which I dont quite understand, must be something to do with the strings. Anyways, when I run the program I get serious problems and have to re-open Visual Studio. Hoping someone can give me a hand and help clear up some mysteries about these arrays of strings and the significance of the pointer. Thanks!
#include <stdio.h>
#include <math.h>
typedef struct DATASET
{
char firstname[12], lastname[12], gender;
int age, hours, minutes, seconds;
};
#define MaxRacers 10
int main()
{
int i;
DATASET data[MaxRacers];
char *places[MaxRacers];
char place1[6] = "First";
char place2[7] = "Second";
char place3[6] = "Third";
char place4[7] = "Fourth";
char place5[6] = "Fifth";
char place6[6] = "Sixth";
char place7[8] = "Seventh";
char place8[7] = "Eighth";
char place9[6] = "Ninth";
char place10[6] = "Tenth";
places[0] = place1;
places[1] = place2;
places[2] = place3;
places[3] = place4;
places[4] - place5;
places[5] = place6;
places[6] = place7;
places[7] = place8;
places[8] = place9;
places[9] = place10;
printf("%s", places[1]); // TEST which works fine
for(i = 0, i < MaxRacers; i = i + 1;)
{
printf("Enter the name of the %s finisher\n", places[i]); // Problem
}
getchar();
return(0);
}
Now Ive got things going a bit further, Im running into a problem now as soon as I have finished entering the last name of the first finisher the program exits out of the command window and a new window comes up saying:
"Exception thrown at 0x0FF6D0F1 (ucrtbased.dll) in ConsoleApplication30.exe: 0xC0000005: Access violation writing location 0xFFFFFFCC.
If there is a handler for this exception, the program may be safely continued."
#include <stdio.h>
#include <math.h>
struct DATASET
{
char firstname[12], lastname[12], gender;
int age, hours, minutes, seconds;
};
#define MaxRacers 10
int main()
{
int i;
DATASET data[MaxRacers];
char *places[] = { "First", "Second", "Third", "Fourth", "Fifth", "Sixth", "Seventh", "Eighth", "Ninth", "Tenth" };
for (i = 0; i < MaxRacers; i++)
{
printf("Enter the first name of the %s finisher:\n", places[i]);
scanf("%s", data[i].firstname);
printf("Enter the last name of the %s finisher:\n", places[i]);
scanf("%s", data[i].lastname);
printf("Enter the gender of the %s finisher: [m/f]: \n", places[i]);
scanf("%c", data[i].gender);
printf("Enter the age of the %s finisher:\n", places[i]);
scanf("%d", data[i].age);
printf("Enter the time of the %s finisher: [hh:mm:ss]\n", places[i]);
scanf("%d:%d:%d", data[i].hours, data[i].minutes, data[i].seconds);
printf("\n\n");
}
getchar();
return(0);
}
for(i = 0, i < MaxRacers; i = i + 1;)
The for loop doesn't work like that. Try this:
for(i = 0; i < MaxRacers; i++)
// ^ ^
// | |
// semicolon here more idiomatic
In addition, you should use the idiomatic character array initialization:
char *places[MaxRacers] = { "First", "Second", ... };
not only because it is way easier to type than your 20 lines of places, but also because there are far less chances to miss a typo like
places[3] = place4;
places[4] - place5; // <---- whoops
places[5] = place6;
While we're at it,
typedef struct DATASET
{ // whatever
};
makes little sense. It doesn't create any typedef name, so the word typedef is useless. It is equivalent to
struct DATASET
{ // whatever
};
Because of that, this declaration
DATASET data[MaxRacers];
is invalid in C. It is valid in C++, which probably means you are using a C++ compiler. If you are learning C, make sure your source file extension is .c.
In your second iteration of this question, you report that:
Im running into a problem now as soon as I have finished entering the last name of the first finisher
I believe that this problem is due to the fact that you have incorrectly declared data[]. DATASET is a struct, not a typedef, so you need:
struct DATASET data[MaxRacers];
But this reveals a new problem. You have several issues around your calls to scanf(). First, you are failing to provide addresses to store the results of scanf() in several instances. To fix this, you need to change to:
printf("Enter the gender of the %s finisher: [m/f]: \n", places[i]);
scanf("%c", &data[i].gender);
printf("Enter the age of the %s finisher:\n", places[i]);
scanf("%d", &data[i].age);
printf("Enter the time of the %s finisher: [hh:mm:ss]\n", places[i]);
scanf("%d:%d:%d", &data[i].hours, &data[i].minutes, &data[i].seconds);
But yet another problem is now apparent. The (evil) function scanf() often leaves newlines and other characters behind, polluting the input stream for the next input function. I personally usually write a function to handle user input in the form of strings, and then use strtol() to convert the results if numeric input is desired.
The simplest thing for you to do, though, would be to simply write a function to clear the input stream before using scanf() with the %c specifier:
void clear_stream(void)
{
int ch;
while ((ch = getchar()) != '\n' && ch != EOF)
continue; // remove unwanted characters
}
Then modify your input code like this:
printf("Enter the first name of the %s finisher:\n", places[i]);
scanf("%s", data[i].firstname);
printf("Enter the last name of the %s finisher:\n", places[i]);
scanf("%s", data[i].lastname);
printf("Enter the gender of the %s finisher: [m/f]: \n", places[i]);
clear_stream();
scanf("%c", &data[i].gender);
printf("Enter the age of the %s finisher:\n", places[i]);
scanf("%d", &data[i].age);
printf("Enter the time of the %s finisher: [hh:mm:ss]\n", places[i]);
scanf("%d:%d:%d", &data[i].hours, &data[i].minutes, &data[i].seconds);
printf("\n\n");
With many format specifiers, scanf() skips over leading whitespace, including newlines. But this is not true for the %c specifier, and this means that if you enter, say a string, the newline that is left behind in the input stream will be picked up instead of the character that you want.
These changes will get your code running. But your input scheme is fragile. It doesn't check to be sure that there was input (scanf() returns the number of values that were read) and it doesn't validate values. Do you want the user to input a negative age? I would urge you to at least rethink your input code to be sure that you get the input that you want. And because scanf() is error-prone, you should really consider using fgets() or write your own input function, such as the one that I linked to earlier.
I have no idea why this code is not working. Could someone please help me? (I want a simple version-fix if it's possible, because I've only started to study C a couple of weeks ago.)
#include <stdio.h>
#include <string.h>
int main ()
{
char *name="alina";
char *input;
printf ("what's your name? \n");
scanf ("%s",&input);
if (input=="alina")
printf("your name is %s good job!\n ",&name);
if (input!="alina")
printf("are you sure? open the program again and insert the correct name");
while (1);
}
you need to apply following changes:
char input[256];
scanf("%s", input);
printf("your name is %s good job!\n ", name);
to compare strings use strcmp - have a look at documentation of this function.
be careful with scanf - think about how long string you can store there and what can go wrong. Have a look at scanf_s
You did some errors. First, if you want to insert a string, you can use the %s, but you have to use an array of char in which you can store that string. That's, you have to write something like this.
char input[100];
scanf("%s", input);
and then it'll work. This snippet of code means: I need to insert (store) a string. So first I create a place in which I can store it (pay attention that the string must be maximum of 99 characters; my array has size 100, but the last character is used to represent the end of the string), and then I use the scanf to write what I want.
The second error is that if you want to compare two strings, you can't simply use the == or !=, like when you do with numbers. The string.h library lets you use the strcmp function, like this:
if (strcmp(name, input) == 0) // this means the strings are equal
...
else
...
remembering that
char* name = "Alina";
char input[100];
Eventually, here you're an inspected version of your code:
#include <stdio.h>
#include <string.h>
int main() {
char* name = "Alina";
char input[100];
printf("What's your name?\n");
scanf("%s", input);
if (strcmp(name, input) == 0)
printf("Your name is %s good job!\n", name);
else
printf("Are you sure? Open the program again and insert the correct name\n");
return 0;
}
The while(1) at the end of your code is absolutely dangerous, because it starts an infinite loop that never ends, crashing your program. You want to definitely remove it!
I've been banging my head against this wall for an hour and I'm losing my mind... I have a piece of code (yes, it is homework) that throws a segmentation fault unless I comment out one of my scanf statements. I've tried to debug the problem using gdb, but I haven't really learned anything about that up until today.
Here is the code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char * creditCard(char * ccNumber){
char * lastFour;
lastFour = (ccNumber + strlen(ccNumber) - 4);
return lastFour;
}
void zipCode(int zip){
printf("The zip code entered is: %d\n", zip);
}
int fuelGrade(int grade){
}
int main(void){
char * ccNumber = NULL;
int zip = 0;
int gasGrade = 0;
printf("Please Enter Credit Card Number: ");
scanf("%s", ccNumber);
printf("Please Enter Your Billing Zip Code: ");
scanf("%d", &zip);
printf("Select your Fuel Grade.\n Unleaded(1) Plus(2) Premium(3): ");
scanf("%d", &gasGrade);
ccNumber = creditCard(ccNumber);
printf("****-****-****-%s\n", ccNumber);
zipCode(zip);
return 0;
}
When I compile and run as is I get the following:
Please Enter Credit Card Number: 123413515
Please Enter Your Billing Zip Code: Select your Fuel Grade.
Unleaded(1) Plus(2) Premium(3): 1
Segmentation fault
Entering the zip code is skipped and I get a segfault right after entering anything in fuel grade. However, if I comment out the scanf("%d", &gasGrade); line the code runs fine.
Originally I did not have the variables initialized and I had the code organized a little differently, but I can't seem to find the right solution to this problem. What am I doing wrong here?
Thanks for your help!
Because by doing scanf("%s", ccNumber); with ccNumber = NULL you are dereferencing a NULL pointer.
The "%s" specifier of scanf() expects a pointer to valid memory where it can write the scanned data, you are passing a NULL pointer, it does not check if the pointer is NULL, and hence it's dereferencing the NULL pointer.
You need valid memory, so you can use the stack in this case, like this
char buffer[100];
char *ccNumber;
if (scanf("%99s", buffer) != 1)
problemScanning_buffer_DoNotUse_buffer_In_TheFollowingCode();
ccNumber = creaditCard(buffer);
Note the 99 above, it prevents overflowing buffer, and you MUST always check the return value of scanf() to prevent Undefined Behavior.
You either have to allocate memory for ccNumber using malloc or define it as an array char ccNumber[17] (16 digits + \0 character). Right now it is a pointer to a single char that you initialize to NULL.
You do not allocate memory for cc Number (ccNumber is NULL)
When reading a number you have to clear the line break character, but to read another value with scanf, automatically read the '\ n' that is in the input buffer (stdin).
printf("Please Enter Your Billing Zip Code: ");
scanf("%d", &zip);
Change:
scanf("%d", &zip);
To:
scanf("%d%*c", &zip);
#include<stdio.h>
#include<string.h>
void main()
{
int entry,i;
printf("\nPlease indicate the number of records you want to enter :\n");
scanf("%d",entry);
char ent[entry][100000];
printf("\nPlease input records of students (enter a new line after each record), with following format first name last name score \n");
for(i=0;i<entry;i++)
{
gets(ent[i]);
printf("%s",ent[i]);
}
}
The following is a code to accept data of student , first name last name and then score.
main should return int, not void.
int main(void) {
/* ... */
}
scanf("%d",entry);
scanf expects the argument corresponding to the "%d" format specifier to be an int *. Your argument, however, is an int. Perhaps you meant this:
scanf("%d",&entry);
On that note, you should really check the return value of scanf. For all you know, the user didn't enter anything numeric.
if (scanf("%d", &entry) != 1) {
exit(0);
}
In fact, this still allows the user to enter a negative number. Have you ever seen an array of a negative number of items? Seems strange to me, too... I think size_t would be a more appropriate type than int (and as a result, you'll need to use the %zu format specifier)...
Last but not least, gets is deprecated because it makes it impossible to prevent the user from overflowing buffers, which could cause segfaults.
#include <stdio.h>
#include <string.h>
int main(void)
{
size_t entry;
printf("\nPlease indicate the number of records you want to enter :\n");
if (scanf("%zu",&entry) != 1)
{
exit(0);
}
char ent[entry][100000];
printf("\nPlease input records of students (enter a new line after each record), with following format first name last name score \n");
for(size_t i=0; i<entry; i++)
{
fgets(ent[i], sizeof ent[i], stdin);
printf("%s",ent[i]);
}
}
you should use int main()instead of void main
when you use you should scanf("%d",&entry) instead of scanf("%d",entry),what scanf need is an address.
you shouldn't use gets(),it's dangerous,try fgets()
scanf("%d",entry); //scanf("%d",&entry)
char ent[entry][100000]; //error
you should use malloc to get an array when you can not know the length of an array in compiling time
The error is in scanf use scanf("%d",&entry) instead of scanf("%d",entry);
Suggestion: use int as return type for main