Struggling on my homework assignment.
After I give inputs it stops rather than doing the random array and last print if anyone can help I would appreciate it
#include <stdio.h>
#include <stdlib.h>
int main() {
char name, color;
int age;
int *poer = &age;
char *p = &name;
char *ptr = &color;
printf("What is your name?\n");
scanf(" %s", &name);
printf("How old are you??\n");
scanf(" %d", &age);
printf("What is your favorite color?\n");
scanf(" %s", &color);
char *story[5] = {"old volkswagen beetle", "singlet", "quater", "left sock",
"blackberry bold ninek"};
srand(time(0));
printf("My pal right here %s is %d years old I feel like we have been coding"
" together for a hundred years now I always wonder where the time has gone"
" One thing I have wanted to know is why they love "
"their %s %s so much I guess I might never know\n",
name, age, color, story[rand() % 5]);
return 0;
}
Plenty of errors can be caught by enabling the compiler warnings.
Here is the list of all problems with their proper solutions:
For this line:
srand(time(0));
You need to include the time.h library, otherwise, you will get an implicit definition of time() error message. Passing NULL to time() is a good practice.
As people figured out:
char name, color;
A single char-type cannot hold more than a single ASCII character. Thus, you need to formulate a sequence of characters, called character array. In C99, variable-length arrays are supported. Still, using a macro constant for defining string lengths during compile-time makes the code good. Replace it:
#define MAX_LENGTH 128 // Prefer your length
...
char name[MAX_LENGTH], color[MAX_LENGTH];
In the similar lines:
printf("What is your name?\n");
scanf(" %s", &name);
scanf() function stops reading further input after whitespace. For example, if you input: John Doe, the name will only store John, Doe becomes truncated. Also, never put an ampersand sign for a char-array in scanf().
fgets() is considered safer than this, since it accepts a limited number of characters defined in its second argument. Replace the scanf():
// ... , sizeof name, ... --- is also applicable here
if (fgets(name, MAX_LENGTH, stdin) == NULL) {
// Do something when input's invalid
}
// Input is okay
Note: The fgets() leaves a trailing newline character as soon as it stops receiving user input. To discard this, use this after its usage:
name[strcspn(name, "\n")] = 0;
After applying all these changes, you will not get any further problems.
the following code will be fine
char name[256];
char color[256];
int age;
printf("What is your name?\n");
scanf(" %s", name);
printf("How old are you??\n");
scanf(" %d", &age);
printf("What is your favorite color?\n");
scanf(" %s", color);
in your code, a char was casted to char* the variable will hold data larger than it could. the the stack was ruined
You used char for string which is wrong. You need a char array to store the strings.
Try this:
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#define STR_MAX 300
int main()
{
char name[STR_MAX];
char color[STR_MAX];
int age;
printf("What is your name?\n");
scanf(" %s", name);
printf("How old are you??\n");
scanf(" %d", &age);
printf("What is your favorite color?\n");
scanf(" %s", color);
char *story[5] = {"old volkswagen beetle","singlet","quater","left sock","blackberry bold ninek"};
srand(time(0));
printf("My pal right here %s is %d years old I feel like we have been coding together for a hundred years now I always wonder where the time has gone One thing I have wanted to know is why they love their %s %s so much I guess I might never know\n",name, age, color, story[rand()%5]);
return 0;
}
your program terminated abnormally because stack was ruined.
char name; //has only 1 byte space
char color; //has only 1 byte space
but these two variables was used to hold data larger than they can. then data was written to some place else which will cause the stack overflow.
code like this will be ok
char name[256];
char color[256];
Related
My issue is coming from the %c name input, I am getting an error that it is expecting type char * but has type char * [15] for the scanf function. I am also getting an error in the printf where the %c expects int but has type char *. I am still quite new at this so if it could be explained as simply as possible that would be amazing.
#include <stdio.h>
struct Student {
int StudentID;
char Name[15];
float Mark1;
float Mark2;
float Mark3;
} a;
int main() {
float ave;
printf("Please input Student's ID \n");
scanf("%d", &a.StudentID);
printf("Please input Student's name. \n");
scanf(" %c", &a.Name);
printf("Input Mark 1. \n");
scanf("%f", &a.Mark1);
printf("Input Mark 2. \n");
scanf("%f", &a.Mark2);
printf("Input Mark 3. \n");
scanf("%f", &a.Mark3);
ave = (a.Mark1 + a.Mark2 + a.Mark3) / 3;
printf("Student Detail\nStudent ID: %d\nName: %c\nMark 1: %.2f\n Mark 2: %.2f\n Mark 3: %.2f\nAverage: %.2f\n",
a.StudentID, a.Name, a.Mark1, a.Mark2, a.Mark3, ave);
return 0;
}
Your problem is related to the difference between an array of chars and a single char.
The %c format only reads in one character at a time.
If you wish to read a string of characters use %s and it will read until a whitespace. (Please make sure you don't try to read a name more than 14 characters long into your 15 character buffer)
In more depth, your char Name[15] is actually a pointer to a series of chars in memory. You are accidentally trying to change to pointer itself, instead of the chars that it points to. This is why the compiler expects a char * .
Instead if you truly meant to only read one char you could use
scanf(" %c", &a.Name[0]);
to place the character in the first block of the Name array.
If this is too complicated don't worry, it will all come eventually :)
For now I think %s will suffice.
You can use %14s to be extra safe.
Also don't forget to use %s in the final printf as well
In your scanf() call, %c tells scanf() to accept a single character. But your argument is a character array. C is a low-level language; it's not smart enough to realize you wanted a string (char array) as input. You have to tell it by using %s instead of %c.
I'm having a bit of trouble passing multiple variables to scanf:
#include<stdio.h>
int main(void) {
char *name;
float weight;
printf("Please enter your name, then weight separated by a comma: ");
scanf("%s,%f", name, &weight);
printf("%s, your weight is %.2f!\n", name, weight);
return 0;
}
Please enter your name, then weight separated by a comma: Tommy,184
Tommy,184, your weight is 0.00!
What would be the proper way to do this, and why doesn't scanf detect the comma and pull the necessary values in their variables?
There are two mistakes in your code:
Wild pointer
char *name; is not a safe code. *name* is a wild pointer and it points to some arbitrary memory location and may cause a program to crash or behave badly. You should use an array like char name[10]. You can refer to this link.
Comma in scanf
You can check this thread for more details
The comma is not considered a whitespace character so the format specifier "%s" will consume the , and everything else on the line writing beyond the bounds of the array sem causing undefined behaviour
I've just tried to modify your code, you should consider removing the comma, and replace it with a space
printf("Please enter your name, then weight separated by a space: ");
scanf("%s %f", name, &weight); // your code should work properly
I think you should be using a char array for the name variable and if you want to store its adress you would assign it to a pointer, doesn't make sense the way you wrote it
float weight;
char[20] name;
scanf(" %s, %f", &name, &weight);
Can you give this a try?
int main()
{
int num;
char str[50];
scanf("%49[^,],%d", str, &num);
printf("%s %d",str, num);
return 0;
}
EDIT
Explanation:
We can read input up to a specific character/characters using %[^<Your character(s)>]. The number 49 here simply refers to the length of string you'd receive and the last character is a null. Adding specific length is up to you ;) This is just one example of getting input the way you asked.
I might miss something really important but I cannot figure out and my teacher does not know either. I am reading char (y/n) as a console input answer, many times, (I do know about " %c" stuff.) I manage to read like 3-4 "y"-s but after that one fails, looks like a NULL and then manages the rest fine.
Functions:
scanf for reading console
fprintf for writing to file
Even though I tried many ways, every time one of my variables fails to contain the real character. When I printf the struct element one by one it fails the same one every time. When I try to read that very one variable of the struct it prints corruptly the y answer. I will include code too, I input as:
address : asdf (whatever really)
size: 0
rest of them are y except the very last. I used to press 2020.
Actual reading:
struct s_orders order;
printf("Address: ");
scanf(" %s", order.address);
printf("Size of fields(m^2): ");
scanf(" %d", &order.size);
printf("Paint ordered?(y/n): ");
scanf(" %c", &order.paint);
printf("Revert ordered?(y/n): ");
scanf(" %c", &order.revet);
printf("Water-gas ordered?(y/n): ");
scanf(" %c", &order.proba);
printf("Kitchen creation ordered?(y/n): ");
scanf(" %c", &order.uniq);
printf("Uphol ordered?(y/n): ");
scanf(" %c", &order.uphol);
printf("Expiration date: ");
scanf(" %s", order.date);
struct:
struct s_orders
{
/* data */
char address[100];
int size;
char paint;
char revet;
char proba;
char water;
char uniq;
char uphol;
char date[100];
};
Expected result:
"asdf;0;y;y;y;y;y;y;2020;"
Gotten:
"asdf;0;y;y;y;(random char here);y;y;2020;"
Edit:
- I am simply bad at focusing, I forgot to ask for input for water variable. Thanks for help!
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.
My goal with this program is to incorporate the users inputs into a sort of interactive/randomized story but I'm not sure how I'm supposed to get the inputs from the users to fit between *ptrDescription, *ptrBeginning, *ptrMiddle, and *ptrEnd. Any help would be much, much appreciated!
#include <stdio.h>
#include<stdlib.h>
#include<time.h>
#include <string.h>
#include <ctype.h>
int main(void){
int i;
char name[20];
char color[20];
int age;
char sentence[1];
//array of pointers to char arrays
char *ptrDescription[]={"the painfully handsome","the one and only","who seemed much older than"};
char *ptrBeginning[]={"was blissfully ignoring","could clearly see","had no idea"};
char *ptrMiddle[]={"the huge truck","the falling meteor","the bucket of milk","the mailman","the most powerful wizard"};
char *ptrEnd[]={"that was barreling toward them.","on the horizon."};
srand(time(NULL));
printf("Enter your first name: ");
scanf("%s", &name);
printf("\nEnter your age: ");
scanf("%d", &age);
printf("\nEnter your favorite color: ");
scanf("%s", &color);
for (i = 0; i < 1; i++)
{
//strcpy(sentence,ptrDescription[rand()%3]);
//strcat(sentence," ");
//strcat(sentence,ptrBeginning[rand()%3]);
//strcat(sentence," ");
//strcat(sentence,ptrMiddle[rand()%5]);
//strcat(sentence," ");
//strcat(sentence,ptrEnd[rand()%2]);
//strcat(sentence,".");
//sentence[0]=toupper(sentence[0]);
puts(sentence);
}
getch();
return 0;
}
EDIT:
I've edited a section of my code so that directly following for (i = 0; i < 1; i++) it now looks like this:
snprintf(sentence, sizeof sentence,"%s, %s %d year old, %s %s %s %s", name, ptrDescription[rand()%3], age,ptrBeginning[rand()%3], ptrMiddle[rand()%5], ptrEnd[rand()%2]);
There are tons of strange characters after the sentence in the output, like Japanese characters and stuff. I'm not sure why they're there, though. This is what it looks like exactly:
"Enter your first name: Justin
Enter your age: 20
Justin, the arrogant 20 year old, was purposefully ignoring the most powerful wizard that was barreling toward them. 汽$0HβHζ(テフフフフフフフフフフフフフH・(DキHH広$0陏&・汽$0タHζ(テフフフフフフフフフフフフフフフH WH・ H櫛H・t9HνHテ<"
Anyone know how I can get rid of them?
If you already have a name and an age, it's just a matter of inserting them into the correct place in sentence, right? So strcat(sentence, name) would work for name. age is a little trickier since you have to format the number first, and strcat won't do it for you. One solution would be to use sprintf(buf, "%d", age), and then concatenate buf (which is a scratch char array you would have to declare).
Any time you work with strings in C, you have to be concerned about having enough space in the target buffer. Your program can run out of space during both input and output. For the output, I would get rid of sentence altogether; since you just end up writing to stdout I would printf("%s", [part]) each part as you go along. For reading, scanf supports adding a length argument to the format string.
If you use one of the *printf functions, there are 2 things you must be careful about:
The arguments you pass are correct for the format string you use
Your buffer ends up null-terminated
Your current problem is with #1 - your format string promises 7 arguments to follow, but you only supply 6. snprintf grabs a "random" 7th value from the stack, interprets it as a char pointer, and copies whatever it finds there to sentence. You could see similar problems if your format string promised a char pointer but you placed an int in a given position. In this case the format string is a constant, so a smart compiler can validate that your format string matches the subsequent parameters. You'll want to get into the habit of taking compiler warnings seriously and not ignoring them.
The second point could be an issue if your sentence ended up bigger than your sentence buffer. If there is no room for a null-terminator, one won't be applied. You can check the return value of snprintf, or you can defensively always write a 0 to the last array position.