different behavior xcode and Dev-C++ - c

Just beginning to learn C.
if I compile the following code in Dev-C++ the program runs fine.
If I compile in Xcode 3.2.6 it looks like in the screenshot.
I tried different compiler settings in Xcode but the behavior is still the same.
Any ideas on this?
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[])
{
char artist[30];
char album[30];
int tracks;
char albumsingle;
float price;
printf("Please enter CD informations below. \n \n");
printf("enter cd artist: ");
scanf("%[^\n]", artist);
printf("enter cd title: ");
fflush(stdin);
scanf("%[^\n]", album);
printf("enter no. of tracks: ");
fflush(stdin);
scanf("%d", &tracks);
printf("enter a for album s for single: ");
fflush(stdin);
scanf("%c", &albumsingle);
printf("enter price: ");
fflush(stdin);
scanf("%f", &price);
printf("\n\n\nartist: %s\n", artist);
printf("album: %s\n", album);
printf("track no.: %d\n", tracks);
if (albumsingle == 'a'){
printf("cd type: album\n");
} else {
printf("cd type: single\n");
}
printf("price: %.2f EUR\n\n", price);
system("PAUSE");
return 0;
}

My guess is it has to do with the system("PAUSE"); statement. Xcode is used on OSX, which is a UNIX variant, and doesn't have the command pause.
Instead why not just ask the user to press the enter key manually instead? Like this:
printf("Press the ENTER key to continue.\n");
int c;
do
{
c = fgetc(stdin);
} while (c != '\n' && c != EOF);
It has the advantage of working on most systems.

fflush(stdin);
Causes an Undefined Behavior, and hence your program shows different behavior on different compilers.
Reference C standard:
int fflush(FILE *ostream);
ostream points to an output stream or an update stream in which the most recent operation was not input, the fflush function causes any unwritten data for that stream to be delivered to the host environment to be written to the file; otherwise, the behavior is undefined.

PAUSE is a Windows, not a Unix command ... so that won't work on the Mac. Use something like getchar() instead if you just want to pause the program at the end.

Include a header file Conio.h and use getch() function whenever you want to hold screen.

Related

Making a mad libs game

I am trying to make a mad libs game but every time I test the first two scanf functions work, but the fgets function is not working how it should be.
it keeps printing the same things I want it to but it's showing the mad libs text before the user has a chance to type in the fgets input
#include <stdio.h>
#include <stdlib.h>
int main(void) {
char color[20];
char COL2[20];
printf("Enter a color: ");
scanf("%s", color);
printf("Enter a another color: ");
scanf("%s", COL2);
printf("Enter a celebrity name: \n");
char celebrity[15];
fgets(celebrity, 15, stdin);
printf("Roses are %s", color);
printf("Violets are %s", COL2);
return 0;
}
fscanf(stdin, "%15s", celebrity);
It worked on my laptop, so it should be fine.
Also fscanf is better and safer usually from what I've heard. Because it checks for end of line.

No output over SSH before waiting for input via scanf()

I have a file called get_int.c on a remote Unix system, containing the following:
#include <stdio.h>
int main() {
int input;
printf("Give an integer: ");
fflush(stdout);
scanf("%d", &input);
printf("Try again: ");
scanf("%d", &input);
printf("You said... %d\n", input);
return 0;
}
I have a command to compile and run this file from my local WSL:
sshpass -f pass.txt ssh username#remote.host.address "cd path/to/file/ && gcc get_int.c && a.out"
When I execute this command, I successfully get the prompt Give an integer: and provide one and press enter. Then, however, I do not get the prompt Try again:. I can still type an integer (123) and press enter. When I do, it then prints Try again: You said... 123
As you can see, no printing occurs until I either fflush(stdout) or the program ends. Can I possibly modify my ssh command so that output goes to the local terminal without having to fflush before every scanf?
Output to stdout does not seem to be flushed when reading from stdin on your system in the specific circumstances described. You must flush stdout explicitly with fflush() before every call to scanf():
#include <stdio.h>
int main() {
int input;
printf("Give an integer: ");
fflush(stdout);
scanf("%d", &input);
printf("Try again: ");
fflush(stdout);
scanf("%d", &input);
printf("You said... %d\n", input);
return 0;
}
Alternately, you can set the output stream as unbuffered and won't need to flush it at all:
#include <stdio.h>
int main() {
int input;
setvbuf(stdout, NULL, _IONBF, 0);
printf("Give an integer: ");
scanf("%d", &input);
printf("Try again: ");
scanf("%d", &input);
printf("You said... %d\n", input);
return 0;
}

