First letter of any word after the first goes missing - c

I am fairly new to programming and i have done some in school, but they only taught basic functions like printf, scanf, for, while, pointers. I am making a small program that will print user input in to a file, but when the text is written into the file the first letter of every word after the first is missing and i don't know why. can somebody explain what is happening to the first letters and do so in a simple manner if you can, please and thank you for your answer.
This is the function i am using to write to the file.
void text(){
int e=1;
puts("After a sentance press enter to continue or esc to stop");`
printf("Enter text now\n");
FILE *fp;
fp=fopen("Text.txt","w");
End:while(e==1){
char txt[100];
puts(gets(txt),fp);
if(getche()=='\e')
e=0;
goto End;
} //end of while
fclose(fp);
}// end of function
New code
void text(){
int e=1;
puts("After ending a sentance press enter to continue or esc to stop");
printf("Enter text now\n");
FILE *fp;
fp=fopen("Text.txt","w");
while(e==1){
char txt[100];
fgets(txt,100,stdin);
fwrite(txt,sizeof(char),sizeof(txt),fp);
if(getche()=='\e'){
break;
}
else;
}
fclose(fp);
}

Your code has many issues, but... your particular problem is that getche() reads one character, if it is \e you do something, but if it is another characters, then it is lost!
Using your functions of choice (getche() and gets()) you can do:
while (1)
{
char c = getche();
if (c == '\e')
break;
txt[0] = c;
gets(txt+1);
/* ... */
}
This will not remove the first character, but will fail with empty lines, I think.. I will leave that as an exercise to the reader.

Related

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);
}

How do i take an unwanted character off the end of a file in C?

So i have some code that will allow the user to write anywhere they want inside a text file, thanks to the answers from How do I write to a specific line of file in c? , However i have hit a new obstacle, whenever i write back to the file an annoying random character will always appear at the end of the last word, and if it's on the first line a new line is created before it.
I know this has something to do with the file copy but i don't know where, can someone please help?
int main()
{
FILE *fp,*fc;
int lineNum;
int count=0;
int ch=0;
int edited=0;
char t[16];
fp=fopen("start.txt","r");
fc=fopen("end.txt","w");
if(fp==NULL||fc==NULL)
{
printf("\nError...cannot open/create files");
return 1;
}
printf("\nEnter Line Number Which You Want 2 edit: ");
scanf("%d",&lineNum);
while((ch=fgetc(fp))!=EOF)
{
if(ch=='\n')
count++;
if(count==lineNum-1 && edited==0)
{
printf("\nEnter input to store at line %d:",lineNum);
scanf(" %s[^\n]",t);
fprintf(fc,"\n%s\n",t); /
edited=1;
while( (ch=fgetc(fp))!=EOF )
{
if(ch=='\n')
break;
}
}
else
fprintf(fc,"%c",ch);
}
fclose(fp);
fclose(fc);
if(edited==1)
{
printf("\nCongrates...Error Edited Successfully.");
FILE *fp1,*fp2;
char a;
system("cls");
fp1=fopen("end.txt","r");
if(fp1==NULL)
{
puts("This computer is terrible and won't open end");
exit(1);
}
fp2=fopen("start.txt","w");
if(fp2==NULL)
{
puts("Can't open start for some reason...");
fclose(fp1);
exit(1);
}
do
{
a=fgetc(fp1);
fputc(a,fp2);
}
while(a!=EOF);
fclose(fp1);
fclose(fp2);
getch();
}
else
printf("\nLine Not Found");
return 0;
}
(Sorry about ident, i'm in a rush)
Try changing your do-while loop like,
while((a=fgetc(fp1))!=EOF)
fputc(a,fp2);
I guess it will solve your problem.
do
{
a=fgetc(fp1);
fputc(a,fp2);
}
while(a!=EOF);
A do-while loop evaluates its condition after performing the body of the loop. In other words, this loop is writing EOF to the file, which you shouldn't be doing. EOF isn't actually a character, it's just something that gets returned by the OS when it's finished reading a file. I'm not sure what would be the end result of actually writing EOF to a file, but I'd hazard a guess this is what's causing the "annoying random character" you're talking about.
Invert the loop into a normal while loop, as follows, so that you're checking for EOF before writing anything:
while ((a=fgetc(fp1))!=EOF)
{
fputc(a,fp2);
}
1) As you said "and if it's on the first line a new line is created before it"
To solve this problem you have to optimize the use of fprintf(fc,"\n%s\n",t); statement.
Replace this fprintf(fc,"\n%s\n",t); with below code.
if(count==0) //if its the first line to edit..
fprintf(fc,"%s\n",t) //watch closely,no '\n' before %s,This will copy wihtout creating new line at beginning of line or file.
else
fprintf(fc,"\n%s\n",t);
2) And Your statement scanf(" %s[^\n]",t); will not work properly if you give multiple-words input.You have tried to use both ScanSet and %s fromat specifer. You should only use any one of them.
Lets understand with a code snippet:-
char t[16]="\0";
scanf(" %s[^\n]",t); //Assume that you gave input "abc efg" from keyboard
printf("%s",t); // This will output only "abc" on moniter.
You should change it to some thing like this:-
char t[16]="\0";
scanf(" %15[^\n]",t);//here 15 is sizeof(array)-1. one left to accomadate '\0'.
printf("%s",t); //this will successfully output "abc efg" (if given)

Problems with restarting program

I've been introduced to C this year as part of my degree, during which I have to write simple programs and test them to be idiot-proof by running them over and over again, putting nonsense variables in, etc. and I had an idea to write a program with the ability to restart itself without having to run the program again.
I've tried writing a program to perform this function (which turned out to be harder than I first thought) and I now have it working, albeit using a goto function that are frowned upon. Now the only problem I have is a while loop to check for nonsense input, that seems determined to run at least once ignoring a prompt for a valid input.
Please could someone give me an idea why this is happening? (My compiler is Dev-C++ 4.9.9.2)
int main (void)
{
mainprogram:
printf("\nPROGRAM START\n");
//code copied from an exam, to check that the program performs a function
//when ran through again
int i,j,k;
printf("Please enter 7:");
scanf("%d",&i);
printf("Please enter 4:");
scanf("%d",&j);
printf("Please enter 0:");
scanf("%d",&k);
//this is to check that the program will take input when it is restarted
do {
switch (i%j) {
case 3:
i--;
k*=i;
break;
case 2:
i--;
k+=i;
default:
i--;
k++;
break;
}
printf("i is %d k is %d\n",i,k);
} while (i>0);
//end of copied code
char prompt='y';
printf("\nRestart program?");
scanf("%c",&prompt);
while (prompt != 'y' && prompt != 'Y' && prompt != 'n' && prompt != 'N')
{
//this is the problem section, when entering nonsense input, the error messages
//display twice before pausing for input, and when restarted, the program does
//run again but displays the error messages once before pausing for input
printf("\nERROR: INVALID INPUT");
printf("\n\nRestart program?");
prompt='y';
scanf("%c",&prompt);
}
if (prompt == 'y' || prompt == 'Y')
{
goto mainprogram;
}
//
return 0;
}
while(1){ //parent
printf("\n\nRun program?");
scanf("%c",&prompt);
if (prompt == 'n' || prompt == `N`)
{
printf("\nEXITINT")
return 0;
}
int i,j,k;
printf("Please enter 7:");
scanf("%d",&i);
printf("Please enter 4:");
scanf("%d",&j);
printf("Please enter 0:");
scanf("%d",&k);
switch (i%j)
{
case 3:
i--;
k*=i;
break;
case 2:
i--;
k+=i;
break;
default:
i--;
k++;
break;
}
printf("i is %d k is %d\n",i,k);
} //end while parent
//end of copied code
There are a couple of ways one could restart a program, or more generally loop over some code. Of course, all of that can be done with gotos, but that makes the code hard to understand, so C has equivalent structures for dealing with the most common patterns:
execute code if and as long as condition holds
while (condition)
{
/* code */
}
This means before executing the code, the condition is checked. If the condition holds (its value is non-zero), the code is executed and then looped back to the top. This is equivalent to:
top_of_while:
if (!condition)
goto done;
/* code */
goto top_of_while:
done:
execute code and redo while condition holds
do
{
/* code */
} while (condition)
This means execute code first and then check for a condition. If the condition holds, executed the code again. This is equivalent to:
top_of_do_while:
/* code */
if (condition)
goto top_of_do_while;
iteration
for (initialization; condition; iteration)
{
/* code */
}
This is a kind of while loop that happens a lot, in which there is an initialization, followed by a while loop, which on the bottom changes a variable to form some sort of iteration. This is equivalent to:
initialization;
while (condition)
{
/* code */
iteration;
}
To restart a program, most likely you want the do-while loop, since for sure you know that the program has to execute once. However, by properly initialization the condition variable of a while loop, you can also ensure that the loop is always entered the first time. It's a matter of style and your liking.
Where to actually use goto
Many people would tell you to never use goto. This roots from the fact that overuse of goto had led to a great number of overly complicated programs, the so-called spaghetti code. The reason is that it's hard to build a mental model of a program where the execution can jump around to any other part.
However, gotos are actually very useful in C, without which error-handling becomes a huge pain in the ... neck. This useful usage of goto is for handling errors and cleanup, which are always in the bottom of the function. An example would be:
int *read_nums(int n)
{
int *array, i;
array = malloc(n * sizeof *array);
if (array == NULL)
goto exit_no_mem;
for (i = 0; i < n; ++i)
if (scanf("%d", &array[i]) != 1)
goto exit_bad_input;
return array;
exit_bad_input:
free(array);
exit_no_mem:
return NULL;
}
This way, the code is not cluttered (much) with error handling and cleanup is done very nicely based on how far the function has executed.
I just reformatted your code and indeed # herohuyongtao is right, the break; for case 2 has moved at the end of default which is not useful there.
But there's something really shocking in your code, is that you use a goto. Just remember that rule: WHENEVER YOU USE GOTO, THERE'S A BETTER WAY TO DO IT!
#include <stdio.h>
short int read_input (void) {
printf("\nPROGRAM START\n");
//code copied from an exam, to check that the program performs a function
//when ran through again
int i,j,k;
printf("Please enter 7:");
scanf("%d",&i);
printf("Please enter 4:");
scanf("%d",&j);
printf("Please enter 0:");
scanf("%d",&k);
//this is to check that the program will take input when it is restarted
do {
switch (i%j) {
case 3:
i--;
k*=i;
break;
case 2:
i--;
k+=i;
break; // break at the right spot
default:
i--;
k++;
}
printf("i is %d k is %d\n",i,k);
} while (i>0);
// getchar(); // could be inserted here (discards one char)
// fflush(stdin); // could also do the job (discards all remaining chars in buffer)
char prompt='y';
// here the design choice is to let the user input whatever
// and not updated the output until the right character is given
// which will hide how many wrong chars has been previously in the buffer.
printf("\nRestart program? ");
do {
prompt = getchar();
} while (prompt != 'y' && prompt != 'Y' && prompt != 'n' && prompt != 'N');
if (prompt == 'y' || prompt == 'Y')
return 1;
return 0;
}
int main() {
while (read_input() == 1);
return 0;
}
Now that the code is clean, for your exact problem, you will get into a carriage return problem. Basically, what you do is get input until \n is hit, but when you hit carriage return, you actually send CR + LF. So there's one character that never gets read in the input buffer, that you need to discard.
So you should first read that SO question that sums up very well your problem, and you can either:
add a lone getchar(); just after your //end of copied code comment,
or a fflush(stdin) can do the job (cf the SO Question to learn more about it) but has been designed about flushing output buffers, not input ones,
add a fseek(stdin,0,SEEK_END); which is a bit dirty (and non-portable) but works,
or change your conditions and your use of scanf to take into account that you're actually having more chars in the buffer.
In the code I gave you, I chose the most simplistic solution, which is to discard any wrong input without printing anything.

junk characters from stdin after reading from file in 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);

do something special when user input empty line

I'm just starting to study C. I have a program that prints a menu and let users choose what to do step by step. Now I would like to return to the main menu whenever the user enters an empty line, but how can I do that?
I think I can make a function that return the program to the main menu, but when to call that function? I know it's not good to put an if-else whenever I scanf something...
I am used to the OO world, so this is a bit unfamiliar to me, please help :)
I'm guessing you're using a switch statement to filter your input, so just make an option for '\n', or the newline character, to output the print the menu.
If you're doing something along the lines of:
printf("0) do something\n");
printf("1) do something else\n");
printf("enter) main menu\n");
...then scanf isn't really your friend.
You could do something like this:
char buf[80];
int choice;
printf(menu_text);
fgets(buf, 80, stdin);
if(strlen(buf))
{
sscanf(buf, "%d", &choice);
switch(choice)
{
case 0:
/* etc */
break;
case 1:
/* etc */
break;
}
}
else
{
go_back_to_main_menu();
}
It depends on if the user is communicating by sending a string or a single character/keypress.
If communicating by string, try starting with:
char buffer[MAX_BUF_LEN];
char* pBuffer = buffer;
scanf("%s%*c",pBuffer);
if (strlen(pBuffer) == 0)
goto_main_menu();
else
process_user_input(pBuffer);
If communicating by character/keystroke, try starting with:
int inkey = getchar();
if (inkey == '\n')
goto_main_menu();
else
process_user_input(inkey);
Using an "if/else" after you scanf something is perfectly valid. Anything sent from the user should be checked and validated before it is used anyway.
C language is not an OO world, so I'd say stick with if-else. Anyway, when creating text menus you usually end up with switch(user_choice) of if-else.
Do you need a help with scanf()?

Resources