Read 2 data string - c

I have faced a problem with my program and I don't understand why. I read 2 data string and the program just skips the first read and jumps on the second one. I can't place the program here because is pretty big and I don't think anyone wants to waste time reading and understanding it.For example:
struct agenda {
char nume[20];
char prenume[20];
} vector[50];
void adaugare (){
printf("x=");
gets_s(vector[0].nume);
printf("y=");
gets_s(vector[0].prenume);
}
And when I build and run it, it only reads the second string.Edit:
struct agenda {
char nume[20];
char prenume[20];
}vector[50];
void adaugare();
void main() {
adaugare();
_getch();
}
void adaugare() {
int numar;
system("cls");
printf("\n\tCate contacte doriti sa adaugati? ");
scanf_s("%d", &numar);
for (int i = 0; i < numar; i++) {
printf("\nIntroduceti contactul %d\n", i);
printf("\tIntroduceti numele contactului %d: ", i);
gets_s(vector[i].nume);
printf("\tIntroduceti prenumele contactului %d: ", i);
gets_s(vector[i].prenume);
}
}
So in this case if you build and run it, it only reads the second string.

First thing you should elaborate what is gets_s() ? Is it your implementation of gets() or typo ? Instead of gets_s use fgets() to avoid buffering problem as mentioned in comments by #user3121023
// gets_s(vector[0].nume);
fgets(vector[0].nume,sizeof(vector[0].nume),stdin);
printf("y=");
// gets_s(vector[0].prenume);
fgets(vector[0].prenume,sizeof(vector[0].prenume),stdin);
EDIT(for visual c++) :
void adaugare() {
int numar;
system("cls");
printf("\n\tCate contacte doriti sa adaugati? ");
scanf_s("%d", &numar);
fflush(stdin);
for (int i = 0; i < numar; i++) {
printf("\nIntroduceti contactul %d\n", i);
printf("\tIntroduceti numele contactului %d: \n", i);
fflush(stdin);
gets_s(vector[i].nume);
printf("\tIntroduceti prenumele contactului %d: \n", i);
fflush(stdin);
gets_s(vector[i].prenume);
}
}
Because You must flush the input buffer(stdin) before using gets_s().
I hope it help's.

Related

How do i Fill in correctly My Struct Table without my Program Crashing?

I dont understand why my program crashs when tryign to fill in some DATA to my struct table declared in main ...
I know that a table is itself a pointer right ?
So basically i dont realy need to pass the address using &var when using scanf ... but thats when it crashes for me ..
when i tried to pass inputs by scanf("expression",&T[i].var) .. that worked but when showing my content i found out :
As you can see I couldnt event put something for my stat and values totally diffrent from the inputs .. probably cuz taking memory adresses .. but why the Id actually worked and also Lieu is null ?
so weird .
struct ChDep
{
int id;
int mins;
char nom[10];
char lieu[10];
double prix;
char stat;
};
//Function Fill some content to my Table
void RemplireHCD(int n, struct ChDep *T)
{
for (int i = 0; i < n; i++)
{
printf("Mission Numero : %d\n", i);
printf("ID = ");
scanf("%d", &T[i].id);
printf("\nDuree = ");
scanf("%d", &T[i].mins);
printf("\nNom = ");
scanf("%s", &T[i].nom);
printf("\nLieu = ");
scanf("%s", &T[i].lieu);
printf("\nPrix = ");
scanf("%lf", &T[i].prix);
printf("\nStatut = ");
scanf("%c", &T[i].stat);
system("cls");
}
}
//Function to show my Struct Table Content
void AfficherHCD(int n, struct ChDep *T)
{
system("cls");
for (int i = 0; i < n; i++)
{
printf("%d > [ ID: %d - Duree : %d - Libelee : %s - Lieu : %s - Prix : %lf - Statut : %c ]\n",
T[i].id, T[i].mins, T[i].nom, T[i].lieu, T[i].prix, T[i].stat);
}
}
int main(int argc, char *argv[])
{
struct ChDep HCD[20];
int n;
printf("SVP donnez Le Nombre de Mission A remplire : \n");
scanf("%d", &n);
system("cls");
RemplireHCD(n, HCD);
AfficherHCD(n, HCD);
getchar();
return 0;
}

gets(); function not waiting for input on second loop in C

