C Board  

Go Back   C Board > General Programming Boards > C Programming

Reply
 
LinkBack Thread Tools Display Modes
Old 08-09-2008, 10:43 AM   #1
Registered User
 
Join Date: Aug 2008
Posts: 3
Trouble writing characters to a file.

I've been learning the C programming language for 2 days now (I'm fairly experienced with Javascript) and I have a problem with this code:

Code:
#include <stdio.h>
FILE *file1;
main() 
{
char thisChar;
file1 = fopen("file1.txt","a");
printf("Type a character to print to the file. Type a slash / to exit: ");
labl:
scanf("%c",&thisChar);
if(thisChar=='/') {
 goto the_end; }
else {
fputc(thisChar,file1);
}
goto labl;

the_end:
}
When I open file1.txt, every character which has been written to the file appears on a separate line. I want them to appear on a single line. What's going on? Any help much appreciated. I'm finding C very challenging, but I hope to eventually be fairly good at it.
Chris
themusician31 is offline   Reply With Quote
Old 08-09-2008, 12:37 PM   #2
The Richness...
 
Richie T's Avatar
 
Join Date: Jan 2006
Location: Ireland
Posts: 469
When you type a character, you press enter and then type another, you press enter again and so on in this manner. The problem is that when you press enter, that is represented as a newline character - it gets left in the program's input buffer and the next time scanf is called, it gets read into thisChar.

There are a number of solutions:

1. Just call scanf() again after you write to the file to read in the extra newline character, or use getchar() immediately after the call to scanf(). I don't recommend using getchar() and scanf() together since it can cause confusion, but I think it would be clearer than using a second scanf().
2. Use getchar() instead of scanf() altogether, and enter the characters all at once (instead of hitting enter after each). This is a good option if you want the program to work for an arbitrary number of characters entered.
3. Read in the characters as a string using fgets(). The only problem with this approach is that it will require you to set a limit on the number of characters to be entered. See my signature for an example of using fgets(). Then to write to the file you would use fputs() or fprintf().

Now onto the problems you didn't ask about:

1. The main() function must return int - in fact you should probably use int main (void). This is more important than it seems and is a big issue for many people on the board. Learn it now, or you can expect to be told repeatedly to change. If you want an explanation, see the appropriate link in my signature.
2. You should use a more consistant style of indentation to make your code more readable. This is very important when asking for help, as many people won't ready code if it is not indented consistantly. There are many styles to choose from, pick one and stick with it throughout an indivual project at the very least. Read this.
3. The use of goto is not recommended. There is no reason why you can't achieve your goal using a while loop instead. Read this tutorial on loops. The problem with goto is that it tends to hide the operation of the code from others, and in a large piece of code, even the author can get confused. For and while loops are much more expressive ways to control program flow.
__________________
No No's:
fflush (stdin); gets (); void main ();


Goodies:
Example of fgets (); The FAQ, C/C++ Reference


My Gear:
OS - Windows XP
IDE - MS Visual C++ 2008 Express Edition


ASCII stupid question, get a stupid ANSI
Richie T is offline   Reply With Quote
Old 08-09-2008, 12:39 PM   #3
Registered User
 
Join Date: Oct 2001
Posts: 2,110
When you press enter, that goes into your scanf like the character does. Then it gets spit out to the file. To avoid this, add an if statement checking for \n.

Indent your code and use loops instead of goto there.

edit: beaten.
robwhit is offline   Reply With Quote
Old 08-09-2008, 12:40 PM   #4
and the hat of vanishing
 
Salem's Avatar
 
Join Date: Aug 2001
Location: The edge of the known universe
Posts: 21,214
Doesn't Javascript have loops?

Two gotos in so few lines, not good.

%c reads newlines (which will be written to the file).
So try typing in say
hello world/


*edit* 3rd Place!?
__________________
If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
Up to 8Mb PlusNet broadband from only £5.99 a month!
Salem is offline   Reply With Quote
Old 08-09-2008, 12:48 PM   #5
Registered User
 
Join Date: Aug 2008
Posts: 3
Thank you all very much
I use Goto because I've also tried PureBasic before, which has a similiar function (Gosub)
I'll try and improve my code so that several characters can be written to the file at once (which was my eventual aim after all).
Chris

