This question already has answers here:
fgets doesn't work after scanf [duplicate]
(7 answers)
Closed 3 years ago.
I have a code that is suppose to ask a user for a car manufacturer and then store it inside a txt file (this is part of introductory course in C). I have the following menu for calling the function inside int main
while(1)
{
printf("Choice");
scanf("%i", &MENYVAL);
switch(MENYVAL){
case 1 : ADDVEHICLE(); break;
case 2 : read(); break;
default: printf("No choice was made");
}
printf("\tChoice");
scanf("%i", &MENYVAL);
}
where "ADDVEHICLE" is the following function
void ADDVEHICLE() {
FILE *fp;
char CAR[50];
fp = fopen("FILE.txt", "a");
if(!fp) {
printf("ERROR");
}
printf("\n Manufacturer");
fgets(CAR, sizeof(CAR), stdin);
fprintf(fp, "%s", CAR);
fclose(fp);}
When running the program and scanning "MENYVAL=1"
I get the output
Manufacturer Choice
I.e the code reads the print in ADDVEHICLE but then returns to the switch code in int main without asking for input.
Attempts:
If I remove the switch code and just call the function ADDVEHICLE the code works fine, I can input text which is stored in the correct txt file.
I tested adding after "fprinf" the following code (which i believe tries to flush the buffer) see link for inspiration:
while (!EOF) { fprintf(fp, "%s", "\t");}
with no success.
PS. I am programming on a linux VM but I am not sure if it is correct to use the tag, I apologize if the tag is incorrect
Probably the '\n' character, remaining after execution of scanf() before switch, is readed inside ADDFORDON() function by fgets() call. Add "buffer flusher" before fgets() like below:
void ADDVEHICLE() {
FILE *fp;
char CAR[50];
fp = fopen("FILE.txt", "a");
if (!fp) {
printf("ERROR");
}
// flush buffer here!
scanf("%s"); // this reads any characters remaining in input buffer then ignores them
printf("\n Manufacturer");
fgets(CAR, sizeof(CAR), stdin);
fprintf(fp, "%s", CAR);
fclose(fp);
}
Related
This question already has answers here:
Why is “while( !feof(file) )” always wrong?
(5 answers)
Closed 5 years ago.
So I have read multiple posts on why feof doesn't work properly and they all utilize using a while(fscanf(...) == 1) to read to end of file, the problem I have is that I have temp values that are different for each loop, because it is reading each line processing it and then moving to next line. The code I currently have reads all the input properly but prints the last line twice. I was wondering if there was a better way to go about this instead of just doing a hack job and removing the last line processed, since it is processed twice.
void readInputFile(Customer customers[]) {
FILE *input = fopen("hw4input.txt", "r");
while (!feof(input)) {
char tempName[MAXNAMELEN];
int tempQuantity;
char tempItem[MAXNAMELEN];
double tempPrice;
fscanf(input, "%s %d %s $%lf", &tempName, &tempQuantity, &tempItem, &tempPrice);
printf("%s %d %s %.2lf\n", tempName, tempQuantity, tempItem, tempPrice);
}
printf("EOF\n");
fclose(input);
}
You cannot use feof() to detect end of file before attempting to read from the file. feof() will return the state of the end-of-file status only after a failed attempt at reading data from the file.
You should instead read values from the stream, with fscanf() for a quick and dirty throw away toy program, or with fgets() for a more robust parser:
void readInputFile(Customer customers[]) {
FILE *input = fopen("hw4input.txt", "r");
if (input != NULL) {
char name[1024];
int quantity;
char item[1024];
double price;
while (fscanf(input, "%1023s %d %1023s %lf", name, &quantity, item, &price) == 4) {
printf("%s %d %s %.2lf\n", name, quantity, item, price);
}
printf("EOF\n");
fclose(input);
} else {
printf("Cannot open input file\n");
}
}
I was wondering if there was a better way to go about this instead of just doing a hack job and removing the last line processed
Yes, there is.
Check the return value from fscanf in your code. The call will fail when you try to read past the end of the file.
You should be checking it anyway. There are even a lot of people who post here who will opine that you shouldn't use any of the *scanf() functions anyway because they're very difficult if not impossible to use in any robust way. There's almost always a way you can feed one of the *scanf() functions data that will cause problems.
This is a first formal C competition I am going through .In the last years paper they had- Specified something called aromatic number and told to find those .I wrote the code and it works well but I am not able to understand these instructions about input and output and how to code them in C for Windows.
I am aware about reading one letter from a file and writing it using fopen() and fprintf and fscanf. But these are letters written in different lines how to extract them as variables from in1.dat and print them in out1.dat?
Means I know
int main()
{
int n;
FILE *fptr;
if ((fptr=fopen("D:\\program.dat","r"))==NULL){
printf("Error! opening file");
exit(1); /* Program exits if file pointer returns NULL. */
}
fscanf(fptr,"%d",&n);
printf("Value of n=%d",n+n);
fclose(fptr);
getch();
}
Which scans the first value in the 1st line .But they ask for multiple lines(3 in sample input) how to do them?
fscanf(fptr,"%d",&n);
printf("Value of n=%d",n+n);
Instead do like this -
while(fscanf(fptr,"%d",&n))
{
printf("Value of n=%d",n+n); //But notice here with every iteration n will be over-written.
}
This will stop at the first conversion failure or end of the file.And then inside this loop you can write into output file .
Try Something Like This:
#include<stdio.h>
int main()
{
FILE *in,*out;
int num;
char line[512],aronum[20];
in = fopen("in.dat", "r");
out = fopen("out.dat","w");
fgets(line, 512, in); //to get number of test cases
sscanf (line, "%d",&num);
while((fgets(line, 512, in) != NULL) && (num--))
{
sscanf (line, "%s",&aronum);
fprintf(out,"%d",calc(aronum)); //use `calc` func to return int ans.
}
fclose(in);
fclose(out);
return 0;
}
This question already has an answer here:
what's the preferred library for CSV parsing/writing in C++? [closed]
(1 answer)
Closed 7 years ago.
Good day. Don't know whether this question has been asked before. Any who, I have a text file with contents like below
AP0003;Football;13.50;90
AP0004;Skateboard;49.90;30
It is basically,
Item Code;Item Name;Price per unit;Quantity
I am trying to put the contents of the text file into an array but I've had no luck so far. And, I can't find anything similar on Stack Overflow (or maybe my search parameters is not accurate). Would appreciate any help I can get. Am new to C Programming.
Firstly open the file using fopen:
FILE* fp = fopen("NAME_OF_FILE.txt", "r"); // "r" stands for reading
Now, check if it opened
if(fp == NULL) //If fopen failed
{
printf("fopen failed to open the file\n");
exit(-1); //Exit program
}
Suppose that these are your arrays to store the line and each data are:
char line[2048]; //To store the each line
char itemCode[50];
char item[50];
double price;
int quantity; //Variables to store data
Read the file using fgets. It consumes line by line. Put it in a loop which terminates when fgets returns NULL to scan the whole file line by line. Then extract data from the scanned line using sscanf. It, in this case, will return 4 if successful:
while(fgets(line, sizeof(line), fp) != NULL) //while fgets does not fail to scan a line
{
if(sscanf(line, "%[^;];%[^;];%lf;%d", itemCode, item, price, quantity) != 4) //If sscanf failed to scan everything from the scanned line
//%[^;] scans everything until a ';'
//%lf scans a double
//%d scans an int
//Better to use `"%49[^;];%49[^;];%lf;%d"` to prevent buffer overflows
{
printf("Bad line detected\n");
exit(-1); //Exit the program
}
printf("ItemCode=%s\n", itemCode);
printf("Item=%s\n", item);
printf("price=%f\n", price);
printf("Quantity=%d\n\n", quantity); //Print scanned items
}
Finally, close the file using fclose:
fclose(fp);
You can try this code :
#include <stdio.h>
#include <stdlib.h>
int main()
{
char str1[1000],ch;
int i=0;
FILE *fp;
fp = fopen ("file.txt", "r"); //name of the file is file.txt
while(1)
{
fscanf(fp,"%c",&ch);
if(ch==EOF) break; //end of file
else str[i++]=ch; //put it in an array
}
fclose(fp);
return(0);
}
This will put your entire file into an array str including '\n' and other special characters.If you dont want the special characters put neccessary conditions in the while loop.
This question already has answers here:
Removing trailing newline character from fgets() input
(14 answers)
Closed 8 years ago.
I'm prompting the user for the file name, but once the user presses enter, it takes that into the file name as well. so the file is never found.
int main (){
char file[100];
FILE *fp;
printf("Please enter a valid filename:\n");
fgets(file,100,stdin);
fp=fopen(file, "r");
if(!fp){
printf("File not found.\n"); \\This will always happen because a new line is added to the user's input.
return 1;}
If I use
scanf("%s", file);
The issue doesn't happen, but I heard scanf is not a good function to use and would introduce new issues. How can I solve the new line problem with fgets?
After fgets(file,100,stdin);, do this file[strlen(file)-1]='\0';, it will remove \n from the code. To use strlen() function you need to include string.h in your code.
Try this modified code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main (){
char file[100];
FILE *fp;
printf("Please enter a valid filename:\n");
fgets(file,100,stdin);
file[strlen(file)-1]='\0'; //Removing \n from input
fp=fopen(file, "r");
if(fp==NULL)
{
printf("File not found.\n");
return 1;
}
else
{
printf("File found!\n");
fclose(fp);
return 0;
}
}
fgets() returns the \n new line code.... that's what it does. You must wipe out that character.
Given that overflowing, or at least totally filling, incoming buffers is a popular attack vector I prefer code that defends against such.
char *cp;
file[(sizeof file)-1)] = '\0'; /* assure \0 termination on buffer fill attack */
cp = strchr( file, '\n' ); /* find expected \n, but allow for none */
if ( cp ) *cp = '\0'; /* safely clear closing \n */
scanf(" %[^\n]", in);
then for example , i input Knock Knock and hit enter
but my code block inside
if (strcmp ("Knock Knock",out)==0)
does not work
please instruct me ,thanks a lot!
char in[80],out[80];
void input(){
printf("Client: ");
scanf("%[^\n]",in);
fp=fopen("test","w");
if (!fp) return ;
fputs(in,fp);
fclose(fp);
}
fp=fopen("test","r");
fgets(out,81,fp);
fclose(fp);
fp=fopen("test","w");
if (strcmp ("Knock Knock",out)==0)
fputs("Server: Who is there?\n",fp);
First off, the layout of the code is very confusing, and as it stands, it would never compile. You have a function input() that you never seem to call, and you leave code outside the function that should be inside another function, or better yet, all of it should be contained inside a main() function so that it can be executed. Here is a cleaned up example for what you're wanting to-do:
#include <stdio.h>
char in[80],out[80];
int main()
{
printf("Client: ");
scanf("%[^\n]",in); //you really should use fgets() here
FILE* fp = fopen("test.txt","w");
if (!fp)
{
perror("Failed to open file");
return 1;
}
fputs(in,fp);
fputs("\n",fp);
fclose(fp);
fp = fopen("test.txt","r");
if (!fp)
{
perror("Failed to open file");
return 1;
}
fgets(out,80,fp);
fclose(fp);
fp = fopen("test.txt","a+");
if (!fp)
{
perror("Failed to open file");
return 1;
}
if (strcmp ("Knock Knock\n",out)==0)
fputs("Server: Who is there?\n",fp);
return 0;
}
Some important notes:
1) fp has a file-type FILE*, since that is the return of fopen(), but you never declare it as such. So this would never compile with that error.
2) Every time you open a file with the w flag, it erases the entire contents of the file. So if you were intending on appending to the file to have a history of what your output from your program was, you need to use the a+ flag when calling fopen()
3) It would be nice to have some type of error print-out if you failed to open the file rather than scratching your head at why "test.txt" is empty after the program takes the input from stdin. Also if you're going to keep re-opening the file, check for a NULL each time since you're going to get unpredictable results from trying to work with a NULL file pointer (most likely a crash).
4) scanf() can result in nasty buffer over-runs from user-input (or malicious user input) ... use fgets() with stdin to a known-length buffer instead.
You should be able to compile this code now and run it. Works for me with gcc 4.4.3 on Ubuntu. After running, your "test.txt" file should look like:
Knock Knock
Server: Who is there?