I'm writing a program that simulates purchasing cars. The program works well the first go around, but after the purchase is made and the prompt asks for a name, gets() does not search for input. Here is my code.
#include <stdio.h>
int i;
int j=1;
int prices[5] = { 24000,28000,25000,20000,120000 };
int invent[5] = { 5,2,3,8,2 };
int purchased[5] = { 0, 0, 0, 0, 0 };
int main()
{
char name[50];
printf("Welcome to Buy-a-Car!\nPlease enter your name:\n");
gets(name);
printf("Welcome, %s. Here is our available inventory.\n", name);
sale();
return 0;
}
void sale()
{
while (i>0, j != 0) {
printf("1. Toyota Camry %d %d\n2. Honda CRV %d %d\n3. Honda Accord %d %d\n4. Hyundai Elantra %d %d\n5. Audi R8 %d %d", invent[0], prices[0], invent[1], prices[1], invent[2], prices[2], invent[3], prices[3], invent[4], prices[4]);
printf("\nWhich car would you like to purchase?\n");
scanf("%d", &i);
i = i - 1;
printf("How many would you like to purchase?\n(Note: To checkout, please press 0.)\n");
scanf("%d", &j);
if (j > invent[i])
printf("I'm sorry, that number is insufficient. Please try again.\n");
else
invent[i] = invent[i] - j;
purchased[i] = j;
}
checkout();
}
void checkout()
{
printf("Review of transaction:\n1. Toyota Camry %d %d\n2. Honda CRV %d %d\n3. Honda Accord %d %d\n4. Hyundai Elantra %d %d\n5. Audi R8 %d %d", purchased[0], prices[0], purchased[1], prices[1], purchased[2], prices[2], purchased[3], prices[3], purchased[4], prices[4]);
int total;
for (i = 0; i < 5; i++)
{
total = total + (purchased[i] * prices[i]);
}
printf("\n\nTotal: %d\n\n\n", total);
j = 1;
int purchased[5] = { 0, 0, 0, 0, 0 };
main();
}
It's because the '\n' char in buffer after use scanf, use scanf("%d%*c",&var); %*c prevents '\n' to skip line when gets is used
gets is not safe, use fgets(&str,sizeof(str),stdin);
After running scanf(), the Enter (and anything before) is still in the input buffer. You can clear it like this:
scanf("%*[\n]%*c");
or
while( getchar() != '\n' );
Now gets() won't return an empty string. But anyway, it's extremely discouraged to use it. Use fgets or scanf("%[^\n]") instead.
fgets(name, sizeof(name), stdin);
// or
scanf("%[^\n]", name);
Besides, don't call main() from anywhere in your program. Its behavior is undefined. You can wrap the whole stuff up in another function, and use a loop. An endless recursion call will surely end up blowing up the stack.

C: Array of Structs (Input into int array within array of structs)