---
EDIT:

I've managed to come up with this code, which is much better. I learnt a fair bit and tried to apply it to this code.
I'm not sure why I'm putting int in front of main(void), but if it's good practice, I'd rather do it.

Code:
#include <stdio.h> 

FILE *file2;
int main(void)
{
  char thisChar[10];
  file2 = fopen("file2.txt","a");
  
    printf ("Please enter a line of text, max %d characters\n", 8);
    fgets(thisChar, sizeof(thisChar)+1, stdin);
    fputs (thisChar,file2);
    printf ("%s has been written to the file.\n",thisChar);

}

Last edited by themusician31; 08-09-2008 at 01:41 PM.
themusician31 is offline   Reply With Quote
Old 08-09-2008, 09:57 PM   #6
CSharpener
 
vart's Avatar
 
Join Date: Oct 2006
Posts: 5,242
Quote:
sizeof(thisChar)+1
bad idea to lie to fgets - you just asking for buffer overrun

also no reason to make file2 global

and as I remember - puts adds new line char at the end, while fgets does not removes one from the input

so you will write new line char twice...

You also are missing checks for return values of fopen and fgets before using its results
__________________
If I have eight hours for cutting wood, I spend six sharpening my axe.
vart is offline   Reply With Quote
Old 08-10-2008, 05:38 AM   #7
Registered User
 
Join Date: Aug 2008
Posts: 3
This is what my code looks like now:

Code:
#include <stdio.h> 


int main()
{
  FILE *file1;
  char thisChar[15];
  char *p;
  file1 = fopen("file1.txt","a");
  
  printf ("Please enter a line of text, max %d characters\n",sizeof(thisChar));
  
      fgets(thisChar, sizeof(thisChar)+1, stdin);
      if ((p = strchr(thisChar, '\n')) != NULL) {
      *p = '\0'; }
      fprintf(file1,"%s",thisChar);
      printf ("Written to the file.\n",thisChar);
}
BTW, is there a disadvantage to making file1 global?
If I DO set the size of fgets to 'sizeof(thisChar)', it only allows 14 characters, whereas the size of thisChar when declared is 15. I already knew this would happen as I had read it on another site - it said it will allow one less than the value declared in the second parameter of fgets().
Chris
themusician31 is offline   Reply With Quote
Old 08-10-2008, 05:50 AM   #8
and the hat of vanishing
 
Salem's Avatar
 
Join Date: Aug 2001
Location: The edge of the known universe
Posts: 21,214
> BTW, is there a disadvantage to making file1 global?
Too many global variables result in an unreadable, and unmaintainable mess.
Like a lot of things in C, they're occasionally very useful, but over-use makes things worse rather than better.

> If I DO set the size of fgets to 'sizeof(thisChar)', it only allows 14 characters, whereas the size of thisChar when declared is 15
So make the array bigger.
In particular, if you type in "hello", then what is in the buffer is "hello\n\0".
Adjust the buffer size to allow for the \n\0 to be stored as well.

Do NOT tell fgets() that it has more space than there is available, that's just plain wrong.
__________________
If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
Up to 8Mb PlusNet broadband from only £5.99 a month!
Salem is offline   Reply With Quote
Reply

Tags
beginner, file, scanf

Thread Tools
Display Modes

Forum Jump

Similar Threads
Thread Thread Starter Forum Replies Last Post
printing "\n" every ten characters and also at the end of a file. Sgemin_001 C Programming 8 12-06-2008 02:43 PM
Memory Address kevinawad C++ Programming 18 10-19-2008 10:27 AM
Post... maxorator C++ Programming 12 10-11-2005 08:39 AM
Dikumud maxorator C++ Programming 1 10-01-2005 06:39 AM
simulate Grep command in Unix using C laxmi C Programming 6 05-10-2002 04:10 PM


All times are GMT -6. The time now is 10:44 PM.


Powered by vBulletin® Version 3.8.1
Copyright ©2000 - 2009, Jelsoft Enterprises Ltd.
Search Engine Optimization by vBSEO 3.3.0 RC2

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22