read text from file C string terminator - c

I want to read a text from file which contains also '\n' character
This is my function
void readFromFile (FILE * fid, unsigned char * mesage) {
unsigned char c;
int mesage_length = 0;
while((c = fgetc(fid)) != EOF) {
mesage[mesage_length] = c;
mesage_length++;
}
}
I have completely absolute no idea why when it gets to the '\n' my program crashes, it enters in an infinite loop and the mesage_length grows up to 13992 or something, but i read only 13 characters like : "Why not working?\n"
How can i read the whole text until EOF and put it into a string (char *) ?
If i put the condition inside the while if(c == '\n') break; it works fine.. but would read until the first \n

Related

Printing char of a file with fgetc() ending with a "?" symbol

I'm trying to print the chars (with fgetc) in a file one by a one with a while loop.
I'm using the latest Atom editor to write the code, and I compile with the GPP Compiler, by pressing F5 and the output is displayed in the xterm terminal.
int main(int argc, char const *argv[])
{
FILE* file = NULL;
file = fopen("text.txt", "r+");
int letter = 0;
if (file != NULL)
{
while(letter != EOF)
{
letter = fgetc(file);
printf("%c", letter);
}
I expected the output to be the text in my file, which it is, but at the end there's a question mark symbol.
What I understood after doing some research is that my fgetc function reads the EOF like a normal character and prints it, resulting in a question mark symbol at the end.
Thanks for your help !
... ending with a “?” symbol
doing
while(letter != EOF)
{
letter = fgetc(file);
printf("%c", letter);
}
you print letter before to check if it is EOF, so you (try to) print EOF which is not a character, producing the unexpected output
Example of a valid code :
while ((letter = fgetc(file)) != EOF)
putchar(letter); /* or printf("%c", letter); if you prefer */
I have been having the same issue and I found out that the return type for fgetc is an integer and it may be returning -1.

how to stop my program from skipping characters before saving them

I am making a simple program to read from a file character by character, puts them into tmp and then puts tmp in input[i]. However, the program saves a character in tmp and then saves the next character in input[i]. How do I make it not skip that first character?
I've tried to read into input[i] right away but then I wasn't able to check for EOF flag.
FILE * file = fopen("input.txt", "r");
char tmp;
char input[5];
tmp= getc(file);
input[0]= tmp;
int i=0;
while((tmp != ' ') && (tmp != '\n') && (tmp != EOF)){
tmp= getc(file);
input[i]=tmp;
length++;
i++;
}
printf("%s",input);
It's supposed to print "ADD $02", but instead it prints "DD 02".
You are doing things in the wrong order in your code: The way your code is structures, reading and storing the first char is moved out of the loop. In the loop, that char is then overwritten. In that case start with i = 1.
Perhaps you want to read the first character anyway, but I guess you want to read everything up to the first space, which might be the first character. Then do this:
#include <stdio.h>
int main(void)
{
char input[80];
int i = 0;
int c = getchar();
while (c != ' ' && c != '\n' && c != EOF) {
if (i + 1 < sizeof(input)) { // store char if the is room
input[i++] = c;
}
c = getchar();
}
input[i] = '\0'; // null-terminate input
puts(input);
return 0;
}
Things to note:
The first character is read before the loop. the loop condition and the code that stores the char then use that char. Just before the end of the loop body, the next char is read, which will then be processed in the next iteration.
You don't enforce that the char buffer input cannot be overwritten. This is dangerous, especially since your buffer is tiny.
When you construct strings char by char, you should null-terminate it by placing an explicit '\0' at the end. You have to make sure that there is space for that terminator. Nearly all system functions like puts or printf("%s", ...) expect the string to be null-terminated.
Make the result of getchar an int, so that you can distinguish between all valid character codes and the special value EOF.
The code above is useful if the first and subsequent calls to get the next item are different, for example when tokenizing a string with strtok. Here, you can also choose another approach:
while (1) { // "infinite loop"
int c = getchar(); // read a char first thing in a loop
if (c == ' ' || c == '\n' || c == EOF) break;
// explicit break when done
if (i + 1 < sizeof(input)) {
input[i++] = c;
}
}
This approach has the logic of processing the chars in the loop body only, but you must wrap it in an infinite loop and then use the explicit break.

puts() output is appended "time" string

I get very unexpected output from quite simple code
char ch = getchar(), word[100], *p = word;
while (ch != '\n') {
*(p++) = ch;
ch = getchar();
}
puts(word);
output of any 17 character input is appended by "time" like
12345678901234567time
if exceeds "time" is overwritten like
1234567890123456789me
Am I doing something wrong?
puts expects a pointer to string. And a string needs to have a terminating null character - \0 - to signify where the string ends.
But in your case, you did not write the \0 at the end to signify that the string ends there.
You need to do:
char ch = getchar(), word[100], *p = word;
/* Also check that you are not writing more than 100 chars */
int i = 1;
while(ch != '\n' && i++ < 100){
*(p++) = ch;
ch = getchar();
}
*p = '\0'; /* write the terminaring null character */
puts(word);
Before, when you were not writing the terminating null character you could not expect anything determinate to print. It could also have been 12345678901234567AnyOtherWord or something.
There are multiple issues in your code:
You do not null terminate the string you pass to puts(), invoking undefined behavior... in your case, whatever characters happen to be present in word after the last one read from stdin are printed after these and until (hopefully) a '\0' byte is finally found in memory.
You read a byte from stdin into a char variable: this does not allow you to check for EOF, and indeed you do not.
If you read a long line, you will write bytes beyond the end if the word array, invoking undefined behavior. If the end of file is encountered before a '\n' is read from stdin, you will definitely write beyond the end of the buffer... Try for example giving an empty file as input for your program.
Here is a corrected version:
char word[100];
char *p = word;
int ch;
while ((ch = getchar()) != EOF && ch != '\n') {
/* check for long line: in this case, we truncate the line */
if (p < word + sizeof(word) - 1) {
*p++ = ch;
}
}
*p = '\0';
puts(word);

Reading a line from a text file into an array of characters in c

I am trying to fill an array from a text file. the array is in a struct which is:
struct ISBN
{
long value;
};
struct Author
{
char authorName[60];
};
struct Book
{
char *bookTitle;
struct Author bookAuthor;
struct ISBN bookID;
};
I tried to write a fillin function which takes the file and struct of type Book, like this:
void fillin (FILE * file, struct Book * bk)
{
bk->bookTitle =(char*) malloc(1000);
size_t n = 0;
int c;
file=fopen("book.txt","r");
while ((c = fgetc(file)) != '\n')
{
bk->bookTitle[n++] = (char) c;
}
bk->bookTitle[n] = '\0';
fscanf(file,"%s", &bk->bookAuthor.authorName);
fscanf(file,"%lld",&bk->bookID.value);
//fscanf(file,"%s", &bk->bookTitle);
}
File book.txt has this data:
UNIX Network Programming
W. Richard Stevens
0131411551
The problem is, it can not scan arrays and i want to fill bookTitle and autherName arrays from the textfile.
The following line is wrong:
fscanf(file,"%s", &bk->bookAuthor.authorName);
When you scan a string, the character array is already a pointer, so you don't take the address of it (&). Try:
fscanf(file,"%s", bk->bookAuthor.authorName);
For safety (in case of long strings), you can use this function:
char * fgets ( char * str, int num, FILE * stream );
Hence:
fgets(bk->bookAuthor.authorName, 60, file);
If the line is too long, the rest of the string won't be copied in. If you do this, you might have to check if the the string is not yet terminated, and throw away the rest of the characters until the newline. (eg. while ((c = fgetc(file)) != '\n');). The \n character is copied in, so you will have to find and remove it:
bk->bookAuthor.authorName[59] = 0; // make sure it is null-terminated
int last = strlen(bk->bookAuthor.authorName)-1;
if (bk->bookAuthor.authorName[last] == '\n') {
bk->bookAuthor.authorName[last] = 0; // read whole line
}
else ; // terminated early
You can also limit the characters with fscanf, and read spaces as well, using:
char c;
scanf(file, "%60[^\n]%c", bk->bookAuthor.authorName, c);
if (c=='\n') {
// we read the whole line
} else {
// terminated early, c is the next character
//if there are more characters, they are still in the buffer
}
To discard the rest of the line, you can do something like
while (c != '\n' && c != EOF) c = fgetc(file);

Read characters from a file and store them in a variable in C

I am trying to read character by character from a file and store the characters in a variable.
Only the content from the first line of the file is required so I am using \n or EOF to stop reading. It is required to store SPACE also.
Here is my program:
#include<stdio.h>
#include<string.h>
void main()
{
FILE *fp;
char ch;
char txt[30];
int len;
fp=fopen("~/hello.txt","r");
ch=fgetc(fp);
while(ch != EOF || ch!="\n")
{
txt[len]=ch;
len++;
ch=fgetc(fp);
}
puts(txt);
}
But I am getting a warning while compiling like comparison between pointer and integer. And when I run it I am getting a segmentation fault.
You're comparing to the wrong thing. Try:
ch != '\n'
^ ^
Also, as spotted in other answers, you're using len without initializing it.
Finally, you do realize fgets can do that as well. You could rewrite the thing to:
if (fgets(txt, sizeof txt, fp))
...
1) len is not initiated
int len=0;
2) From fgetc() page:
int fgetc ( FILE * stream );
so the fgetc() return int and not char so you have to define ch as int
int ch;
3) In addition of the cnicutar remark, the while condition should be checked with the && and not with ||:
while(ch != EOF && ch!='\n')
4) You have to add null terminator charachter at the end of your txt buffer after finishing reading from file.
Add this line after the while loop
txt[len]='\0';
BTW you can read the first line with fscanf() it's more easier. Just use the following code
fscanf(fp, "%29[^\n]", txt);
The "%[^\n]" means that fscanf will read all characters from fp except the '\n' charachter and it will stop reading if it gets this charachter. So the fscanf will read all characters from fp till it find '\n' character and save them into the buffer txt with null terminator charchter at the end.
The "%29[^\n]" means that fscanf will read all characters from fp till it find '\n' character or till it reach 29 readed charchters and save them into the buffer txt with null terminator charchter at the end.
len is not initialised so you're probably attempting to write way beyond the end of txt. The fix is simple - initialise it to 0 on declaration
int len = 0;
In addition to the error pointed out by cnicutar, you should also check the return value from fopen before using fp.
#include<stdio.h>
#include<string.h>
void main()
{
FILE *fp;
char ch;
char txt[30];
int len = 0;
fp=fopen("~/hello.txt","r");
if(!fp) {
printf("Cannot open file!\n");
return;
}
ch=fgetc(fp);
while(ch != EOF && ch!= '\n' && len < 30)
{
txt[len] = ch;
len++;
ch=fgetc(fp);
}
txt[len] = 0;
puts(txt);
}
This program may help you to solve your problem.
#include<stdio.h>
int main()
{
FILE *fp;
int ch;
char txt[300];
int len=0;
fp=fopen("tenlines.txt","r");
do{
ch=fgetc(fp);
txt[len]=ch;
len++;
} while(ch!=EOF && ch!='\n');
fclose(fp);
puts(txt);
return 0;
}

Resources