Here is my code
#include<stdio.h>
int main()
{
FILE* fp;
int i;
fp=fopen("newfile","r");
if(fp==NULL)
{
printf("hhaha");
return 0;
}
char str[20];
for(i=0;i<2;i++)
{
fgets(str,20,fp);
printf("%s",str);
}
return 0;
}
Now if my newfile has text
my name
is xyz
then how come when i print the two lines are printed in two newlines?
where does the newline character come from?
fgets sets the pointer to a char * representing the line of the file including the \n at the end of the line. (As is the case with most strings, it will also be '\0' terminated)
A file with this:
Thisismyfile
Will have this from fgets:
This\n\0,is\n\0,my\n\0,file\n\01
1The final value may not be include \n. That will depend on whether it is a \n terminated file.
from man fgets
gets() reads a line from stdin into the buffer pointed to
by s until either a terminating newline or EOF, which it replaces with
'\0'. No check for buffer overrun is performed
(see BUGS below).
fgets() reads in at most one less than size characters from
stream and stores them into the buffer pointed to by s. Reading stops
after an EOF or a newline. If a newline is read,
it is stored into the buffer. A '\0' is stored after the last
character in the buffer.
and thus fgets behaviour is different from what you might expect
From the linux man page for fgets():
fgets() reads in at most one less than size characters from
stream and stores them into the buffer pointed to by s. Reading stops
after an EOF or a newline. If a newline is read, it is stored into
the buffer. A '\0' is stored after the last character in thebuffer.
fgets() includes the newline when reading into the string - that's how fgets() is defined to work. From the standard:
No additional characters are read after a new-line character (which is retained) or after end-of-file.
Related
I am currently studying input and output in C and I have found out that there are about a billion different ways to get input, such as, getch, getchar, gets and fgets, and the same with output (putchar, puts, fputs, etc.).
All these different methods of I/O are confusing me quite a bit, so I came on here to ask what the basic differences between the aforementioned functions are.
I also wrote a bit of code using these different functions and I commented in how I think they work, based on what I've learnt, but I'm not sure if my understanding is correct. I've read up on them in other places as well, but the explanations are very complicated and don't seem coherent.
So could anyone please tell me if I am using them correctly and if not, how I should use them and what are the main differences between them?
Here is my code:
#include <stdio.h>
#include <stdbool.h>
#include <string.h>
#include <ctype.h>
void individualCharacters()
{
char theChar;
while ((theChar = getchar()) != '~') { // getchar() stores all characters in a line buffer as it is entered until newline is entered
putchar(theChar); // putchar() prints the characters in the line buffer and does not print a newline, line buffering depends on compiler
}
}
void withoutF()
{
char name[50];
printf("What is your name? ");
gets(name); // receives a string until newline is entered, newline is then replaced with string terminator, array limit should not be passed
puts("Hi"); // only prints one string at a time and adds the newline because gets() previously replaces the newline
puts(name);
}
void withF()
{
char name[50];
printf("What is your name? ");
fgets(name, 50, stdin); // does add a newline so the newline takes up one space in the array, it stores input until either newline is entered or array limit is reached
fputs("Hi ", stdout); // does not print a newline but prints the string input up to the array limit
fputs(name, stdout);
}
void main()
{
//sum();
//individualCharacters();
//withoutF();
//withF();
//printRandomString();
}
These are just some functions I wrote that get input and display output in different ways, but I'm having trouble understanding why there are so many different ways of doing so.
If I have made any mistakes using the I/O functions, feel free to tell me so I can make amendments.
Thank you
fgets - reads up to SIZE-1 characters from a specified stream into a buffer, including the trailing newline if there's room. Adds a 0 terminator to the end of the buffer, making it a valid C string:
char buffer[SIZE];
if ( fgets( buffer, sizeof buffer, stdin ) ) // read from standard input
do_something_with( buffer );
else
error();
On success, fgets returns the address of the input buffer. On failure or end-of-file, it returns NULL.
fgetc - reads a single character from the specified input stream and returns it:
FILE *input_stream = fopen( "some_file", "r" );
int c;
while ( (c = fgetc( input_stream )) != EOF )
do_something_with( c );
gets - was deprecated after C99, removed completely from C2011. Like fgets, it would read a sequence of characters from standard input into a buffer and add a 0 terminator, but unlike fgets it did not provide a mechanism to limit input, making it a popular malware exploit. Also, it would not store a trailing newline to the buffer. Using it was guaranteed to introduce a point of failure in your code. Pretend you've never heard of it.
getc - identical to fgetc, except that it may be implemented as a macro.
getchar - reads a single character from standard input:
int c;
...
while( (c = getchar()) != EOF )
do_something_with( c );
fputs - writes a string to the specified output stream:
char str[SIZE];
...
fputs( str, output_stream );
fputc - writes a single character to the specified output stream:
while ( i < strsize )
fputc( str[i], output_stream );
putc - identical to fputc, except that it may be implemented as a macro
putchar - writes a single character to standard output.
getch() is a function that prompts to press a key,in which the character is not echoed back.
In contrast getche() will echo the character back.
gets() will read characters from stdin but is unsafe(use fgets() instead).
getchar() will return the next character it reads from stdin, it's same as calling getc() with stdin as an argument.
fgets() reads characters from a stream (like a file or stdin), and stores them as a C string into str until (num-1) characters have been read or newline or EOF is reached.
putch() writes a character to stdout. It's same as calling putc() with stdout as an argument.
puts() writes a C string pointed by str to stdout and appends a newline character. It starts copying till it reached the null-terminator(\0). Null-terminator is not printed.
fputs() writes a C string pointed by str to the stream, and is essentially like puts()
As for your code,try to avoid using gets(), as it is unsafe and use scanf(), same goes for puts(). Use printf() instead.
Here,give this a read: http://www.cplusplus.com/reference/cstdio/
I know it's C++ reference but the library functions are the same
fgets
char * fgets ( char * str, int num, FILE * stream );
Get string from stream
Reads characters from stream and stores them as a C string into str until (num-1) characters have been read or either a newline or a the End-of-File is reached, whichever comes first.
A newline character makes fgets stop reading, but it is considered a valid character and therefore it is included in the string copied to str.
A null character is automatically appended in str after the characters read to signal the end of the C string.
fputs
int fputs ( const char * str, FILE * stream );
Write string to stream
Writes the string pointed by str to the stream.
The function begins copying from the address specified (str) until it reaches the terminating null character ('\0'). This final null-character is not copied to the stream.
getchar
function
<cstdio>
int getchar ( void );
Get character from stdin.
Returns the next character from the standard input (stdin).
It is equivalent to getc with stdin as its argument.
putchar
function
<cstdio>
int putchar ( int character );
Write character to stdout
Writes character to the current position in the standard output (stdout) and advances the internal file position indicator to the next position.
It is equivalent to putc(character,stdout).
gets: from standard input to memory
puts: from memory to standard input
Example :
#include<stdio.h>
void main( )
{
char name[10];
printf("What is your first and last name?");
gets(name);
puts(name);
}
I am relatively new to C programming, but, from what I understand, fscanf skips any whitespace when scanning input for every type beside characters. What other means do I have to scan integers while keeping any newline character that may be attached to them within the file (as I actually want to do something with these newline characters)?
You can use fgets in the following format:
char *fgets(char *s, int size, FILE *stream);
and as it's man page says:
fgets() reads in at most one less than size characters from stream and stores them into the buffer pointed to by s. Reading stops after an EOF or a newline. If a newline is read, it is stored into the buffer. A terminating null byte ('\0') is
stored after the last character in the buffer.
It will read a newline character, however it will stop reading after that and terminate with the null character.
You could use fcanf(file,"%[^\n]") which takes everything up to user hit enter.
I have taken a string from the keyboard using the fgets() function. However, when I print the string using printf(), the cursor goes to a new line.
Below is the code.
#include<stdio.h>
int main()
{
char name[25];
printf("Enter your name: ");
fgets(name, 24, stdin);
printf("%s",name);
return 0;
}
And below is the output.
-bash-4.1$ ./a.out
Enter your name: NJACK1 HERO
NJACK1 HERO
-bash-4.1$
Why is the cursor going to the next line even though I have not added a \n in the printf()?
However, I have noticed that if I read a string using scanf(), and then print it using printf() (without using \n), the cursor does not go to next line.
Does fgets() append a \n in the string ? If it does, will it append \0 first then \n, or \n first and then \0?
The reason printf is outputting a newline is that you have one in your string.
fgets is not "adding" a newline --- it is simply reading it from the input as well. Reading for fgets stops just after the newline (if any).
Excerpt from the manpage, emphasis mine:
The fgets() function reads at most one less than the number of characters specified by size from the given stream and stores them in the string str. Reading stops when a newline character is found, at end-of-file or error. The newline, if any, is retained. If any characters are read and there is no error, a `\0' character is appended to end the string.
An easy way to check if there's a newline is to use the help of one of my favorite little-known functions --- strcspn():
size_t newline_pos = strcspn(name, "\r\n");
if(name[newline_pos])
{
/* we had a newline, so name is complete; do whatever you want here */
//...
/* if this is the only thing you do
you do *not* need the `if` statement above (just this line) */
name[newline_pos] = 0;
}
else
{
/* `name` was truncated (the line was longer than 24 characters) */
}
Or, as an one-liner:
// WARNING: This means you have no way of knowing if the name was truncated!
name[strcspn(name, "\r\n")] = 0;
Because if there is a '\n' in the read text it will be taken by fgets(), the following was extracted from the 1570 draft §7.21.7.2 ¶ 2
The fgets function reads at most one less than the number of characters specified by n
from the stream pointed to by stream into the array pointed to by s. No additional
characters are read after a new-line character (which is retained) or after end-of-file. A
null character is written immediately after the last character read into the array.
I highlighted by making bold the part which says that the '\n' is kept by fgets().
I've some doubts about fgets. From what I know, it adds "\n" at the end of the string, and not "\0". So if I write this code:
fgets(buff,2,stdin);
printf("%s",buff);
So fgets reads two characters, I give as input "y", so buff should be "y\n". I'd expect printf to print y and add a line, while it prints "y" without adding a line. Can you explain why?
char * fgets ( char * str, int num, FILE * stream );
Reads characters from input stream and stores them as a C string into str until (num-1) characters have been read or either a newline or the end-of-file is reached, whichever happens first.
A newline character makes fgets stop reading, but it is considered a valid character by the function and included in the string copied to str.
A terminating null character ('\0') is automatically appended after the characters copied to str.
It must terminate the string, so yes it will always add '\0' at the end. However, fgets might not always add the newline, if it doesn't fit. I recommend this reference page for fgets.
According to man page it clearly given :
char *fgets(char *s, int size, FILE *stream);
fgets() reads in at most one less than size characters from stream
and
stores them into the buffer pointed to by s. Reading stops after an
EOF or a newline. If a newline is read, it is stored into the buffer.
A '\0' is stored after the last character in the buffer.
fgets() adds \0 at the end but it reads the string with \n if it exists in the file
i have such thing after reading string:
"guitar\n\0\U00000004\xd5..."
my file had string with word "guitar" and \n after it
so, as u see it read the word with "\n" and added "\0" to the string
When allocating Strings on the heap (with 'malloc'),
and initializing them with the standard input (using 'fgets),
an unnecessary newline appears between them when trying to print them (with 'printf' and %s formatting).
for example:
main()
{
char *heap1;
char *heap2;
heap1=malloc(10);
heap2=malloc(10);
fgets(heap1,10,stdin);
fgets(heap2,10,stdin);
printf("%s%s",heap1,heap2);
}
with input "hi1\nhi2" produces "hi1\nhi2".
compiled using gcc 4.3.4 for Debian.
fgets also reads the '\n' (newline) character. You should remove it if you don't want it to print like that.
heap1[strlen(heap1) - 1] = '\0';
after you read the contents of heap1.
fgets returns the newline as part of the string.
See man 3 fgets. Specifically:
fgets() reads in at most one less
than size characters from stream and
stores them into the buffer pointed
to by s. Reading stops after an
EOF or a newline. If a newline is
read, it is stored into the buffer.
A '\0' is stored after the last
character in the buffer.
fgets is probably appending the newline. Try trimming the string you get back from fgets.