I was under the impression that to open binary files using strings, you could simply create the string, and then implement it as the name of the file where it will read the string. This is what my lecture notes state. However I'm obveously missing something. I've used &name, name, &name[SIZE] within the fopen and each time i've gotten inBinFile == NULL unless I use the commented line. My string is correct. What's wrong? Help is much appreciated. Thanks in advance.
#include <stdio.h>
#include <stdlib.h>
#define SIZE 25
int frstmenu(void);
int sndmenu(void);
int main()
{
int fmenu, smenu;
char name[SIZE];
FILE *inBinFile;
unsigned char numRead;
fmenu = frstmenu();
if ( fmenu !=1 && fmenu !=2 )
{
printf("\nIncorrect option\n");
fmenu = frstmenu();
}
if (fmenu == 1)
{
printf("\nEnter the file name: \n");
scanf("%s", &name[SIZE]);
/* printf("filename: %s", &name[SIZE]); */
smenu = sndmenu();
if (smenu !=1 && smenu !=2 )
{
printf("\nIncorrect option\n");
smenu = sndmenu();
}
if (smenu == 1)
{
inBinFile = fopen( name, "rb");
/* inBinFile = fopen( "stream.grc", "rb"); */
if (inBinFile == NULL)
{
fprintf(stderr, "Error opening %s", &name[SIZE]);
return(-1);
fclose(inBinFile);
}
}
return(0);
}
int frstmenu()
{
float selection;
printf("----Menu----\n");
printf("1 Open a file ( supported format: .grc )\n");
printf("2 Exit the program\n");
printf(" Please select an option (1 or 2): ");
scanf("%f", &selection);
return(selection);
}
int sndmenu()
{
int selection;
printf("---Menu---\n");
printf("1 Decode the sequence\n");
printf("2 Exit the program\n");
printf(" Please select an option (1 or 2):\n");
scanf("%i", &selection);
return(selection);
}
You probably want to say
scanf("%s", &name[0]);
or even just:
scanf("%s", name);
Your &name[SIZE] points to name + SIZE, which is beyond the allocated memory.
Related
This question already has answers here:
gets() does not work
(3 answers)
Why is gets() not consuming a full line of input?
(7 answers)
Closed 1 year ago.
I am trying to read students data (name, department, roll, sgpa, cgpa), I used fgets function to read name and department, but it skips to the department and can't read name.
here is my code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct {
char name[100];
char department[50];
int roll;
float sgpa[12];
float cgpa;
} Student;
void add(FILE *fp);
void modify(FILE *fp);
void display(FILE *fp);
FILE * del(FILE * fp);
int main(int argc, char **argv) {
int option;
FILE *fp;
fp = fopen("db.txt", "rb+");
if (fp == NULL) {
fp = fopen("db.txt", "wb+");
if (fp == NULL) {
printf("Can't open the database");
return 0;
}
}
printf("\t1. Add Student");
printf("\n\t2. Modify Student");
printf("\n\t3. Show All Student");
printf("\n\t4. Remove Student");
printf("\n\tEnter Your Option :--> ");
scanf("%d",&option);
switch(option)
{
case 1:
add(fp);
break;
case 2:
// modify(fp);
break;
case 3:
// display(fp);
break;
case 4:
// fp = del(fp);
break;
default:
printf("Unkonw option\n");
}
return 0;
}
void add(FILE *fp) {
Student std;
int i;
float cgpa;
fseek(fp,0,SEEK_END);
printf("\n\tEnter Full Name of Student: ");
fflush(stdin);
fgets(std.name,100,stdin);
std.name[strlen(std.name)-1]='\0';
printf("\n\tEnter Depertment Name: ");
fflush(stdin);
fgets(std.department,50,stdin);
std.department[strlen(std.department)-1]='\0';
printf("\n\tEnter Roll number: ");
scanf("%d",&std.roll);
printf("\n\tEnter SGPA for 12 semesters\n");
for(i=0,cgpa=0; i<12; i++)
{
scanf("%f",&std.sgpa[i]);
cgpa+=std.sgpa[i];
}
cgpa/=12.0;
std.cgpa=cgpa;
fwrite(&std,sizeof(std),1,fp);
}
Is there a way of limiting scanf in C?
I did this, if you're having that many problems with string input giving an eye on my other answer might help you
Here's a more specific answer to your problem on message you place what you wanna print before the input and StringInput you place the array you're using to hold the message
I hope this works since you also use a array for it
also i see this:
fp = fopen("db.txt", "rb+");
if (fp == NULL) {
fp = fopen("db.txt", "wb+");
if (fp == NULL) {
printf("Can't open the database");
return 0;
}
}
which may not be what you want because if it fails because of a sudden glitch by using wb+ you will overwrite it
“r+” – Searches file. Opens the file for both reading and writing. If opened successfully, fopen() loads it into memory and sets up a pointer which points to the first character in it. Returns NULL, if unable to open the file.
“w+” – Searches file. If the file exists, its contents are overwritten. If the file doesn’t exist, a new file is created. Returns NULL, if unable to open the file.
FUNCAUX_MAX_STRING is a macro and you define it like so:
#define FUNCAUX_MAX_STRING 100
This makes it so that the number or elements is 100 and you can easily change every number thats using the macro by simply changing the value once
void readString(char message[FUNCAUX_MAX_STRING], char StringInput[FUNCAUX_MAX_STRING], int maxChars)
{
int sizeString;
do // Repete leitura caso sejam obtidas strings vazias
{
printf("%s", message);
fgets(StringInput, maxChars, stdin);
sizeString = strlen(StringInput);
if (sizeString == 1)
{
printf("Nao foram introduzidos caracteres!!! . apenas carregou no ENTER \n\n");
}
}
while (sizeString == 1);
if(StringInput[sizeString-1] != '\n')
{
cleanBufferStdin();
}
else
{
StringInput[sizeString-1] = '\0';
}
}
void cleanBufferStdin(void)
{
char chr;
do
{
chr = getchar();
}
while (chr != '\n' && chr != EOF);
}
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 need to write a C program to fetch data from one file and write it to another file, without using user defined functions. My requirements are to:
Search customer details by Name.
Store the transaction data (paid amount) in another text file.
I did the code to search by name. But its not working,
#include <stdio.h>
#include <stdlib.h>
int main () {
char name[10], nic[10], mobile[10];
char fname[10], fnic[10], fmobile[10];
char choice;
int amount;
FILE *cfptr;
printf("Enter search type - \n 1. NAME \n 2. NIC \n 3.MOBILE \n ----> ");
scanf("%c", &choice);
printf("Enter search text : ");
scanf("%s", &name);
cfptr = fopen ("customer.dat", "r");
while (!feof(cfptr)){
fscanf(cfptr, "%s %s %s", fname, fnic, fmobile);
printf("Read Name |%s|\n", fname );
printf("Read NIC |%s|\n", fnic );
printf("Read Mobile |%s|\n", fmobile );
}
fclose(cfptr);
scanf("%d", &amount);
return(0);
}
customer.dat File
Shan 100012 200202
Marsh 121213 667675
Kim 126573 663412
This code is not complete asI cant filter the single name assigning
if(name == fname)
as am getting
assignment to expression with array type error
Can any one complete me the code to search and save to another file so I can do the amount calculation part?
int Search_in_File(char *fname, char *str) {
FILE *fp;
int line_num = 1;
int find_result = 0;
char temp[512];
//gcc users
//if((fp = fopen(fname, "r")) == NULL) {
// return(-1);
//}
//Visual Studio users
if((fopen_s(&fp, fname, "r")) != NULL) {
return(-1);
}
while(fgets(temp, 512, fp) != NULL) {
if((strstr(temp, str)) != NULL) {
printf("A match found on line: %d\n", line_num);
printf("\n%s\n", temp);
find_result++;
}
line_num++;
}
if(find_result == 0) {
printf("\nSorry, couldn't find a match.\n");
}
//Close the file if still open.
if(fp) {
fclose(fp);
}
return(0);
}
few comments:
when scanning the choice, read it as an integer and not as a character.
scanf("%c", &choice); // change to scanf("%d", &choice);
single '=' is an assigment, you meant comparison which is double '=='
if(name = fname) // comparison is if(name == fname)
in order to compare string, do not use '==' operator. use strcmp or implement an equivalent of strcmp.
Thanks for the effort, As with changes, I have changed my code as below and its working. Without checking with the name, I alternately checked with the nic.
#include <stdio.h>
int main(void){
int nic, n, mobile;
char name[30];
FILE *aPtr;
aPtr = fopen("Details.txt","w");
if(aPtr == NULL){
printf("File cannot be opened");
return -1;
}
printf("Enter nic to search - ");
scanf("%d", &n);
fscanf(aPtr, "%d %-s %d", &nic, name, &mobile);
while(!feof(aPtr)){
if(nic == n){
Printf("%d %s %d \n", nic, name, mobile);
}
fscanf(aPtr, "%d %s %d", &nic, name, &mobile);
}
fclose(aPtr);
return 0;
}
I am a complete beginner of C. My problem is to modify a content in a file.
I am writing two files and then merge the contents of the two files in a another file. This another file is the one I need to modify.
what to modify?
The myfile1.txt values are 199112345671273 and the myfile2.txt values are 24AUS2024MED712.
The merging file (myfile3.txt) has 19911234567127324AUS2024MED712
The thing that I need to modify is the values of myfile2.txt. I want to hide its values in asterisk so when reading myfile3.txt,I get the following
199112345671273****************
my logic is messed up. I just want to stores both values of myfile1 and myfile2. then display myfile3 in condition that myfile2 has to be hidden in asterisk when reading.
My write.c program - write data in two files
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_SIZE 100
int main (int argc, char **argv) {
char registration[MAX_SIZE], location[MAX_SIZE], faculty[MAX_SIZE];
int birthOfYear, birthOfMonth, birthOfDate, layerArch1, layerArch2, levelOfStudy, graduatingYear;
FILE *fptr, *anotherfptr;
fptr = fopen("myfile01.txt","w");
anotherfptr = fopen("myfile02.txt", "w");
if(fptr == NULL) {
printf("Error!");
exit(1);
}
printf("Enter a registration number (XXXXXX): ");
scanf("%s", registration); //read as a string
printf("Enter location (location as in currency, AUS CND SIN: ");
scanf("%s", location); //read as a string
printf("Enter faculty (ENG BUS SCI MED): ");
scanf("%s", faculty); //read as a string
printf("Enter birth of year (19XX 200X): ");
scanf("%d", &birthOfYear);
printf("Enter birth of month (XX): ");
scanf("%d", &birthOfMonth);
printf("Enter birth of date (XX): ");
scanf("%d", &birthOfDate);
printf("Enter level of study (1 -first, 2- second, 3- third, 4-fourth, 5 - other): ");
scanf("%d", &levelOfStudy);
printf("Enter graduating year (XXXX): ");
scanf("%d",&graduatingYear);
printf("Enter layer of Architecture 1 (0-sensing, 1-network, 2-smart(hidden), 3-devices): ");
scanf("%d",&layerArch1);
printf("Enter layer of Architecture 2 (0-sensing, 1-network, 2-smart(hidden), 3-devices): ");
scanf("%d",&layerArch2);
fprintf(fptr,"%d%s%d%d%d", birthOfYear, registration, birthOfMonth, birthOfDate, layerArch1); //writing into file with some formatting
fclose(fptr);
fprintf(anotherfptr,"%d%d%s%d%s%d%d", layerArch2, levelOfStudy, location, graduatingYear, faculty, birthOfDate, birthOfMonth);
//writing into file with some formatting
fclose(anotherfptr);
return 0;
}
my merge.c program - to merge two files
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char **argv)
{
FILE *fs1, *fs2, *ft;
char ch, file1[200], file2[200], file3[200];
printf("Enter name of first file\n");
gets(file1);
printf("Enter name of second file\n");
gets(file2);
printf("Enter name of file which will store contents of the two files\n");
gets(file3);
fs1 = fopen(file1, "r");
fs2 = fopen(file2, "r");
if(fs1 == NULL || fs2 == NULL)
{
perror("Error ");
printf("Press any key to exit...\n");
exit(EXIT_FAILURE);
}
ft = fopen(file3, "w"); // Opening in write mode
if(ft == NULL)
{
perror("Error ");
printf("Press any key to exit...\n");
exit(EXIT_FAILURE);
}
while((ch = fgetc(fs1)) != EOF)
fputc(ch,ft);
while((ch = fgetc(fs2)) != EOF)
fputc(ch,ft);
printf("The two files were merged into %s file successfully.\n", file3);
fclose(fs1);
fclose(fs2);
fclose(ft);
return 0;
}
my read.c - to read files
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char **argv) {
char c[1000];
FILE *fptr, anotherfptr;
if ((fptr = fopen("myfile1.txt", "r")) == NULL) {
printf("Error! opening file");
exit(1);
}
// reads text until newline
fscanf(fptr,"%[^\n]", c);
printf("Data from the file:\n%s", c);
fclose(fptr);
if ((fptr = fopen("myfile2.txt", "r")) == NULL) {
printf("Error! opening file");
exit(1);
}
// reads text until newline
fscanf(anotherfptr,"%[^\n]", c);
printf("Data from the file:\n%s", c);
fclose(anotherfptr);
return 0;
}
My issue is my logic on how to solve this simple program. I am literally stuck.
Any help/clarification would be much appreciated.
In this case you need to create a program which should know the content/size of 'myfile1.txt' or 'myfile2.txt' so as to show * for the second content while reading 'myfile3.txt'.
I prefer not to create separate c programs for each task but to use it as a function in one single program.
Coming to the logic : Masking is what you are searching for. Basically it is used as a password masking. ( You might have seen * while typing password in any sites. ). In your case you want to display a content as * without actually changing the content in file.
Get an idea of how masking is done for password in the below document :
https://www.geeksforgeeks.org/print-in-place-of-characters-for-reading-passwords-in-c/
Hope you have tried all possible way out. Please check the solution below :
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char **argv) {
char c1[1000];
char c3[1000];
FILE *fptr, *anotherfptr;
if ((fptr = fopen("myfile1.txt", "r")) == NULL) {
printf("Error! opening file");
exit(1);
}
// reads text until newline
fscanf(fptr,"%[^\n]", c1);
printf("Data from the file myfile1.txt :%s\n", c1);
fclose(fptr);
//calculate the length of string c1
int lengthc1=strlen(c1);
printf("Length of string c1 is : %d\n", lengthc1);
if ((anotherfptr = fopen("myfile3.txt", "r")) == NULL) {
printf("Error! opening file");
exit(1);
}
// reads text until newline
fscanf(anotherfptr,"%[^\n]", c3);
printf("Data from the file myfile3.txt :%s\n", c3);
fclose(anotherfptr);
//to show data of myfile2.txt in astrisk
int lengthc3=strlen(c3);
printf("Final data is ");
for ( int i=0 ; i<=lengthc3 ; i++)
{
if (i < lengthc1)
{
printf("%c", c3[i]);
}
else
{
printf("*");
}
}
return 0;
}
The program works when the edit is alone and it also works when the read is alone :
printf("Enter the name of file you wish to edit:\n");
gets(file_name); //file_name = input
file = fopen(file_name,"w"); // write mode
if( file == NULL ) //If file couldn't be opened
{
perror("Error while opening the file!\n");
exit(EXIT_FAILURE);
}
printf("Enter name: \n"); scanf("%s",name1);
printf("Enter second name if applicable: \n"); scanf("%s",name2);
printf("Enter grade: \n"); scanf("%s",grade);
fprintf(file, "%s%s%s\t%s%s%s", name1, " ", name2, "=", " ", grade);
fclose(file);
printf("File write was successful\n");
And
printf("Enter the name of file you wish to see:\n");
gets(file_name); //file_name = input
file = fopen(file_name,"r"); // read mode
if( file == NULL ) //If file couldn't be opened
{
perror("Error while opening the file!\n");
exit(EXIT_FAILURE);
}
printf("The contents of %s file are:\n", file_name);
while( ( character = fgetc(file) ) != EOF /*EOF = End Of File*/)
printf("%c",character); //print c (character)
fclose(file); //remove the file from RAM
However when they are put together with an if the program crashes as soon as 1 or 2 is inputted into the first section:
printf("Edit or Read file? (1 for edit, 2 or read)\n"); scanf("%s",RW);
Here is the whole code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
char character, file_name[25];
int RW;
const char *quit;
FILE *file; //"file" stores file stream
char data [100000];
char name1 [100000];
char name2 [100000];
char grade [100000];
printf("Edit or Read file? (1 for edit, 2 or read)\n"); scanf("%s",RW);
if (RW == 1)
{
printf("Enter the name of file you wish to see:\n");
gets(file_name); //file_name = input
file = fopen(file_name,"r"); // read mode
if( file == NULL ) //If file couldn't be opened
{
perror("Error while opening the file!\n");
exit(EXIT_FAILURE);
}
printf("The contents of %s file are:\n", file_name);
while( ( character = fgetc(file) ) != EOF /*EOF = End Of File*/)
printf("%c",character); //print c (character)
fclose(file); //remove the file from RAM
} else if ( RW == 2) {
printf("Enter the name of file you wish to edit:\n");
gets(file_name); //file_name = input
file = fopen(file_name,"w"); // write mode
if( file == NULL ) //If file couldn't be opened
{
perror("Error while opening the file!\n");
exit(EXIT_FAILURE);
}
printf("Enter name: \n"); scanf("%s",name1);
printf("Enter second name if applicable: \n"); scanf("%s",name2);
printf("Enter grade: \n"); scanf("%s",grade);
fprintf(file, "%s%s%s\t%s%s%s", name1, " ", name2, "=", " ", grade);
fclose(file);
printf("File write was successful\n");
}
printf(" \n");
printf("Close window?\n"); scanf("%s",quit);
if (quit == "y")
{
printf("Bye!\n");
}
return (0);
}
the posted program crashes because of this line:
scanf("%s",RW);
the variable RW is declared as an int.
The call to scanf() is expecting a pointer to an char array.
so the code is trying to tread RW as a pointer, and followed that pointer (which contains what ever trash was on the stack at the location of RW. That is what is causing the crash.
Suggest writing the statement as:
scanf("%u",&RW);
As BLUEPIXY said:
scanf("%s",RW); --> scanf("%d%*c", &RW);
const char *quit; --> char quit; ... scanf("%s",quit); if(quit == "y") --> scanf(" %c", &quit); if(quit == 'y')
These changes meant that there were no problems with the variables.