this is my code and I have been getting constant nulls from it so I do need a help
#include<stdio.h>
#include<string.h>
int main () {
char jojo[100];
printf("name: ");
scanf("[^\n]*c", &jojo);
printf("Happy Birthday to %s.\n");
printf("\n");
return 0;
}
For starters in the call of scanf
scanf("[^\n]*c", &jojo);
you shall not use a pointer to the character array. Also you need to use the symbol '%' before the conversion specifiers.
Instead write
scanf("%[^\n]%*c", jojo);
In the call of printf you forgot to specify the argument that represents the array.
printf("Happy Birthday to %s.\n");
write
printf("Happy Birthday to %s.\n", jojo);
Here is a demonstrative program.
#include <stdio.h>
int main(void)
{
char jojo[100];
printf( "name: " );
scanf("%99[^\n]%*c", jojo );
printf( "Happy Birthday to %s.\n", jojo );
return 0;
}
The program output might look like
name: programmer Vaustin
Happy Birthday to programmer Vaustin
You probably want this:
#include<stdio.h>
#include<string.h>
int main() {
char jojo[100];
printf("name: ");
scanf("%s", jojo); // use the %s format specifier
// and remove the &
printf("Happy Birthday to %s.\n", jojo); // you forgot 'jojo' as second
// argument to printf
printf("\n");
return 0;
}
Explanations int the comments.
I am not able to flush stdin here, is there a way to flush it? If not then how to make getchar() to take a character as input from user, instead of a "\n" left by scanf() in the input buffer??
#include "stdio.h"
#include "stdlib.h"
int main(int argc,char*argv[]) {
FILE *fp;
char another='y';
struct emp {
char name[40];
int age;
float bs;
};
struct emp e;
if(argc!=2) {
printf("please write 1 target file name\n");
}
fp=fopen(argv[1],"wb");
if(fp==NULL) {
puts("cannot open file");
exit(1);
}
while(another=='y') {
printf("\nEnter name,age and basic salary");
scanf("%s %d %f",e.name,&e.age,&e.bs);
fwrite(&e,sizeof(e),1,fp);
printf("Add another record (Y/N)");
fflush(stdin);
another=getchar();
}
fclose(fp);
return 0;
}
EDIT: updated code, still not working properly
#include "stdio.h"
#include "stdlib.h"
int main(int argc,char*argv[]) {
FILE *fp;
char another='y';
struct emp {
char name[40];
int age;
float bs;
};
struct emp e;
unsigned int const BUF_SIZE = 1024;
char buf[BUF_SIZE];
if(argc!=2) {
printf("please write 1 target file name\n");
}
fp=fopen(argv[1],"wb");
if(fp==NULL) {
puts("cannot open file");
exit(1);
}
while(another=='y') {
printf("\nEnter name,age and basic salary : ");
fgets(buf, BUF_SIZE, stdin);
sscanf(buf, "%s %d %f", e.name, &e.age, &e.bs);
fwrite(&e,sizeof(e),1,fp);
printf("Add another record (Y/N)");
another=getchar();
}
fclose(fp);
return 0;
}
Output:
dev#dev-laptop:~/Documents/c++_prac/google_int_prac$ ./a.out emp.dat
Enter name,age and basic salary : deovrat 45 23
Add another record (Y/N)y
Enter name,age and basic salary : Add another record (Y/N)y
Enter name,age and basic salary : Add another record (Y/N)
fflush(stdin) is undefined behaviour(a). Instead, make scanf "eat" the newline:
scanf("%s %d %f\n", e.name, &e.age, &e.bs);
Everyone else makes a good point about scanf being a bad choice. Instead, you should use fgets and sscanf:
const unsigned int BUF_SIZE = 1024;
char buf[BUF_SIZE];
fgets(buf, BUF_SIZE, stdin);
sscanf(buf, "%s %d %f", e.name, &e.age, &e.bs);
(a) See, for example, C11 7.21.5.2 The fflush function:
int fflush(FILE *stream) - If stream 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.
Update: You need to add another getchar() at the end of your loop to consume the '\n' that follows the Y/N. I don't think this is the best way to go, but it will make your code work as it stands now.
while(another=='y') {
printf("\nEnter name,age and basic salary : ");
fgets(buf, BUF_SIZE, stdin);
sscanf(buf, "%s %d %f", e.name, &e.age, &e.bs);
fwrite(&e,sizeof(e),1,fp);
printf("Add another record (Y/N)");
another=getchar();
getchar();
}
I would suggest reading the data you want to parse (up to and including the '\n') into a buffer and then parse it out using sscanf(). This way you consume the newline and you can perform other sanity checks on the data.
Use this instead of getchar():
char another[BUF_SIZE] = "y";
while( 'y' == another[0] )
{
printf( "\nEnter name,age and basic salary : " );
fgets( buf, BUF_SIZE, stdin );
sscanf( buf, "%s %d %f", e.name, &e.age, &e.bs );
fwrite( &e, sizeof(e) , 1, fp );
printf( "Add another record (Y/N)" );
fgets( another, BUF_SIZE, stdin );
}
It's not a good practice to use fflush( stdin ) as it has undefined behavior. Generally, functions like scanf() leaves trailing newlines in stdin. So, it is better to use functions that are "cleaner" than scanf(). You can replace your scanf() with a combination of fgets() and sscanf() and you can do away with fflush( stdin ).
I would recommend the fgets()+sscanf() approach that a lot of other people have suggested. You could also use scanf("%*c"); before the call to getchar(). That will essentially eat a character.
If you are doing this under windows, you can use winapi to flush input buffer before your getch().
#include <windows.h>
hStdin = GetStdHandle(STD_INPUT_HANDLE);
FlushConsoleInputBuffer(hStdin);
-or-
#include <windows.h>
FlushConsoleInputBuffer(GetStdHandle(STD_INPUT_HANDLE));
As others already pointed out, you should not write a struct to a file. Instead, try to write the data in a formatted manner. This way your text file can be parsed line-by-line by finding the last and second-to-last delimiters, for example semicolons. Keep in mind that certain characters like '-' or '.' may occur in the stringified float field.
int write_data(FILE *fh, struct emp *e) {
if(fh == NULL || e == NULL)
return -1;
fprintf(fh, "%s;%d;%f", e->name, e->age, e->bs);
return 0;
}
The other thing is how everybody keeps recommending the same scanf family of functions, but nobody ever checks whether the return value is equal to the number of fields to be read. I think that is a bad idea, effectively asking for trouble. Even with the strtol/strtod way you need error checking:
int parse_int(char *buf, long *result) {
if(buf == NULL || result == NULL)
return -1;
errno = 0;
*result = strtoul(buf, NULL, 0);
if(errno != 0) {
perror("strtoul");
return -1;
}
return 0;
}
the two code examples above return silently which is fine if you plan to call them using existing objects all the time; consider printing an error message, though, and illustrate in your documentation that people should check the return values when using your functions.
stdin is not something flushable, you can flush only output streams. I.e. you don't need to call flush on stdin at all.
I am new to "C programming" and I have Googled for my answer, but I can't seem to get what I am looking for. I am making a simple 2 question program. The code is listed below:
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
char characterName[] = "Mike";
int age = 0;
printf("Enter your age, %s.\n", characterName);
scanf("%d", &age);
printf("Your being %d is old older than me and my brother "
"which was the first computer.Hahaaa.... \n", age);
return 0;
}
This is the next question:
char str[50];
{
printf("Anything to say about my comment? \n");
scanf ("%[^\n]", str);
printf("That was a good answer. I wasn't expecting that from you.\n");
return 0;
}
How about a function to ask a question, and return a response?
#include <stdio.h>
/*
* Prompt the user with the given question, return their
* input in answer, up to max_answer_length bytes
* returns 1 for ok, 0 on error.
*/
int askQuestion(const char *question, char *answer, const size_t max_answer_length)
{
int input_ok = 1;
// Show the user the question
printf( "%s: ", question );
// Throw away any existing input in the user's input-queue
// (like if they answered with a really-long string previously)
fflush(stdin);
// Read a line of input from the user into <answer>, but not more
// than <max_answer_length>-1 bytes are accepted (see fgets() for details)
// If the fgets() returns EOF or an error, make sure we remember it
if ( fgets( answer, max_answer_length, stdin ) == NULL )
input_ok = 0;
// return whether there was an error on input
return input_ok;
}
int main(void)
{
char answer_buffer[200];
askQuestion( "What is your favourite fruit?", answer_buffer, sizeof(answer_buffer) );
printf( ">> %s\n", answer_buffer );
askQuestion( "How long have you been programming C?", answer_buffer, sizeof(answer_buffer) );
printf( ">> %s\n", answer_buffer );
return 0;
}
I want the program to ask the user for a number, and if the user does not enter a number the program will say "input not a integer."
Thx for the help guys!
I propose this (it doesn't handle integer overflow):
#include <stdio.h>
int main(void)
{
char buffer[20] = {0}; // 20 is arbitrary;
int n; char c;
while (fgets(buffer, sizeof buffer, stdin) != NULL)
{
if (sscanf(buffer, "%d %c", &n, &c) == 1)
break;
else
printf("Input not integer. Retry: ");
}
printf("Integer chosen: %d\n", n);
return 0;
}
EDIT: Agreed with chux suggestions below!
One possible way: use scanf() function to read the input. It returns the number of items it successfully read.
Another way: read the input as string with scanf() of fgets() and then try to parse it as integer.
I'm trying to find the bug here, but still don't get it.
I've been debugging and googling it and found some close topics, but there are only solutions which I don't need ATM, and I'm curious why this code is not working:
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#define BUFFER 256
int main()
{
int missionCode;
char *desc = (char*)malloc(sizeof(char)*BUFFER);
do {
printf("Please enter the mission code (or -1 for exit): ");
scanf("%d", &missionCode);
fflush(NULL);
if (missionCode==-1)
return 1;
} while (missionCode>10);
do {
printf("Please enter a string:\n");
scanf("%[^\n]s", desc); //it doesn't stop here!
fflush(NULL);
if (!strcmp("exit",desc))
return 1;
} while (strlen(desc)<20);
printf("your string:\n%s", desc);
return 0;
}
There's something wrong with the scanf\flushall in the second loop, but I don't find out what.
BTW, this is C ofcourse.
scanf("%d", &missionCode);
leaves the newline in the buffer, so
scanf("%[^\n]s", desc);
immediately finds one and stops. You can add a space
scanf(" %[^\n]s", desc);
to the format to skip initial whitespace.