How to read a specific line from binary file into a structure C

Essentially, I printed to a binary file using fseek() and fwrite(). However, I want to read the contents from a specific line into a structure. I also used fseek() and fread() to obtain the contents. I prompted the user to enter a code. From what I have learnt, I would use the value obtained from the user to use in the fseek function to get the specific line to start read from. Apparently, the fseek to read the contents does not work, I am getting gibberish essentially when it is displayed on the screen. Assistance is greatly appreciated.
#include <conio.h>
#include <stdio.h>
typedef struct registered
{
int compcode;
char compname[20];
int pinID;
int custID;
char IDtype[15];
int compID;
}REGISTERED;
void AddUpdate(REGISTERED info);
void SellPetrol();
void main(){
REGISTERED info = {0, "Apple", 0, 0, "passport", 0};
REGISTERED list;
AddUpdate(info);
SellPetrol();
}
void AddUpdate(REGISTERED info){
int choice;
FILE *registryfile = NULL;
registryfile = fopen("Sales.dat", "ab");
if (registryfile == NULL){
perror("Error: ");
}
else{
do{
printf("Company Code: ");
scanf("%d", &info.compcode);
printf("Company Name: ");
scanf("%s", &info.compname);
printf("Pin: ");
scanf("%d", &info.pinID);
printf("Customer ID: ");
scanf("%d", &info.custID);
printf("ID type: ");
scanf("%s", &info.IDtype);
printf("Company ID: ");
scanf("%d", &info.compID);
fseek(registryfile, (info.compcode - 1) * sizeof(REGISTERED), SEEK_SET);
fwrite(&info, sizeof(REGISTERED), 1, registryfile);
printf("Enter choice: ");
scanf("%d", &choice);
}while(choice == 1);
}
printf("\tCompany Code: %d\t\n", info.compcode);
printf("\tCustomer ID: %d\t\n", info.custID);
fclose(registryfile);
}
void SellPetrol(){
int code = 0, PIN;
REGISTERED list;
FILE *registryfile = NULL;
registryfile = fopen("Sales.dat", "rb");
if (registryfile == NULL){
perror("Error: ");
}
else{
printf("Please enter the company code: ");
scanf("%d", &code);
// printf("Please enter the PIN: ");
// scanf("%d", &PIN);
rewind(registryfile);
fseek(registryfile, (code - 1) * sizeof(REGISTERED), SEEK_SET);
fread(&list, sizeof(REGISTERED), 1, registryfile); //reads data into list
fflush(stdin);
printf("Company Code: %d\n", list.compcode);
printf("Company Name: %s\n", list.compname);
printf("Pin: %d\n", list.pinID);
printf("Customer ID: %d\n", list.custID);
printf("ID Type: %s\n", list.IDtype);
printf("Company ID: %d\n", list.compID);
}
fclose(registryfile);
}
It seems whichever method you're using to learn C is causing troubles, as the mistakes you seem to be making are common. I suggest reading a book, such as K&R2E... Do the exercises as you stumble across them; don't move on until you've completed them, and ask questions about them if necessary.
Don't fflush(stdin). fflush doesn't do what you think it does.
Check return values for functions such as fopen, scanf, fseek, fread, even fwrite. You'll probably find that your fread or scanf is returning a value indicating failure, hence the gibberish you speak of.
Be aware that C uses pass-by-value semantics ONLY. The source of at least one error in your code is a misunderstanding regarding these semantics. Namely, AddUpdate has no way to modify the variable declared within main, as it recieves a copy of that variable; at this point it seems void AddUpdate(REGISTERED info) should be void AddUpdate(void) and info should be declared within AddUpdate.
scanf("%s", &info.compname); probably doesn't do what you think it does. The %s directive tells scanf to read (metalinguistically speaking) a word (that is, a whitespace-delimitered token), not a line (a newline delimitered token), of user input. You probably want int x = scanf("%19[^\n]", info.compname); or better yet, char *x = fgets(info.compname, sizeof info.compname, stdin);...
void main() is unportable, and so is #include <conio.h>. You probably want int main(void) and ... you don't appear to be using any functions from <conio.h>, so you probably don't want anything in place of that. In C99, a main function that has no return statement will implicitly return 0; without a warning issued.

comparing strings and printing stored strings in C

