can't read string from file in c - c

I'm trying to read a text file line by line and printing the first 17 characters.
FILE *devices;
devices = NULL;
devices = fopen("devices.txt", "r");
char deviceaddr[17];
char addr[17];
char line[1024];
while (fgets(line,1024,devices) != NULL)
{
fscanf(devices,"%s", deviceaddr);
printf("%s\n", deviceaddr);
}
fclose(devices);
the output should be 00:07:80:4C:0E:EEfor the first line but it gives 6.

The while loop is reading a line of text, then the fscanf will read the next set of text (and possibly overrun that buffer incidentally). It seems as if you should just be printing the desired data inside the loop from the buffer line.
For example, suppose there are three lines of text.
00:07:80:4C:0E:EE --> ends up line buffer line
second --> ends up in deviceaddr
third line --> ends up in line (unless the fscanf did not consume newline)

There's no way the output can be "00:07:80:4c:0E:EE", since
that would result in undefined behavior, due to buffer
overrun—the string requires 18 bytes, but you only provide
17. You should never us "%s" in an fscanf without
specifying the length.
And you're calling fscanf on devices after having read
a line from it; if you're reading line by line, you want to use
sscanf on the line you've read.

Related

How can I get one line and other lines in two parts in C?

I try to get input from a text file. First line of the text only contains a number, then others related with it like that;
4
ssss
sss
ss
s
I used fgets function for getting these lines from file, but I want to use "4" and the other lines in different functions.
I was getting both these lines with fgets like that;
char inp[150];
int i;
FILE *fp;
while(1) {
if(fgets(inp, 150, fp) == NULL) break;
printf("%s",inp);
i++;
}
I used printf for only see that this code getting all lines or not. It is getting all lines same with input, but when I try to print first line of the input "inp[0]", I expect to print "4", but it prints "s" again.
Therefore, I can't use or get the number which is in the first line. How can I print or use first line independently from others.
By the way, the number and the other lines ,which are related with it, can change with another inputs.
Pass the file pointer to the functions, and have them attempt to read the lines.
That's a basic parser for you.
Don't forget to:
Do error handling, and properly indicate if a read failed.
Reset the file pointer position in case of failure.
Store the result of fgetpos at the beginning and restore it with fsetpos
The problem with your code is that fgets(inp, 150, fp) reads until newline, 149 characters read or EOF.
So each timefgets(inp, 150, fp) you store new values in inp. And last value is s.
Try to use fgetc and store character by character in inp.

Reading line by line in C

Currently to read a file line by line in C I am using:
char buffer[1024];
while(fgets(buffer, sizeof(buffer), file) != NULL) {
//do something with each line that is now stored in buffer
}
However there is no guarantee in the file that the line will be shorter than 1024. What will happen if a line is longer than 1024? Will the rest of the line be read in the next iteration of the while loop?
And how can I read line by line without a maximum length?
Yes, the rest of the line will be read in the next iteration.
You can detect whether or not you read a whole line by inspecting the last character of the string (i.e. the one before the null terminator) to see if it is '\n' or not -- fgets passes '\n' through to you.
There is no Standard C function which will read a line whilst dynamically allocating enough memory for it, however there is a POSIX function getline() which does that. You could write your own that uses fgets or otherwise to do the reading, in a loop with realloc, of course.
From the standards §7.19.7.2,
char *fgets(char * restrict s, int n, FILE * restrict stream);
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.
From MSDN,
fgets reads characters from the current stream position to and including the first newline character, to the end of the stream, or until the number of characters read is equal to n – 1, whichever comes first. The newline character, if read, is included in the string.
So, yes fgets will read the rest of the line in next iteration if the it doesn't encounters the newline character within sizeof(buffer)-1 range.
If you want to read the whole line in one shot, then it is better to go with malloc and, if needed, reallocing the memory as per your needs.

File read in 'c' using fgets

If i have a text file with each line of different length, how does the following code work??
FILE *ptr;
char str[100];
ptr=fopen("hi.txt","r");
while(fgets(str,100,ptr)!=NULL)
{
........
........
}
In this code the 'str' will hold 100 characters which includes some of the characters from 2nd line of text file(if the 1st line of file is 90 chars then 10 chars from second line will also be read)..
If i am correct, can you please tell how to read exactly only one line during every ready?
fgets will read up to a single line OR the value passed in as the second parameter.
fgets man page
As long as none of your lines are longer than 99 characters (saving one for the NUL terminator, your code will work as expected.
If you call fgets on a line that is longer than N-1, your next read will continue where it left off and go another 99 bytes or until it finds the end of the line.

fscanf not scanning file

I am trying to scan a file using fscanf and put the string into an char array of size 20 as follows:
char buf[20];
fscanf(fp, "%s", buf);
The file fp currently contains: 1 + 23.
I am setting a pointer to the first element in buf as follows:
char *p;
p = buf;
Printing buf, printf("%s", buf) yields only 1. Trying to increment p and printing prints out rubbish as well (p++; printf("%c", *p)).
What am I doing wrong with fscanf here? Why isn't it reading the whole string from the file?
fscanf (and related functions) with the format-string "%s" will try to read as many characters as it can without including a whitespace, in this case it will find the first character (1) and store it, then it will hit a space () and therefore stop searching.
If you'd like to read the whole line at once consider using fgets, it is also safer to use since you need to specify the size of your destination buffer as one of it's arguments.
fgets will try to read at maximum length-of-buffer minus 1 characters (last byte is saved for the trailing null-byte), it will stop at either reading that many characters, hitting a new-line or the end of the file.
fgets (buf, 20, fp);
Links to documentation
codecogs.com - scanf, fscanf and related functions - <stdio.h>
codecogs.com - fgets - <stdio.h>

How to skip a line when fscanning a text file?

I want to scan a file and skip a line of text before reading. I tried:
fscanf(pointer,"\n",&(*struct).test[i][j]);
But this syntax simply starts from the first line.
I was able to skip lines with scanf with the following instruction:
fscanf(config_file, "%*[^\n]\n");
The format string matches a line containing any character including spaces. The * in the format string means we are not interested in saving the line, but just in incrementing the file position.
Format string explanation:
% is the character which each scanf format string starts with;
* indicates to not put the found pattern anywhere (typically you save pattern found into parameters after the format string, in this case the parameter is NULL);
[^\n] means any character except newline;
\n means newline;
so the [^\n]\n means a full text line ending with newline.
Reference here.
fgets will get one line, and set the file pointer starting at the next line. Then, you can start reading what you wish after that first line.
char buffer[100];
fgets(buffer, 100, pointer);
It works as long as your first line is less than 100 characters long. Otherwise, you must check and loop.
It's not clear what are you trying to store your data into so it's not easy to guess an answer, by the way you could just skip bytes until you go over a \n:
FILE *in = fopen("file.txt", "r");
Then you can either skip a whole line with fgets but it is unsafe (because you will need to estimate the length of the line a priori), otherwise use fgetc:
char c;
do {
c = fgetc(in);
} while (c != '\n');
Finally you should have format specifiers inside your fscanf to actually parse data, like
fscanf(in, "%f", floatVariable);
you can refer here for specifiers.
fgets would work here.
#define MAX_LINE_LENGTH 80
char buf[MAX_LINE_LENGTH];
/* skip the first line (pFile is the pointer to your file handle): */
fgets(buf, MAX_LINE_LENGTH, pFile);
/* now you can read the rest of your formatted lines */

Resources