I'm writing a simple exercise app in C, which should ask user if he want write something to file or read the file. I want give name to the file and then input some text in console. I want use that text to save it to the file.
The problem is that, when I already give name to the file, I can't input data to the console and by this I can't save these datas to the text file. In addition, the while loop ignores my 'y' to restart the program again. Furthermore, when I want use reading file then it really does, program works, but it also adds instruction from default (printing just error) but I don't want that, just only read from file and print it to the console.
Can someone explain me what I'm doing wrong and how to solve this? I'd be grateful.
Here's my code:
int main()
{
FILE *file;
char nameFile[32];
char string[500];
char ans[2];
int choice;
do{
printf("What do you want to do?\n");
printf("1. Write text to file\n");
printf("2. Read text file\n");
scanf("%d", &choice);
switch (choice) {
case 1:
printf("Give name to the file (*.txt).\n");
scanf("%s", nameFile); //This line skips me to line where program ask user if restart the program (I have no idea why :()
system("clear");
file=fopen(nameFile, "w");
if(file!=NULL){
printf("Input text:\n");
scanf("%[^\n]", string); //<--- HERE I'cant input text to console, seems like scanf doesn't work.
fprintf(file, "%s", string);
printf("\n\t\t\t-----------Ended writing.------------\n");
fclose(file);
}
else
{
printf("Could not open the file.");
return -1;
}
break;
case 2:
printf("Give name to the file (*.txt)");
scanf("%s", nameFile);
system("clear");
file=fopen(nameFile, "r");
if(file!=NULL){
while (!feof(file)) {
fscanf(file, "%s", string);
printf("%s\n",string); //After printing data from text file, adds instruction from line , and that is printing Error. How to get rid of it?
}
}
else{
printf("Could not open the file.");
return -1;
}
default:
printf("Error.");
break;
}
printf("Do you want to restart the program? (y/*)"); //Even if I write 'y', program ends anyway :(
scanf("%s", ans);
}
while(ans=='y');
return 0;
}
https://ideone.com/aCYJR5
scanf("%[^\n]", string); doesn't work unless the input buffer is clear. Use instead scanf("%499s", string) where 499 is the size of the string minus 1.
Don't use while (!feof(file)){...}, use instead while(fscanf(file, "%500s", string) == 1){...}
Use while(ans[0]=='y') as suggested earlier. Or use
char ans;
scanf(" %c", &ans);//note the blank space before `%c`
while(ans == 'y')
You also forgot to break a switch statement. Try the following:
char c;
char ans;
do {
printf("What do you want to do?\n");
printf("1. Write text to file\n");
printf("2. Read text file\n");
scanf("%d", &choice);
switch(choice) {
case 1:
printf("Give name to the file (*.txt).\n");
scanf("%s", nameFile);
file = fopen(nameFile, "w");
if(file == NULL) { printf("Could not open the file."); return -1; }
printf("Input text:\n");
while((c = getchar()) != '\n' && c != EOF);
fgets(string, sizeof(string), stdin);
string[strcspn(string, "\r\n")]=0;
fprintf(file, "%s", string);
printf("\n\t\t\t-----------Ended writing.------------\n");
fclose(file);
break;
case 2:
printf("Give name to the file (*.txt)");
scanf("%s", nameFile);
file = fopen(nameFile, "r");
if(file == NULL) { printf("Could not open the file."); return -1; }
while(fgets(string, sizeof(string),file))
printf("%s\n", string);
fclose(file);
break;
}
printf("Do you want to restart the program? (y/*)");
scanf(" %c", &ans);
} while(ans == 'y');
See also
Why is “while ( !feof (file) )” always wrong?
How to clear input buffer in C?
your while should be
while(ans[0]=='n');
A char array is a string, you are trying to compare a whole string to the character 'y'. Also, it should "Loop while ans[0] is equal to 'n'" meaning keep going if the user specifies n.
Related
I can't get my delete record function to break out of the switch case or even give me an error when the record doesn't exist. Could someone please tell me why this is?
Any help is much appreciated!
I can't get my delete record function to break out of the switch case or even give me an error when the record doesn't exist. Could someone please tell me why this is?
Any help is much appreciated!
void delete_record();
void displayContent();
struct Update
{
char studentName[50];
char studentID [50];
char emailID[100];
char courseID[5];
char grade[50];
} update2;
int main ()
{
int num;
do
{
printf("1. Delete a record for the specific name\n");
printf("2. Display Content of File\n");
printf("6. Exit\n");
switch(num)
{
case 1:
printf("this is a test\n");
delete_record();
break;
//displayContent();
//printf("this is a test 2\n");
case 2:
printf("\n\nDiplaying Contents of File\n\n");
displayContent();
default:
printf("Give me a break!\n");
break;
}
scanf("%d", &num);
} while (num != 6);
return 0;
}
void delete_record()
{
FILE *fp;
FILE *fp_tmp;
fp = fopen ("BINARY_FILE.txt", "w");
char studentsID[20];
printf("enter studentID to delete:");
scanf("%s",studentsID);
printf("is this a test?\n");
while(fread(&update2,sizeof(update2),1,fp))
{
printf("this is another test\n");
if(strcmp(update2.studentID,studentsID) != 0)
{
//printf("testing\n");
fwrite(&update2,sizeof(update2),1,fp);
}
else
{
printf("No student with that student ID\n");
}
}
printf("more tests\n");
fclose(fp);
return;
}
void displayContent()
{
char c;
// Open file
FILE *fp;
fp = fopen ("BINARY_FILE.txt", "r");
if (fp == NULL)
{
printf("File Has No Content\n");
exit(0);
}
// Read contents from file
c = fgetc(fp);
while (c != EOF)
{
printf ("%c", c);
c = fgetc(fp);
}
fclose(fp);
//return 0;
}
When using scanf to read from the keyboard you must remember
that all characters that you enter are written to the in-buffer,
this means that if you type in
42ENTER
The ENTER will also be present in the in-buffer, so next time you call scanf ENTER will still be in the buffer and then scanf returns 0 since the format specificier "%d" doesn't match.
The easiest way to handle input from keyboard in C and to avoid the hassle of scanf in-buffer by using fgets() to read from the keyboard, then use sscanf() to cherry pick from the buffer:
// always check return value from all runtime functions when possible
char buffer[128];
if (fgets(buffer,sizeof(buffer), stdin) != NULL)
{
if (sscanf(buffer, "%d", &num) == 1)
{
}
else {...}
}
else {...}
I'm new to programming in c and I've come across a problem with my file system. The aim of this program is for a user to enter a message and that message gets stored in a text file. After the users message gets stored in a text file, they have the choice to 'read' a messaged their loved one has sent to them.
char SingleLine[150];
FILE * filePointer;
FILE * fpointer;
char mess[10];
char reply[100];
case 4:
printf("enter a message: ");
fscanf(stdin, "%s", mess);
filePointer = fopen("gift.txt", "w");
fprintf(filePointer, "%s \n", mess);
printf("you said %s \n", mess);
printf("they wrote something back?, would you like to read it? yes or no? \n ");
scanf("%s", &reply);
if ((toupper(reply[0]) == 'Y') && (toupper(reply[1]) == 'E') && (toupper(reply[2]) == 'S'))
{
printf("you said %s is that true???", &reply);
printf("ok loading...\n");
fpointer = fopen("luvtracey.txt", "r");
while (!feof(fpointer))
fgets(SingleLine, 150, fpointer);
puts(SingleLine);
}
else if ((toupper(reply[0]) == 'N') && (toupper(reply[1]) == 'O'))
{
printf("wow ignorant \n");
}
else
{
printf("your not having it anymore");
}
}
But when this code runs firstly, when a user enters a message with no spaces, it'll get stored. But when you add spaces, the message would get chopped in half and the first bit would get stored. Secondly, when you type 'yes' (when you want to see what your loved one has sent) it crashes completely but i don't understand why. Also its not retrieving the information in the 'luvtracey.txt' file which has words in it.
I accept feedback and i just want to say thank you to those in advance who help me solve these problems.
~Neamus
if ((toupper(reply[0]) == 'Y') && (toupper(reply[1]) == 'E') ...
You can convert the string to lowercase or uppercase and strcmp, rather than checking letters one by one.
while (!feof(fpointer))
fgets(SingleLine, 150, fpointer);
puts(SingleLine);
Don't use feof. Instead check if fgets succeeds. Presumably you want to print each line in the file, so don't print the line after the loop finishes. You also need error checks to make sure the file was opened successfully. Example:
#include <stdio.h>
#include <ctype.h>
#include <string.h>
int main(void)
{
char buffer[150];
printf("enter a message: ");
fscanf(stdin, "%s", buffer);
printf("you said %s \n", buffer);
FILE *fp = fopen("gift.txt", "w");
fprintf(fp, "%s \n", buffer);
fclose(fp);
printf("yes or no? ");
scanf("%s", buffer);
for(int i = 0, len = strlen(buffer); i < len; i++)
buffer[i] = (char)tolower(buffer[i]);
if (strcmp(buffer, "yes") == 0)
{
fp = fopen("luvtracey.txt", "r");
if(!fp)
{
printf("can't open...\n");
}
else
{
while(fgets(buffer, sizeof(buffer), fp))
printf("%s", buffer);
fclose(fp);
}
}
return 0;
}
I've been working on this program for my job that I'm trying to make an inventory of tools. I'm very new to programming if there is an alternative rout to take on this I'm open to looking in to it.
My first case works. All it does is ask the user for a nomenclature, part number(P/N), and serial number (S/N).
The second case I'm trying to make it print the list of data.
My goal for this is to get my problem fixed for my second case
#include<stdio.h>
#include<stdlib.h>
main()
{
FILE * fp;
int qty;
int menu;
char nomen[26];
char pN[26];
char ans;
//Test to see if file exist
fp = fopen("Metro Inventory.txt", "w");
if (fp == NULL)
{
printf("*Error opening file*");
fprintf(fp,"*Error opening file*");
exit(1);
}
//Intro Header
fprintf(fp,"List of Special Tools:");
fprintf(fp,"\t\t\tPart Number:");
fprintf(fp,"\t\t Quantity:\n\n");
printf("Metro Aviation Tools List\n\n");
printf("What would you like to do?\n");
scanf("%d", &menu);
//loop of switch asking for nomenclature
do
{
switch (menu)
{ //Case 1 adds new content
case(1):
{
printf("Enter Nomenclature(no spaces):\n");
scanf("%s", nomen);
fputs(nomen, fp);
fputs("\t\t\t",fp);
//Part Number
printf("What is the part number?\n");
scanf("%s", pN);
fputs(pN, fp);
fputs("\t\t\t", fp);
//Quantity
printf("What is the quantity?\n");
scanf("%d", &qty);
fprintf(fp,"%d",qty);
fputs("\n", fp);
break;
fclose(fp);
}// Case 2 Edits content
case(2):
{
int c;
fp = fopen("Metro Inventory.txt", "r");
if (fp)
{
while ((c = getc(fp)) != EOF)
putchar(c);
fclose(fp);
}
fclose(fp);
break;
}
default : printf("Thank you");
break;
}//end switch
printf("To add tool type Y.\n To exit type N.\n");
getch();
scanf("\n%c", &ans);
//loop
}
while ((ans == 'Y')||(ans == 'y'));
if ((ans == 'N')||(ans=='n'));
{
exit(1);
}
getch();
return 0;
}
I haven't done file I/O for C for quite a long time however, a quick look into your program reveals that the time when you set/modify the value of menu is at line 26/27. Then, your loop starts at line 29. After that, there isn't any instruction to set/modify your menu value.
Later on at line 73 to 75, you are asking for input before the loop scope ends. This input is only used later on in another loop. What I'd suggest to you is to remove the whole switch case structure and allow the program to start away continue to do whatever you want to do. As there isn't any explanation too on why should the user pick 1 for menu or 2.
Edit
It seems that you do not understand my initial comment, so I've taken the liberty to change some parts of your code.
Changes done:
Main() - For C programming, it has to have a type for the program entry point. Either void or int. Should you do int main() make sure to place return 0; before the last braces. Look at the modified code below for clarity.
Position of the code where the input for menu is supposed to happen. I placed it inside the loop so that the user will be prompt every time the loop restarts.
In my initial answer or comment, I've said that in your original code, the point where you modify your variable required for the switch case to work only once and it happens before the loop.
You must think from 1 line to another. What happens at line 1. How does line 1 affect line 2. In this example of yours, at line 26/27, you've set the value of menu to which ever input by the user (input validation is another topic). At that point, it is still linear, nothing loops so it means that your from the point you set the menu (line 26/27) to the point where the program exits (or ends) the value of menu remains static, unchanged.
Removed exit(1); I assumed you wanted the program to end if fp returns null and/or the user has chosen other input for ans. The issue of having an exit point is solved with the next modification I've made (refer to item 4).
Rearranged the code so that if (fp != null) which is the else part in the new code (refer to line 20) the program will allow the file to be written to. And should fp returns null, the whole program will exit with a return 0;.
Modified code
#include<stdio.h>
#include<stdlib.h>
int main()
{
FILE * fp;
int qty;
int menu;
char nomen[26];
char pN[26];
char ans;
//Test to see if file exist
fp = fopen("Metro Inventory.txt", "w");
if (fp == NULL)
{
printf("*Error opening file*");
fprintf(fp,"*Error opening file*");
}
else
{
//Intro Header
fprintf(fp,"List of Special Tools:");
fprintf(fp,"\t\t\tPart Number:");
fprintf(fp,"\t\t Quantity:\n\n");
do
{
printf("Metro Aviation Tools List\n\n");
printf("What would you like to do?\n");
scanf("%d", &menu);
//loop of switch asking for nomenclature
switch (menu)
{ //Case 1 adds new content
case(1):
{
printf("Enter Nomenclature(no spaces):\n");
scanf("%s", nomen);
fputs(nomen, fp);
fputs("\t\t\t",fp);
//Part Number
printf("What is the part number?\n");
scanf("%s", pN);
fputs(pN, fp);
fputs("\t\t\t", fp);
//Quantity
printf("What is the quantity?\n");
scanf("%d", &qty);
fprintf(fp,"%d",qty);
fputs("\n", fp);
break;
fclose(fp);
}
// Case 2 Edits content
case(2):
{
int c;
fp = fopen("Metro Inventory.txt", "r");
if (fp)
{
while ((c = getc(fp)) != EOF)
putchar(c);
fclose(fp);
}
fclose(fp);
break;
}
default :
printf("Thank you");
break;
}//end switch
printf("To add tool type Y.\n To exit type N.\n");
getch();
scanf("\n%c", &ans);
//loop
}while ((ans == 'Y')||(ans == 'y'));
}
return 0;
}
I wrote a program that collects user data and saves it to a file. At the moment when he wants to view the file, the program loops and shows only the first record. I do not know what this error is caused.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
FILE *fptr;
struct notification {
char name[50];
char lastname[50];
char price[10];
char descreption[100];
}notification;
void insertRecord()
{
fptr=fopen("G:\\file.txt","a+");
fflush(stdin);
printf("Podaj imie: ");
gets(notification.name);
printf("Podaj nazwisko: ");
gets(notification.lastname);
printf("Podej cene: ");
gets(notification.price);
printf("Podaj opis usterki: ");
gets(notification.descreption);
strcat(notification.descreption,"\n");
if(fwrite(¬ification,sizeof(notification),1,fptr) != 1)
{
perror("Blad: ");
} else{
printf("Dane dodane poprawnie\n");
}
fclose(fptr);
}
void readDatabase()
{
struct notification *object2=malloc(sizeof(struct notification));
fptr=fopen("G:\\file.txt","rb");
fread(object2,sizeof(struct notification),1,fptr);
while(!feof(fptr))
{
printf("Imie: %s\n", object2->name);
printf("Nazwisko: %s\n", object2->lastname);
printf("Cena: %s\n", object2->price);
printf("Opis: %s\n", object2->descreption);
printf("==========\n");
}
fclose(fptr);
}
int main() {
int i,option=0,check=0;
do{
printf("1) Dodaj rekord do bazy \n");
printf("2) Odczytaj rekordy z bazy \n");
printf("0) Zakoncz program \n");
scanf("%d", &option);
switch (option)
{
case 1:
insertRecord();
break;
case 2:
readDatabase();
break;
default:
break;
}
}while(check == 0); //petla dziala dopóki zmienna check bedzie równa 0
}
EDIT:
Correct insertRecord function:
void insertRecord()
{
fptr=fopen("G:\\file.txt","a+");
fflush(stdin);
struct notification *obj = malloc(sizeof(struct notification));
printf("Podaj imie: ");
gets(obj->name);
printf("Podaj nazwisko: ");
gets(obj->lastname);
printf("Podej cene: ");
gets(obj->price);
printf("Podaj opis usterki: ");
gets(obj->descreption);
strcat(notification.descreption,"\n");
if(fwrite(obj,sizeof(struct notification),1,fptr) != 1)
{
perror("Blad: ");
} else{
printf("Dane dodane poprawnie\n");
}
free(obj);
fclose(fptr);
}
Now ALL display and insert OK, but in file.txt I see Chinese characters, why?
There are a variety of problems in the readDatabase function
while(!feof)-is-always-wrong
the fread needs to be in the loop.
you don't need to malloc the memory, but if you do malloc memory, you should free it when you're done with it
you always need to check the return value from fopen, because it can and does fail, e.g. because the file is not found
With all that in mind, the readDatabase function should look like this
void readDatabase( void )
{
struct notification object2;
if ( (fptr = fopen("G:\\file.txt","rb")) == NULL )
{
printf( "File not found\n" );
return;
}
while ( fread( &object2, sizeof(struct notification), 1, fptr ) == 1 )
{
printf("Imie: %s\n", object2.name);
printf("Nazwisko: %s\n", object2.lastname);
printf("Cena: %s\n", object2.price);
printf("Opis: %s\n", object2.descreption);
printf("==========\n");
}
fclose(fptr);
}
Move this line:
fread(object2,sizeof(struct notification),1,fptr);
inside your while loop.
scanf("%d", &option); followed by gets() leads to trouble. The first does not consume the '\n' after the number and the second only reads in the short line '\n'.
Do not use scanf(). Do not use gets(). Use fgets(), then parse the input.
scanf() will leave new line character in input stream by default. you can use getchar() function to clear this new line character or you can flush the input buffer like this.
while ((ch = getchar()) != '\n' && ch != EOF);
but don't use fflush(stdin) because if the file stream is for input use, as stdin is, the behaviour is undefined, therefore it is not acceptable to use fflush() for clearing keyboard input. As usual, there are some exceptions, check your compiler's documentation to see if it has a (non-portable) method for flushing input.
I am writing a menu system in C, the code works correctly but for some reason the first first time the while loop is entered for the menu it skips the getchar() command and runs through the while loop again, but the second time round it works?
Any ideas as to why it does this?
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "structs.h"
int main(void)
{
FILE *fp = NULL;
char fileName[25], line[200], userInput = ' ';
int len;
while (fp == NULL)
{
printf("Enter The File To Load In: \n");
scanf("%s", fileName); // Ask User For File Name
fp = fopen(fileName, "r"); // Open File To Read
if (fp == NULL)
{
perror("Error While Loading File\n");
}
}
while (userInput != 'g')
{
printf(" |User System|\n");
printf("A) Save Current Data To A File\n");
printf("B) Enter Details\n");
printf("C) View Details\n");
printf("D) Amend Details\n");
printf("E) Search by Award Title\n");
printf("F) Search by Surname\n");
printf("G) Shut Down\n");
userInput = getchar();
if (userInput == 'c')
{
fgets(line, 200, fp);
len = strlen(line);
printf("%s", line);
userInput = getchar();
}
}
}
After 'scanf' use
getchar();
to consume extra newline. As 'scanf' can not discard newline, first iteration of 'getchar();' take the newline.
So you shold place getchar() after scanf as to consume extra newline('\n')
scanf("%s", fileName);
getchar();
It's better to use 'fgets' instead of scanf as file name may have space.
You can use 'fgets()' as
fgets(fileName, sizeof(fileName), stdin);
fileName[strlen(fileName)-1] = 0; //Replace newline with '\0' character