Hi I have to create a database that stores students number, name and also stores an array of course marks (1-N) in C Programming Language.
Everything worked until I started coding for the array of course marks. Then every time I compiled the code it kept crashing as soon as it asked to input the course marks.
Can you please tell me where I'm going wrong in my programming for this task? I have attached it to this message.
The program worked for inputting the name, student number, however I could not get the program to input array of marks. I have asked how many course marks to be entered and then used a for loop within the "void insert(void)" function to keep inputting the course marks into the array *marks. I am referring specifically to lines 24 to 30 in my programming code.
Always at this point the program kept crashing and I could not proceed further to enter more names or print the stored student details.
I think there is a problem with this part:
for (i= 0; i < num_marks; i++)
{
printf("Enter Course Mark: \n");
scanf("%d", &(list[num_students].marks[num_marks]));
}
Anyway here is the full code:
#include <stdio.h>
#include <string.h>
struct student{
int number;
char name[10];
int marks[5];
};
struct student list[10];
int num_students = 0;
int num_marks = 0;
int *p;
void insert(void)
{
int student_number;
int i;
printf("Enter number: \n");
scanf("%d", &list[num_students].number);
printf("Enter NAME: \n");
scanf("%s", &list[num_students].name);
printf("Enter NO of courses: \n");
scanf("%d", num_marks);
for (i= 0; i < num_marks; i++)
{
printf("Enter Course Mark: \n" );
scanf("%d", &(list[num_students].marks[num_marks]));
}
num_students++; // HOW DO WE INPUT ARRAY MARKS??? MARK1: , MARK2: , MARK3 ,
}
void printtest(void)
{
int i;
for (i=0; i < num_students; i++)
{
printf("Name: \n");
puts(list[i].name);
printf("Number: %d \n", list[i].number);
printf("Mark: %d /100 \n", list[i].marks);
printf("\n");
}
}
int main(void)
{
int code;
int opt1;
int courses, i, k, j, counter;
for (;;){
printf("Enter operation code: \n");
printf("(1) ADD NEW STUDENT DETAILS: \n");
printf("(2) DISPLAY REPORT OF ALL STUDENTS: \n");
scanf(" %d", &code);
switch (code){
case 1 :
insert();
break;
case 2 :
printtest();
break;
default:
printf("Illegal code\n");
printf("\n");
}
}
}
Apart from what others pointed out, I'd like to draw your attention towards the following:
void insert(void)
{
int student_number;
int i;
printf("Enter number: \n");
scanf("%d", &list[num_students].number);
printf("Enter NAME: \n");
scanf("%s", &list[num_students].name);
printf("Enter NO of courses: \n");
scanf("%d", num_marks);
for (i= 0; i < num_marks; i++)
{
printf("Enter Course Mark: \n" );
scanf("%d", &(list[num_students].marks[num_marks]));
}
num_students++;
}
void printtest(void)
{
int i;
for (i=0; i < num_students; i++)
{
printf("Name: \n");
puts(list[i].name);
printf("Number: %d \n", list[i].number);
printf("Mark: %d /100 \n", list[i].marks);
printf("\n");
}
}
There are three problematic statements:
scanf("%s", &list[num_students].name); This is why beginners should use compilers with all warnings enabled.
printf("Mark: %d /100 \n", list[i].marks); What did you declare marks as in the first place?
scanf("%d", num_marks); Seems like you put & operator where not needed and ignore where needed. Read your textbook before asking a question next time.
Seems like you're having a tough time understanding the concept of arrays and pointers. Read your text book thoroughly before venturing into the world of pointers. If you don't use them correctly, even compiler can't help you.
Also, even if I don't expect your program to have a robust input mechanism, at least array bounds checking is expected. Learn good habits from the beginning. They'll save a lot of your time while debugging later.
Seems to be an error in:
for (i= 0; i < num_marks; i++)
{
printf("Enter Course Mark: \n" );
scanf("%d", &(list[num_students].marks[num_marks]));
}
The crash is probably because num_marks as index indexes beyond the array. Change to:
for (i= 0; i < num_marks; i++)
{
printf("Enter Course Mark: \n" );
scanf("%d", &(list[num_students].marks[i]));
}

Strange error while adding a feature to my little game (0xC0000005)