I am having trouble getting this program to print the strings I enter properly. It keeps telling me that I have not entered data, even when I have. I also can't get the strings to compare to run my if statement. Thank for any help.
#include <stdio.h>
//function prototype
void enterPerson();
void enterChoice();
//global variables
char person[30];
char choice;
int main(void) {
enterPerson();
enterChoice();
printf("Please try the Precipitation Program again.\n");
return 0;
}
void enterPerson(){
// Ask for person name
printf("Please enter name:\n");
scanf("%s", &person);
//-------------------------------------------
printf("person is %s\n", person);
//-------------------------------------------
}
void enterChoice(){
//initialize choice
choice = "M";
//ask what they choose
printf("Do you choose test or rate? (Enter T for test R for rate)\n");
scanf("%c", &choice);
printf("Xchoice is: %c\n", choice);
if ((choice == 'T')||(choice == 'R')){
printf("choice is: %c\n", choice);
}
else{
printf("Incorrect or no data was input at this time\n");
}
}
As mentioned in comments, there are at least 3 problems:
scanf("%s", person); - do not take the address of char array.
scanf(" %c", &choice); - insert space to ignore whitespace.
choice = 'M'; - "M" is a string literal, while choice is char.
There is a linefeed (0xa) character left in the input buffer. You can see it by printing the choice variable after your scanf line with:
scanf("%c", &choice);
printf("c: %x\n", choice);
There are several options to get rid of this. Easiest is explained here.
Also there is a problem in:
scanf("%s", &person);
Character array name in C points to the first character, so you should fix this with:
scanf("%s", person);

C prompt ordering for reading string with getchar() [duplicate]

This question already has answers here:
Why is getchar() reading '\n' after a printf statement?
(3 answers)
Closed 9 years ago.
This is a newbie question. I am new to C programming. I have the following code which does not prompt for 'Name' Onece the 'Age' is entered, it bypass the 'Name section.
#include <stdio.h>
int main()
{
char name[30],ch;
int age;
printf("Enter age : ");
scanf("%d", &age);
int i=0;
printf("Enter name: ");
while((ch = getchar())!='\n')
{
name[i]=ch;
i++;
}
name[i]='\0';
printf("Name: %s\n",name);
printf("Age : %d\n", age);
return 0;
}
After reading first prompt it bypass the second prompt which is using getchar() function. But if I change the order of prompt to ask for 'Name' first and then 'Age' it works fine.
The working code.
#include <stdio.h>
int main()
{
char name[30],ch;
int age;
int i=0;
printf("Enter name: ");
while((ch = getchar())!='\n')
{
name[i]=ch;
i++;
}
name[i]='\0';
printf("Enter age : ");
scanf("%d", &age);
printf("Name: %s\n",name);
printf("Age : %d\n", age);
return 0;
}
My coding IDE is CodeBlock and my compiler is GNU C Compiler (mingw32-gcc.exe)
Please help me to breakthrough.
A few improvements/advices to the code in the question:
the type of the return value of getchar() is int, so the type of ch also should be int
you could (and should, I believe) use format %s to read the name, this is easier and the leading white spaces in the input stream would not be a problem
the user of the code could give a name which contains more than 30 characters, and this input could crash your program, so you should protect your code for this possibility. You have two options:
a. use format '%29s" to read the name
b. change the definition of name to char *name, read it by scanf("%ms", &name);, and call free(name); after you do not need it anymore
Here is an example, in which the name can be very long and can include spaces:
#include <stdio.h>
#include <stdlib.h>
int
main(int argc, char *argv[])
{
char *name;
int age;
printf("Enter name: ");
scanf("%m[^\n]", &name);
printf("Enter age: ");
scanf("%d", &age);
printf("Name: %s\n", name);
printf("Age : %d\n", age);
free(name);
exit(EXIT_SUCCESS);
}
And here is a run of it:
$ ./a.out
Enter name: a very looooooooooooooooooooooooooooooooooooooooooooooong name
Enter age: 12
Name: a very looooooooooooooooooooooooooooooooooooooooooooooong name
Age : 12
In first code the \n character left behind by the scanf is read by getchar. This makes the condition (ch = getchar())!='\n' in while loop false and the loop body never get executed.
You need to consume that \n character which comes up to the buffer along with the age you entered on pressing Enter key.
Putting the statement
while(getchar()!='\n');
after the scanf will consume all of the newline characters.
Your second code is working fine because %d skips white-space characters unlike %c specifiers.

Resources