junk characters from stdin after reading from file in C - c

After succesfully reading a re-directed file to my program from the console, I ask a user to enter a word, then use scanf() to read in the word.
The problem i'm having is that scanf() is immediately reading in junk characters and then the program continues. It doesn't even pause to let the user enter anything in the console. It doesn't happen when I don't open a file. EVERYTHING else works perfectly. What could be the issue:
**I tried everything suggested, still can't get it to work. I've made a new project that is just for getting this part to work, here it is. Ignore that scanf is only looking for a single character, even though I ask for a word. I did this just to see if the program would actually pause and allow me to enter something, but it doesn't. Just enters some garbage and program ends.
main(){
int n,i;
char ch;
char line[80];
while(fgets(line, 80, stdin) != NULL){
for(i=0;i<80;i++){
ch=line[i];
if(ch=='\n'){
printf("%c",ch);
break;
}
else{
printf("%c",ch);
}
}
}
printf("Please enter a word: ");
scanf("%c",&ch);
}

You can't re-direct stdin from a file and then also use the keyboard for input (that I know of). If you want to do that, it's simpler to have the program take the input file as a command-line argument and then run it like so: prog myfile.txt. Also, leave yourself a pad with fgets() -- use one less than the allocated array for maxlen. It's always safest with C char arrays to use one less than the allocated length for anything requiring a maximum length in case the maximum length is not including the '\0' terminating character.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc,char *argv[])
{
FILE *f;
int i;
char line[80];
if (argc<2)
{
printf("Usage: %s <inputfile>\n",argv[0]);
exit(10);
}
/* Open file and echo to stdout */
f=fopen(argv[1],"r");
if (f==NULL)
{
printf("Cannot open file %s for input.\n",argv[1]);
exit(20);
}
while (fgets(line, 79, f) != NULL)
printf("%s",line);
fclose(f);
/* Get user input from stdin */
printf("Please enter a word: ");
if (fgets(line,79,stdin)==NULL)
{
printf("Nothing entered. Program aborted.\n");
exit(30);
}
/* Remove CR/LF from end of line */
for (i=strlen(line)-1;i>=0 && (line[i]=='\n' || line[i]=='\r');i--)
;
line[i+1]='\0';
printf("The word entered is: '%s'\n",line);
return(0);
}

sscanf is used to input from a stream or a buffer, and in unix stdin is considered as file so u are supposed to use fscanf which inputs from a file so use fscanf(stdin,"%s",testword);

Related

How do I stop a blank line from being added in this instance?

I am trying to make it so you can write a multi line message and it will store it in a file of your choosing and to be done you enter ` but when I do this at the top there is a blank line printed. How can I prevent this?
#include <stdio.h>
char filename[BUFSIZ];
char input[BUFSIZ];
FILE *file;
int main() {
printf("What do you want to name the file?\n");
scanf("%s", filename);
printf("Enter the contents. Once you are done enter `\n");
scanf("%[^`]s", input);
file = fopen(filename, "w");
fprintf(file, "%s", input);
fclose(file);
}
Code:
/* multi.c
*/
#include <stdio.h>
#define BUFSIZE 1024
int main(void)
{
char filename[BUFSIZE];
char input[BUFSIZE];
FILE *fp;
/* using fprintf(stderr... is better because of output buffering.
* This way, we don't need the '\n' at the end for the string to
* appear in the console. You could also use:
*
* printf("Filename: "); fflush(stdout);
*/
fprintf(stderr, "Filename: ");
/* When you press ENTER, a '\n' will be created at the stdin buffer.
* However, this scanf() will NOT read it into #filename. So the '\n'
* is left in the buffer...
*/
scanf("%s", filename);
fprintf(stderr, "Contents: ");
/* when you call scanf() again, the old '\n' is the first character
* it reads into #input. So, to discard that, simply add a space
* before the % - this ignores whitespaces (tabs, newlines, spaces)
*/
scanf(" %[^`]", input);
/* open the file, check for errors */
if(!(fp = fopen(filename, "w"))) {
perror("fopen");
return -1;
}
/* print the contents to the file */
fprintf(fp, "%s", input);
/* clean up */
fclose(fp);
return 0;
}
This is the execution:
$ ./multi
Filename: hello.txt
Contents: My name is Enzo
I am writing some multiline content to a file
And then I'm posting it to
Stack Overflow.`
And this is hello.txt
$ cat hello.txt
My name is Enzo
I am writing some multiline content to a file
And then I'm posting it to
Stack Overflow.$
Notice that after the last line my terminal character $ is there. This is because we end the input with a ` character, and not with a new line. Therefore, there's no new-line at the end of the file.
int main() {
printf("What do you want to name the file?\n");
scanf(" %s", filename);
printf("Enter the contents. Once you are done enter `\n");
scanf(" %[^`]s", input); //do not forget to put a space in scanf
file = fopen(filename, "w");
fprintf(file, " %s", input); //try to make a space in there or if it doesn't work
fclose(file); //than try " %[^\n] but this is a little risky depends in the way you want use the code.
//if none of these works than try this other way "\b %s"
}
always put a white space before " %s" or other text format specificators because, you may have problems...
The reason is that when you add a scanf() directely after a printf() sometimes it scanf takes as part of the string that it has to read even the last character printed by printf(), depending in what kind of characters they are (mostly white spaces, \n, \t). It's a little bit weird but it happened me a lot of times in the past.
I think that the problem is in there
scanf(" %[^`]s", input); //put that white space
first try to make that space here and I think it will work, but if it doesn't try the others left in comments. One of them will definitively work.