Hello everyone,
I decided some time ago to write my own version of Minesweepers as some practice and I did it. The game ran perfectly, but after deciding to add a "Choose difficulty" option the window freezes and I get an error message, saying that the program does not respond. Also the line 0xC0000005 appeares. I have tryed many, many things: moving code from main() to a seperate function(now all in int playGame()), allocating some more memory in the heap, even creating a seperate .c file to store some piece of the code, but nothing worked sofar. I came back to the code after a few weeks, but I still have no clue why it is happening.
Can anyone help me with this? I hope my code is not hard to read. I added some comments explaining what is what. I am still new to C.
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include "difLvl.c"
int displayFiled(char **field); //prints out the map of the field
int combine(char answer, int answer1); //combines user input and field numeration
int Randomizer(int **mineArray); //generates random mine map
int difficulty();
int playGame();
int main(){
int playGame();
playGame();
system("PAUSE");
return 0;
}
int Randomizer(int **mineArray){
int difficulty();
int i, j;
srand(time(NULL));
int mines;
int placeMine;
int totalMines;
//int difLvl=2;
int difLvl=difficulty();
for(i=0, totalMines=0; i<10; i++){
for(j=0, mines=0; j<10 && mines<difLvl; j++){
placeMine= rand() % 2;
mineArray[i][j] = placeMine;
if(placeMine==1){
++mines;
};
};
totalMines+=mines;
};
return totalMines;
}
int displayFiled(char **field){
int i, j;
printf(" A B C D E F G H I J\n");
printf(" --------------------\n");
for (i=0; i<10; i++){
if (i==9){
printf("%d |", i+1);
}else{
printf("%d |", i+1);
};
for (j=0; j<10; j++){
printf("%c ", field[i][j]);
if (j==9){
printf("\n");
};
};
};
printf("\n");
return 0;
}
int playGame(){
int displayFiled(char **field);
int combine(char answer, int answer1);
int Randomizer(int ** mineArray);
char Y_char; //column as character (a, b, c etc.)
int X; //row
int Y; //Y_char converted to a number
int **mineArray; //stores the map of mines
char **fieldDisplay; //prints out the map of the field
int i, j; //counters
int life=1;
int movePl=0; //no dying on the first move
int globalMines; //number of mines placed
int openedFields=0; //counts the number of fields opened
//int difLvl;
//int difficulty();
//difLvl= difficulty();
/*disabled the trhee lines above while I was trying some solutions*/
/*int difficulty() is now called from int Randomizer()*/
system("cls");
/*Allocates memory to mineArray*/
mineArray= (int*)calloc(10, sizeof(int));
for(i = 0; i < 10; i++){
mineArray[i] = calloc(10, sizeof(int));
};
/*Allocates memory to fieldDisplay*/
fieldDisplay= (int*)calloc(10, sizeof(int));
for(i = 0; i < 10; i++){
fieldDisplay[i] = calloc(10, sizeof(int));
};
/*default look of fields with ?*/
for (i=0; i<10; i++){
for (j=0; j<10; j++){
fieldDisplay[i][j]='?';
};
};
globalMines= Randomizer(mineArray);
while(life==1 && openedFields<(100-globalMines)){
/*for checking purposes only*/
/*for (i=0; i<10; i++){
for (j=0; j<10; j++){
printf("%d ", mineArray[i][j]);
if (j==9){
printf("\n");
};
};
};*/
//printf("\nDifficulty level %d\n", difLvl);
printf("Total number of mines is %d\n\n", globalMines);
printf("\tMove nr. %d\n\n", movePl+1);
displayFiled(fieldDisplay);
printf("Which field do You want to activate?\nType first the letter, space and then the number (A 1, B 10 etc.)\n");
scanf("%c %d", &Y_char, &X);
if (Y_char >= 'A' && Y_char <= 'Z'){
Y = Y_char - 'A';
}else if(Y_char >= 'a' && Y_char <= 'z'){
Y = Y_char - 'a';
};
/*checks if a field is a mine*/
/*X-1 because the player chooses from 1 to 10*/
if (mineArray[X-1][Y]==0 && fieldDisplay[X-1][Y]=='?'){
movePl++;
fieldDisplay[X-1][Y]='0';
openedFields=openedFields+1;
OPEN : if (((X-2)<10) && ((X-2)>=0)){
if (mineArray[X-2][Y]==0 && fieldDisplay[X-2][Y]=='?'){
fieldDisplay[X-2][Y]='0';
openedFields=openedFields+1;
};
};
if ((X<10) && (X>=0)){
if (mineArray[X][Y]==0 && fieldDisplay[X][Y]=='?'){
fieldDisplay[X][Y]='0';
openedFields=openedFields+1;
};
};
if (((Y+1)<10) && ((Y+1)>=0)){
if (mineArray[X-1][Y+1]==0 && fieldDisplay[X-1][Y+1]=='?'){
fieldDisplay[X-1][Y+1]='0';
openedFields=openedFields+1;
};
};
if (((Y-1)<10) && ((Y-1)>=0)){
if (mineArray[X-1][Y-1]==0 && fieldDisplay[X-1][Y-1]=='?'){
fieldDisplay[X-1][Y-1]='0';
openedFields=openedFields+1;
};
};
system("cls"); //clears console screen
}else if (mineArray[X-1][Y]==0 && fieldDisplay[X-1][Y]=='0'){
system("cls");
printf("You can't choose an already opened field!\n\n");
}else if(mineArray[X-1][Y]==1 && movePl==0){
/*only activates on the first turn if players hits mine*/
movePl++;
mineArray[X-1][Y]= 0;
fieldDisplay[X-1][Y]='0';
globalMines=globalMines-1;
goto OPEN;
system("cls");
}else{
system("cls");
printf("YOU DIED ! YOU DIED ! YOU DIED !\n\n");
printf("Moves successfully made: %d\n\n", movePl-1);
fieldDisplay[X-1][Y]='1';
displayFiled(fieldDisplay);
--life;
};
};
if(openedFields==(100-globalMines)){
printf("Congratulations! You won the game!\n\n");
displayFiled(fieldDisplay);
};
for(i = 0; i < 10; i++){
free(mineArray[i]);
};
free(mineArray);
for(i = 0; i < 10; i++){
free(fieldDisplay[i]);
};
free(fieldDisplay);
return 0;
}
The difLvl.c file:
#include <stdio.h>
#include <stdlib.h>
int difficulty(){
int difLvl;
while(1){
printf("Please choose a difficulty level:\n");
printf("Easy-1\nNormal-2\nNightmare-3\n");
printf("Your answer: ");
scanf(" %d", &difLvl);
if(difLvl>=1 && difLvl<=3){
break;
}else{
system("cls");
continue;
};
};
system("cls");
return difLvl;
}
I created it, because I thought that maybe main() had too many code in it and that maybe that was why the difficulty option wasnt working right.
EDIT
After the user is promped to enter the difficulty level, the mine map is created, but after choosing a filed, the program crashes.
SOLVED
scanf("%c %d", &Y_char, &X);
changed to
scanf(" %c %d", &Y_char, &X);
First, you don't allocate your two-dimensional fields correctly. The "outer" field must hold int *, not just int:
mineArray = calloc(10, sizeof(*mineArray));
for (i = 0; i < 10; i++) {
mineArray[i] = calloc(10, sizeof(*mineArray[i]));
}
Another potential source of the segmentation fault is that Y might end up uninitialised and therefore with a garbage value. The cause is the scanf:
scanf("%c %d", &Y_char, &X);
Most scanf formats skip white space before the conversion, but %c doesn't. It is very likely that you read the newline character as the char for %c when you expect to read a letter. Because the new-line character is white space, you can hot-fix the by placing a space before the %c? format:
scanf(" %c %d", &Y_char, &X);
(I say hot-fix, because it isn't a good solution. scanf doesn't treat new-line characters specially; they are just space. A better solution might be to read a line first with fgets and then scan that with sscanf. At least you can treat each line as frash input. (And your input really should ensure that bad input is ignored.)
Lastly, it is strange that you include a *.c file. If you want to spread ypur project over various files, which is basically a good idea, you should write a header file for each *.c, which has the file's interface. Include the header files in other *.c files; compile the *.c files into objects separately and then link them. This process is usually controlled by Makefiles or Projects.

"Program has stopped working"

When I run the program the first for loop works just fine but then I get the "Program has stopped working" message before going into the second while loop. Is there an error in my coding and if so how can I fix it?
#include<stdio.h>
double Combat(int x, int y, char mons[20]);
int main(void)
{
int monsters, i, target, alive;
while(1)
{
printf("ENTERING COMBAT\n\nHow many monsters?> ");
scanf(" %d", &monsters);
char monster[monsters][20];
int monstermaxhp[monsters];
int monsterhp[monsters];
for(i=0;i<monsters;++i)
{
printf("\n\nNO SPACES\n\nEnter Monster %d's name> ", i+1);
scanf("%s", &monster[i]);
printf("\n\nEnter %s's hitpoints> ", monster[i]);
scanf("%d", &monstermaxhp[i]);
monsterhp[i]=monstermaxhp[i];
}
alive=1;
while(alive==1)
{
for(i=0;i<monsters;++i)
{
printf("\n\n%d:%s%3c%3d/%d", i+1, ' ',monsterhp[i],monstermaxhp[i]);
}
printf("\n\nSelect Target> ");
scanf("%d", &target);
i=target-1;
monsterhp[i]=Combat(monsterhp[i],monstermaxhp[i],monster[i]);
for(i=0;i<monsters;++i)
{
if(monsterhp[i]<=0)
alive=0;
}
}
}
return(0);
}
double Combat(int x, int y, char mons[20])
{
int damage, plrroll, monroll;
printf("\nRoll for %s> ", mons);
scanf("%d", &monroll);
printf("\nRoll for Player> ");
scanf("%d", &plrroll);
if(plrroll>monroll)
{
printf("\nHIT! Roll for damage> ");
scanf("%d", &damage);
x=x-damage;
}
else
{
printf("\nMISS! :P\n");
}
return(x);
}
Change:
printf("\n\n%d:%s%3c%3d/%d", i+1, ' ',monsterhp[i],monstermaxhp[i]);
to
printf("\n\n%d: %s %3d/%d", i+1, monster[i], monsterhp[i], monstermaxhp[i]);
You're trying to printf in the wrong order. I think you missed out the monster's name! There's no need for the 3 spaces using %c either, so I've inlined the spaces in your format string instead.
You now get an output like:
1: Good 1/1
2: Evil 2/2
Ok just a few problems with your code :
you are declaring arrays : monster,monstermaxhp and monsterhp everytime you loop in outer while
its not return(0); .. its return 0;
in for loop do post increment ( change ++i to i++)
Fix your printf statement to this:
printf("\n\n%d:%s%3c%3d/%d", i+1, monsterhp[i], ' ', monstermaxhp[i]);
Also change :
scanf("%s", &monster[i]);
to this:
scanf("%s", monster[i]);

Resources