I have to enter random names and weights and finish the loop when I hit enter instead of the name. However the way I used to detect the enter does not serve to take the name so getting two variables. The question is how to put the enter of the test and name using the same variable
#include <stdio.h>
#include <string.h>
#include <ctype.h>
int main() {
int c, weight[1000], i = 0;
char name[1000];
puts ("Enter the person's name or only enter to end the program");
if ((c = getchar() == '\n')) {
} else {
while (c != '\n') {
printf("Enter the name");
scanf("%s", &nome[i]);
i++;
printf("Enter the \n");
scanf("%i", &weight[i]);
}
}
return 0;
}
Here is a simple example
#include <stdio.h>
#include <string.h>
int main(void)
{
char name[1000] = {0}; // initialise
puts ("Enter the person's name or only enter to end the program");
if (fgets(name, sizeof(name), stdin) != NULL) {
name [ strcspn(name, "\r\n") ] = 0; // remove trailing newline etc
if (strlen(name)) {
printf("The name entered was: %s\n", name);
}
else {
printf("You did not enter a name\n");
}
}
return 0;
}
First off, names is an array of characters and you're treating it like an array of strings. Secondly, loops that need to exit based on input are most clearly expressed with break:
char *names[1000];
int count = 0;
while (1) {
char *r, buf[1000];
int len;
char *r = fgets(buf, 1000, stdin);
if (NULL == r) break; // EOF
if ((len = strlen(buf)) < 2) break; // NL only
r = malloc(len + 1);
if (NULL == r) break;
strcpy(r, buf);
names[count] = r;
count += 1;
...
}
...
Related
I am trying to give an if statement to check if a particular name is present in text file, then give access to it otherwise give error message.
#include <stdio.h>
#include <stdlib.h>
int main(){
printf("For person details, please enter the person name: \n");
FILE * fr = fopen("/home/bilal/Documents/file.txt","r");
int catch, i=0, index=0;
char ch[100];
printf("Enter your Name: ");
if (scanf("%s", )){ // Don't know what to put here?
perror("Error while reading!");
return 0;
}
catch = fgetc(fr);
while(catch != EOF){
ch[index] = catch;
if (ch[index] == ' '){
ch[index] = '\0';
printf("Here is your result: %s\n",ch);
index = 0;
i++;
}
else
index++;
catch = fgetc(fr);
}
fclose(fr);
return 0;
}
Simply the program firstly opens a file and asks for a user input and verifies if the provided content is case-sensitively matched with the file. If so, then it'll let the program access the entire file and display on the screen, to do that, we must use another FILE b/c the old *fp is already manipulated and in case it's reused, it may display wrong data.
#include <stdio.h>
#include <string.h>
int main(void) {
FILE *fp = fopen("file.txt", "r"); // for verification
FILE *fp1 = fopen("file.txt", "r"); // for future use
char ch[50], str[50];
short int FLAG = 0;
printf("Enter the string: ");
scanf("%s", &str); // asks for input
while (fscanf(fp, "%s", ch) != EOF) {
if (!strcmp(ch, str)) { // checks if a string matches provided by the user
printf("Found! Here's your details...\n\n");
FLAG = 1;
}
}
if (!FLAG == 1) { // no? exits.
printf("Not found, access denied!\n");
return -1;
}
fclose(fp);
int c = fgetc(fp1); // yes? let's go...
while (c != EOF) {
printf("%c", c); // displays containing data
c = fgetc(fp1);
}
fclose(fp1);
return 0;
}
You'll want to add a variable for your scanf output:
char name[100];
if (scanf("%s", name) != -1)
// ...
Then to compare both you'll use strcmp.
#include <string.h>
//...
if (strcmp(ch, name) == 0)
// both are equal
Note that you can access documentation for scanf and strcmp by typing man scanf or man strcmp in your terminal.
int main()
{
printf("For person details, please enter the person name and id card
number: \n");
printf("Enter your Name: ");
char personName[100];
scanf("%s", personName);
printf("Enter your card number: ");
int cardNumber;
if (scanf("%d", &cardNumber)){
printf("no error detected");
}
else{
printf("error while reading");
}
return 0;
}
The fixed code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main() {
printf("For person details, please enter the person name: \n");
FILE* fr = fopen("/home/bilal/Documents/file.txt", "r");
int catch, i = 0, index = 0;
char ch[100] = { 0 };
if (fr == NULL)
{
perror("Invalid file opening!");
return 1;
}
printf("Enter your Name: ");
fgets(ch, 100, fr);
size_t len = strcspn(ch, "\n");
ch[(len < 100) ? (len) : (99)] = 0; // For file safety checking
if (strlen(ch)) { // Don't know what to put here?
perror("Error while reading!");
return 1;
}
catch = fgetc(fr);
while (catch != EOF) {
ch[index] = catch;
if (ch[index] == ' ') {
ch[index] = '\0';
printf("Here is your result: %s\n", ch);
index = 0;
memset(ch, 0, 100);
i++;
}
else
{
index++;
}
catch = fgetc(fr);
}
fclose(fr);
return 0;
}
Working on a C knapsack program that will have a UI like interface, I have come to a point where I need for the user to be able to enter in characters for commands and while all of the ones which require only a simple one character input are quite simple I need to be able to allow the user to enter in a char and an int at the same time in the cases of adding or removing a number from the knapsack. While I know this can be done with two separate inputs from the user I'm wondering how can this be done in the same line without requiring the user to enter in two separate inputs. For example if the user types a 7 then it will add 7 to the knapsack.
CODE
#include <stdio.h>
#include "knapsack.c"
#include <stdlib.h>
#include <string.h>
int main()
{
listitemptr k2 = NULL;
char input[100];
int *returnval;
while(*input != 'q'){
printf("> ");
fgets(input, 100, stdin);
if(*input == 'p'){
KnapsackPrint(&k2);
}
else if(*input == 'a'){
printf("test\n");
sscanf(input, "%d", returnval);
printf("%d\n", *returnval);
}
else if(*input == 'r'){
}
else if(*input == 'l'){
}
else if(*input == 's'){
}
}
}
There are many solutions for your user input proble. I would suggest you read one line at a time with fgets() and parse it with sscanf():
#include <ctype.h>
#include <stdlib.h>
#include <string.h>
#include "knapsack.c"
int main() {
char input[100];
listitemptr k2 = NULL;
int i, returnval = 0;
char command;
for (;;) {
printf("> ");
if (!fgets(input, sizeof input, stdin))
break;
i = strspn(input, " \t\n"); /* skip blanks */
command = input[i++];
if (command == '#' || command == '\0') {
/* ignore comment lines and blank lines */
continue;
}
if (command == 'q' && input[i] == '\n')
break;
}
if (command == 'p') {
KnapsackPrint(&k2);
continue;
}
if (command == 'a') {
int item;
if (sscanf(input + i, "%i", &item) != 1) {
printf("invalid input\n");
continue;
}
KnapsackAdd(&k2, item);
continue;
}
// add more commands
printf("unknown command: %c\n", command);
}
return returnval;
}
I've been writing a HTML generator in C. After some research I found some code that allows me to take input in a array that allocates more memory to it if you need it. The problem is that after a couple of times, the code stops working.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
char *inputString(FILE *fp, size_t size);
int main(){
char *nameOfFile;
char *multiF;
int choice;
FILE *f;
printf("Name of file: ");
nameOfFile=inputString(stdin, 10);
f = fopen(strcat(nameOfFile,".html"),"w+");
fprintf(f, "<head>\n");
printf("Title: ");
multiF=inputString(stdin, 10);
fprintf(f, "\t<title>%s</title>\n</head>\n<body>\n", multiF);
while(choice != 99){ //Code stops working in while loop
printf("What do you want to do?\n");
printf("[1]Headings\n");
printf("[2]Paragraphs\n");
printf("[99]Exit\n");
scanf("%d",&choice);
switch(choice){
case 1:
printf("What size[1-6]? ");
scanf("%d",&choice);
if(choice < 7 && choice > 0){
printf("Heading[%d]:",choice);
multiF=inputString(stdin,10);
fprintf(f,"<h%d>%s</h%d>",choice,multiF,choice);
}else{
printf("Input something useful...\n");
}
break;
case 2:
printf("Paragraph: ");
multiF=inputString(stdin,10);
fprintf(f,"<p>%s</p>",multiF);
break;
case 99:
break;
default:
printf("Input something useful...\n");
}
}
fprintf(f,"</body>");
free(multiF);
free(nameOfFile);
return 0;
}
char *inputString(FILE *fp, size_t size){
char *str;
int ch;
size_t len=0;
str = realloc(NULL, sizeof(char)*size);
if(!str)return str;
while(EOF!=(ch=fgetc(fp)) && ch != '\n'){
str[len++]=ch;
if(len==size){
str = realloc(str, sizeof(char)*(size+=16));
if(!str)return str;
}
}
str[len++]='\0';
return realloc(str, sizeof(char)*len);
}
This should work:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
void inputString(char **str, FILE *fp); // No char *str, because we need to change the value of pointer str
int main(){
char *nameOfFile = malloc(0);
char *multiF = malloc(0); // Calling malloc() for later free()
int choice = 0; // Initialization
FILE *f;
printf("Name of file: ");
inputString(&nameOfFile, stdin);
nameOfFile = realloc(nameOfFile, strlen(nameOfFile) + 5); // You need more memory for ".html"
strcat(nameOfFile, ".html");
f = fopen(nameOfFile, "w");
fprintf(f, "<head>\n");
printf("Title: ");
inputString(&multiF, stdin);
fprintf(f, "\t<title>%s</title>\n</head>\n<body>\n", multiF);
while(choice != 99){
printf("What do you want to do?\n");
printf("[1]Headings\n");
printf("[2]Paragraphs\n");
printf("[99]Exit\n");
scanf(" %d%*c", &choice); // " %d" to discard whitespace characters, and "%*c" to consume '\n'
switch(choice){
case 1:
printf("What size[1-6]? ");
scanf(" %d%*c", &choice);
if(choice < 7 && choice > 0){
printf("Heading[%d]:", choice);
inputString(&multiF, stdin);
fprintf(f, "<h%d>%s</h%d>", choice, multiF, choice);
}else{
printf("Input something useful...\n");
}
break;
case 2:
printf("Paragraph: ");
inputString(&multiF, stdin);
fprintf(f, "<p>%s</p>", multiF);
break;
case 99:
break;
default:
printf("Input something useful...\n");
break;
}
}
fprintf(f, "</body>");
free(multiF);
free(nameOfFile);
fclose(f); // Don't forget to close the file
return 0;
}
void inputString(char **str, FILE *fp){
int ch;
size_t size = 1, index = 0;
free(*str);
*str = malloc(size);
if(!*str)
return;
while(EOF != (ch = fgetc(fp)) && ch != '\n'){
(*str)[index++] = ch;
if(index == size){
*str = realloc(*str, size += 16); // sizeof (char) is guaranteed to be 1 by the standard
if(!*str)
return;
}
}
(*str)[index] = '\0'; // No need to increase index
}
See my comments for the details.
There are some issues in your code:
After scanf("%d",&choice);, a '\n' will be left in stdin. When it is met by inputStrng(), the function stops generating string immediately.
To change the value of a pointer variable in a function, you need to pass a pointer to pointer, such as char **str.
You forgot to close the file, which may cause information loss.
//why the code starts printing retry infinitely if i wrongly
enter a string in place of int i in terminal
#include<stdio.h>
#include<stdlib.h>
int main(int argc, char const *argv[])
{
int i,j=0;
while(1)
{
scanf("%d",&i);
if(i==10)
{
printf("you got the max! YOU WON\n");
break;
}
else
{
printf("%s\n","retry" );
}
}
return 0;
}
Try consuming (flushing) on bad input:
else {
while ((j = fgetc(stdin)) != '\n' && j != EOF);
printf("%s\n", "retry");
}
An alternative using fgets (is preferable because it consumes the whole line) and strtol:
#include <stdio.h> /* fgets, printf */
#include <stdlib.h> /* strtol */
#include <string.h> /* strchr */
int main(void) /* No args */
{
char buf[128], *p;
int i;
while (fgets(buf, sizeof(buf), stdin)) {
if ((p = strchr(buf, '\n')) != NULL) {
*p = '\0'; /* remove newline */
}
i = (int)strtol(buf, &p, 10); /* Base 10 */
if (*p != '\0' || i != 10) {
printf("retry\n");
} else {
printf("you got the max! YOU WON\n");
break;
}
}
return 0;
}
Read fails because of you inputted wrong type and i will have garbage value.
Add initialization to i:
int i=0, j=0;
scanf returns number of succesful reads. Add return value check to scanf:
int r = scanf("%d",&i); // Will return 1 if 1 argument was successully read
if(r == 1 && i == 10)
{
//do something
}
Edit:
As others have pointed out, it seems that scanf doesn't consume incoming bytes if input is wrong. Thus you might want to replace it wit fgets and sscanf:
int r;
char temp[32];
fgets(temp, 32, stdin); // Read input to temporary buffer
r = sscanf(temp, "%d", &i); // Try to convert value on buffer
if(r == 1 && i == 10)
{
//do something
}
I'm using this piece of code to read users input and check if it is a number or not.But sincerly it just works for numbers and letters. I want it to work with every char. For example "!?%". I have already tried to change the "isalnum" by "isascii" but that does not work.
#include <stdio.h>
#include <ctype.h>
int main ()
{
int a;
int b = 1;
char c ;
do
{
printf("Please type in a number: ");
if (scanf("%d", &a) == 0)
{
printf("Your input is not correct\n");
do
{
c = getchar();
}
while (isalnum(c));
ungetc(c, stdin);
}
else
{
printf("Thank you! ");
b--;
}
}
while(b != 0);
getchar();
getchar();
return 0;
}
Unless you have specific requirements, you should use fgets and sscanf
while (1) {
char buf[1000];
printf("Please input a number: ");
fflush(stdout);
if (!fgets(buf, sizeof buf, stdin)) assert(0 && "error in fgets. shouldn't have hapenned ..."):
/* if enter pending, remove all pending input characters */
if (buf[strlen(buf) - 1] != '\n') {
char tmpbuf[1000];
do {
if (!fgets(tmpbuf, sizeof tmpbuf, stdin)) assert(0 && "error in fgets. shouldn't have hapenned ...");
} while (buf[strlen(tmpbuf) - 1] != '\n');
}
if (sscanf(buf, "%d", &a) == 1) break; /* for sufficiently limited definition of "numbers" */
printf("That was not a number. Try again\n");
}
A correct way in strictly C89 with clearing input buffer, checking overflow looks like:
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int readLong(long *l)
{
char *e,in[20];
fgets( in,20,stdin );
if(!strchr(in,'\n')) while( getchar()!='\n' );
else *strchr(in,'\n')=0;
errno=0;
*l=strtol(in,&e,10);
return *in&&!*e&&!errno;
}
int main()
{
long l;
if( readLong(&l) )
printf("long-input was OK, long = %ld",l);
else
puts("error on long-input");
return 0;
}