Changing the current filename to a different one using fopen

I'm currently practicing File I/O in C. I created a program where I get a file and extract data from it and I would like an option to change the file that is being read. The problem that I'm encountering is that for example I have two files: sample1.txt and sample2.txt. If I chose sample1.txt as the first file to be read and then I wanted to change the file to sample2.txt what ends up happening is that the filename does not change to sample2.txt but instead always stays what ever filename the first file has.
Here is my code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <strings.h>
#include <assert.h>
#include <time.h>
#include <ctype.h>
int main()
{
char file_location[100]={0};
char new_location[100]={0};
FILE* fPointer=NULL;
int choice;
printf("Enter the filename that you wish to open.\n");
scanf("%[^\n]s",file_location); // I enter sample1.txt//
printf("%s\n",file_location);
fPointer=fopen(file_location,"r"); // success,sample1.txt is currently being read.//
if (fPointer==NULL)
{
printf("File error!,invalid file name! program will now exit.\n");
exit(0);
}
else
{
printf("Success!\n");
}
printf("Do you want to change the file being read\n); //Now I want to change the file,from sample1.txt to sample2.txt//
prinft("Enter 1 to change, 0 to exit the program\n);
do{
scanf("%d",&choice);
printf("You entered %d\n",choice);
if(choice<0||choice>1)
{
printf("Error,please choose between 1 and 0\n");
}
}while(choice!=1||choice!=0);
switch(choice) // I enter 1,go to case1//
{
case 0:
printf("Exiting program now\n");
exit(0);
break;
case 1:
fclose(fPointer);
printf("Enter the filename that you wish to open.\n");
scanf("%[^\n]s",new_location); //scanf does not even prompt me to enter a string.//
printf("%s\n",new_location); //nothing prints//
fPointer=fopen(new_location,"r"); // fpointer still points to sample1.txt//
break;
}
return 0;
}
Could anyone explain to me why my code keeps failing?
Any constructive criticism ,notes about File I/O is appreciated.
The fundamental problem is that your code mishandles newlines. This method of obtaining input probably does not do what you think it does:
scanf("%[^\n]s",new_location);
First, there is no reason for the trailing s here. Second, this will leave a trailing newline behind in the input stream. This newline is ignored when you call scanf("%d",&choice);, since the %d conversion specifier skips over leading whitespace characters. But, this second call to scanf() also leaves a newline character behind, and this is not ignored by the final call to scanf(), since %[^\n] tells scanf() to read characters until a newline is encountered.
One fix is to simply remove the scanset from your scanf() statements:
scanf("%s", new_location);
This will ignore leading whitespace characters, so the newline left behind from the previous call to scanf() will be ignored.
Also, when you open the new file, you are using file_location instead of new_location.
You will need to change your do loop condition to:
while(choice != 1 && choice != 0);
since you want to repeat the loop only if the user enters a number that is both not 0 and not 1.
If you want to read lines that include spaces, which is what [^\n] is sometimes used for, a better alternative is to use fgets(). This function keeps the newline, so you will need to remove it from the filenames. Also, if you are using fgets() to get the strings, it is best to use fgets() to get the numeric input, by reading the user input into a buffer and using sscanf() to parse it. Then your input code would look like:
/* Get first filename, and remove the newline */
printf("Enter the filename that you wish to open.\n");
fgets(file_location, sizeof file_location, stdin);
file_location[strcspn(file_location, "\r\n")] = '\0'; // remove newline
...
/* Get numeric input; this keeps the newline, so it does not interfere
* with the next call to `fgets()` */
char buffer[100];
fgets(buffer, sizeof buffer, stdin);
sscanf(buffer, "%d", &choice);
...
/* Get the new filename, and remove the newline */
printf("Enter the filename that you wish to open.\n");
fgets(new_location, sizeof new_location, stdin);
new_location[strcspn(new_location, "\r\n")] = '\0'; // remove newline

Read each line in a text file when I press a key? C programming

I know how to use fgets inside a while loop to read an entire text file, but how can I press a key inside that loop, so it will read another line, one at a time?
I tried with a simple printf("Press any key\n") getchar() but nothing happens, I run the programm and it just doesn't do anything, not even show the first line. I'm assuming this may be a stupid question but I can't find how to do this :(
Here is what I've tried:
/* gcc readline.c -Wall -o read */
#include <stdio.h>
//#include <stdlib.h>
int main (int argc, char *argv[]) {
char url[]="dbus.log";
FILE *arq;
char info[1000];
arq = fopen(url, "r");
while (fgets(info, sizeof(info), arq) != NULL) {
printf("%s", info);
printf("Press Any Key to Continue\n");
getchar();
}
fclose(arq);
return 0;
}
The program isn't showing the prompts because stdio is buffered and you're not flushing. Use fflush(stdout); to ensure that buffered output is produced.
Like this:
fflush(stdout);
getchar();
Also note that by default stdin is in "cooked" IO mode. Pressing enter will produce a character, but other characters will be buffered until enter is pressed.

fgets Introducing new line in user's input [duplicate]

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 */

gets not working properly to write in a file

I made a following program.The program shows no compiler error. There exist a file alive.txt in the directory. I want to use gets to write string to the file alive.txt but its not working properly.
#include<stdio.h>
#include<conio.h>
#include<ctype.h>
int main()
{
FILE *myfile;
char c,d;
char e[100];
myfile=fopen("alive.txt","r");
if(!myfile)
{
puts("Disk Error");
return(1);
}
while((c=fgetc(myfile))!=EOF)
{
putchar(c);
}
puts("\n");
puts("Do ya want to overwrite this file:{Y/N}");//
d=toupper(getchar());
if(d!='Y')
{
puts("Ok.. See ya Later");
return(1);
}
myfile=fopen("alive.txt","w");
puts("Type The Character to overwrite");
gets(e); // scanf works
fprintf(myfile,"%s",e);
fclose(myfile);
getch();
return(0);
}
The file is already open for reading from when you open it for writing to. Add
fclose(myfile);
before the second fopen.
The problem is that gets() reads the newline after the Y and realizes 'end of line', and returns an empty string (because it removes the newline), so there's nothing written to the file. If you use scanf("%s", e); instead of gets(), the %s format skips leading white space (such as the newline after the Y) and reads the next word.
Other problems include:
You're also leaking file descriptors (file streams) because you don't fclose() the myFile from the first fopen().
You're using gets() which is, as stated in a comment, a very bad idea. (Teachers who suggest using gets() should be forcibly restrained from teaching; students who use gets() should be given 0 marks automatically.) Don't use gets(); use fgets() or
getline() instead. Note that fgets() includes the newline in the data if there's space for it.
You're using char c; and then trying to detect EOF with it — which is unreliable.
You don't check that your fopen() calls succeed; you use the file pointer anyway, which will cause your program to crash if the file isn't there for any reason.
#include<stdio.h>
//#include<conio.h> Non-portable
#include<ctype.h>
int main()
{
FILE *myfile;
char c,d;
char e[100];
myfile=fopen("alive.txt","r");
if(!myfile)
{
puts("Disk Error");
return(1);
}
/* Show the current file content. */
while((c=fgetc(myfile))!=EOF)
{
putchar(c);
}
fclose(myFile); // Close the read-only file mode.
puts("\n");
puts("Do ya want to overwrite this file:{Y/N}");
d=toupper(getchar());
if(d!='Y')
{
puts("Ok.. See ya Later");
return(1);
}
/*Flush '\n' character from stdin */
getchar();
puts("Type The Characters used to overwrite");
gets(e); // scanf works
myfile=fopen("alive.txt","w"); Re-open in write mode, deleting old file content.
fprintf(myfile,"%s",e);
fclose(myfile);
// getch(); Non-portable
/* Be nice and close the file when finished with it. */
fclose(myfile);
return(0);
}

Resources