How to read file line by line c
How to read file line by line c
Read file line by line using ifstream in C++
The contents of file.txt are:
Where 5 3 is a coordinate pair. How do I process this data line by line in C++?
I am able to get the first line, but how do I get the next line of the file?
8 Answers 8
Trending sort
Trending sort is based off of the default sorting method — by highest score — but it boosts votes that have happened recently, helping to surface more up-to-date answers.
It falls back to sorting by highest score if no posts are trending.
Switch to Trending sort
First, make an ifstream :
The two standard methods are:
Assume that every line consists of two numbers and read token by token:
Line-based parsing, using string streams:
You shouldn’t mix (1) and (2), since the token-based parsing doesn’t gobble up newlines, so you may end up with spurious empty lines if you use getline() after token-based extraction got you to the end of a line already.
Use ifstream to read data from a file:
If you really need to read line by line, then do this:
But you probably just need to extract coordinate pairs:
Update:
Reading a file line by line in C++ can be done in some different ways.
[Fast] Loop with std::getline()
The simplest approach is to open an std::ifstream and loop using std::getline() calls. The code is clean and easy to understand.
[Fast] Use Boost’s file_description_source
Another possibility is to use the Boost library, but the code gets a bit more verbose. The performance is quite similar to the code above (Loop with std::getline()).
[Fastest] Use C code
If performance is critical for your software, you may consider using the C language. This code can be 4-5 times faster than the C++ versions above, see benchmark below
The results show the time (in ms) that each piece of code took to read the files.
The performance difference between the two C++ approaches is minimal and shouldn’t make any difference in practice. The performance of the C code is what makes the benchmark impressive and can be a game changer in terms of speed.
Solarian Programmer
My programming ramblings
Posted on April 3, 2019 by Paul
In this article, I will show you how to read a text file line by line in C using the standard C function fgets and the POSIX getline function. At the end of the article, I will write a portable implementation of the getline function that can be used with any standard C compiler.
Reading a file line by line is a trivial problem in many programming languages, but not in C. The standard way of reading a line of text in C is to use the fgets function, which is fine if you know in advance how long a line of text could be.
You can find all the code examples and the input file at the GitHub repo for this article.
Let’s start with a simple example of using fgets to read chunks from a text file. :
For testing the code I’ve used a simple dummy file, lorem.txt. This is a piece from the output of the above program on my machine:
The code prints the content of the chunk array, as filled after every call to fgets, and a marker string.
If you watch carefully, by scrolling the above text snippet to the right, you can see that the output was truncated to 127 characters per line of text. This was expected because our code can store an entire line from the original text file only if the line can fit inside our chunk array.
Let’s start by creating a line buffer that will store the chunks of text, initially this will have the same length as the chunk array:
Next, we are going to append the content of the chunk array to the end of the line string, until we find the end of line character. If necessary, we’ll resize the line buffer:
Please note, that in the above code, every time the line buffer needs to be resized its capacity is doubled.
This is the result of running the above code on my machine. For brevity, I kept only the first lines of output:
You can see that, this time, we can print full lines of text and not fixed length chunks like in the initial approach.
Let’s modify the above code in order to print the line length instead of the actual text:
This is the result of running the modified code on my machine:
In the next example, I will show you how to use the getline function available on POSIX systems like Linux, Unix and macOS. Microsoft Visual Studio doesn’t have an equivalent function, so you won’t be able to easily test this example on a Windows system. However, you should be able to test it if you are using Cygwin or Windows Subsystem for Linux.
Please note, how simple is to use POSIX’s getline versus manually buffering chunks of line like in my previous example. It is unfortunate that the standard C library doesn’t include an equivalent function.
When you use getline, don’t forget to free the line buffer when you don’t need it anymore. Also, calling getline more than once will overwrite the line buffer, make a copy of the line content if you need to keep it for further processing.
This is the result of running the above getline example on a Linux machine:
It is interesting to note, that for this particular case the getline function on Linux resizes the line buffer to a max of 960 bytes. If you run the same code on macOS the line buffer is resized to 1024 bytes. This is due to the different ways in which getline is implemented on different Unix like systems.
As mentioned before, getline is not present in the C standard library. It could be an interesting exercise to implement a portable version of this function. The idea here is not to implement the most performant version of getline, but rather to implement a simple replacement for non POSIX systems.
We are going to take the above example and replace the POSIX’s getline version with our own implementation, say my_getline. Obviously, if you are on a POSIX system, you should use the version provided by the operating system, which was tested by countless users and tuned for optimal performance.
The POSIX getline function has this signature:
Since ssize_t is also a POSIX defined type, usually a 64 bits signed integer, this is how we are going to declare our version:
In principle we are going to implement the function using the same approach as in one of the above examples, where I’ve defined a line buffer and kept copying chunks of text in the buffer until we found the end of line character:
This is how we can use the above function, for simplicity I kept the code and the function definition in the same file:
The above code gives the same results as the code that uses the POSIX’s getline function:
I’ve also tested the code with the Microsoft C compiler and gives identical results for the same input file.
If you want to learn more about C99/C11 I would recommend reading 21st Century C: C Tips from the New School by Ben Klemens:
C read file line by line
I wrote this function to read a line from a file:
The function reads the file correctly, and using printf I see that the constLine string did get read correctly as well.
However, if I use the function e.g. like this:
printf outputs gibberish. Why?
17 Answers 17
Trending sort
Trending sort is based off of the default sorting method — by highest score — but it boosts votes that have happened recently, helping to surface more up-to-date answers.
It falls back to sorting by highest score if no posts are trending.
Switch to Trending sort
If your task is not to invent the line-by-line reading function, but just to read the file line-by-line, you may use a typical code snippet involving the getline() function (see the manual page here):
In your readLine function, you return a pointer to the line array (Strictly speaking, a pointer to its first character, but the difference is irrelevant here). Since it’s an automatic variable (i.e., it’s “on the stack”), the memory is reclaimed when the function returns. You see gibberish because printf has put its own stuff on the stack.
You need to return a dynamically allocated buffer from the function. You already have one, it’s lineBuffer ; all you have to do is truncate it to the desired length.
ADDED (response to follow-up question in comment): readLine returns a pointer to the characters that make up the line. This pointer is what you need to work with the contents of the line. It’s also what you must pass to free when you’ve finished using the memory taken by these characters. Here’s how you might use the readLine function:
A complete, fgets() solution:
Remember, if you want to read from Standard Input (rather than a file as in this case), then all you have to do is pass stdin as the third parameter of fgets() method, like this:
readLine() returns pointer to local variable, which causes undefined behaviour.
To get around you can:
Use fgets() to read a line from a file handle.
Some things wrong with the example:
There is a potential buffer overflow at the line
If the line is exactly 128 characters long, count is 128 at the point that gets executed.
As others have pointed out, line is a locally declared array. You can’t return a pointer to it.
Here is my several hours. Reading whole file line by line.
note that the ‘line’ variable is declared in calling function and then passed, so your readLine function fills predefined buffer and just returns it. This is the way most of C libraries work.
There are other ways, which I’m aware of:
btw, ‘explicit’ casting from char* to const char* is redundant.
btw3 do not use ‘dynamic sized stack arrays’ (defining the array as char arrayName[some_nonconstant_variable] ), if you don’t exactly know what are you doing, it works only in C99.
Going through a text file line by line in C
I have been working on a small exercise for my CIS class and am very confused by the methods C uses to read from a file. All that I really need to do is read through a file line by line and use the information gathered from each line to do a few manipulations. I tried using the getline method and others with no luck. My code is currently as follows:
Right now I am getting a seg fault with the sscanf method and I am not sure why. I am a total C noob and just wondering if there was some big picture thing that I was missing. Thanks
4 Answers 4
Trending sort
Trending sort is based off of the default sorting method — by highest score — but it boosts votes that have happened recently, helping to surface more up-to-date answers.
It falls back to sorting by highest score if no posts are trending.
Switch to Trending sort
So many problems in so few lines. I probably forget some:
In addition to the other answers, on a recent C library (Posix 2008 compliant), you could use getline. See this answer (to a related question).
Say you’re dealing with some other delimiter, such as a \t tab, instead of a \n newline.
Use of an array avoids the need to use malloc and free to create a character pointer of the right length on the heap.
How to read a file line-by-line in C?
I have a text file with up to 100 IP addresses, 1 per line. I need to read each address, as a string, into an array called «list». First, I’m assuming that «list» will need to be a two-dimensional char array. Each IP address is 11 characters in length, 12 if you include ‘\0’, so I declared list as follows:
Next, I attempt to use fgets to read the stream:
To check to see if the strings were read properly, I attempt to output them:
After running the program, it’s clear something is wrong. Being a beginner, I’m not sure what, but I’m guessing I’m reading the file wrong. There are no errors. It compiles, but prints a strange address on two lines.
Edit:
I replaced the fgets code with this:
It now prints five strings, but they are «random» characters from memory.
7 Answers 7
Trending sort
Trending sort is based off of the default sorting method — by highest score — but it boosts votes that have happened recently, helping to surface more up-to-date answers.
It falls back to sorting by highest score if no posts are trending.
Switch to Trending sort
You have a big problem right here. This is attempting to read a string into each successive character in your array.
All in all, I think you’re making this a lot more complex than it needs to be. Think of your array as 100 strings, and fgets will work with a string at a time. That means reading can look something like this:
There is one other minor detail to deal with: fgets() normally retains the new-line at the end of each line. As such, you may need to leave room for 13 characters (11 for address, 1 for new-line, 1 for NUL terminator), or else you may want to read the data into a temporary buffer, and copy it to your list only after you’ve stripped off the new-line.
In your current code for printing the strings, you’re working one character at a time, which can work, but is unnecessarily difficult. Several people have suggested using the %s printf conversion, which is fine in itself. To go with it, however, you have to simplify your indexing a bit. Printing the first six addresses would look something like this:
Your call to fgets reads up to 11 characters from the stream into the array. So you don’t want to be calling that once for each character of each string.
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.
You may be reading the first 12 characters in the first call the fgets, then the second call will catch the newline, then the third call gets the next line.
Try using fgets with a 15 character limit, and expanding your buffer.
The second loop is not necessary and it corrupts your memory. You should do something like this,
Do not use feof() as your loop condition; it will not return true until after you’ve tried to read past the end of the file, meaning your loop will execute one time too many. Check the result of your input call (whether you use fgets() or fscanf() ) to see if it succeeded, then check feof() if you got an error condition.
fgets() reads entire strings, not individual characters, so you don’t want to pass the address of each individual character in your string. Call it like so instead:
And now, for Bode’s usual spiel about arrays and pointers.
When an array expression appears in most contexts, the type of the expression is implicitly converted from «N-element array of T» to «pointer to T», and the value of the expression is the address of the first element of the array. The exceptions to this rule are when the array expression is the operand of the sizeof or & operators, or it is a string literal that is being used as an initializer in a declaration. When you hear people say «arrays and pointers are the same thing», they’re garbling that rule. Arrays and pointers are completely different animals, but they can be used interchangeably in some contexts.
Just to nail it down:
then the contents of your input buffer after the read will be «1.1.1.1\n\0xxx» where x is some random value. If you don’t want the newline there, you can use the strchr() function to find it and then overwrite it with a 0:
Since fgets() stops at the next newline, and since your input buffer is sized for 12 characters, it’s possible for you to run into a situation where you have a newline as the next input character in the file; in that case, fgets() will write only that newline to the input buffer, so you’ll have some empty entries, which is probably not what you want. You might want to add an extra byte to your input buffer in order to avoid that situation.
Источники информации:
- http://solarianprogrammer.com/2019/04/03/c-programming-read-file-lines-fgets-getline-implement-portable-getline/
- http://stackoverflow.com/questions/3501338/c-read-file-line-by-line
- http://stackoverflow.com/questions/9206091/going-through-a-text-file-line-by-line-in-c
- http://stackoverflow.com/questions/1842393/how-to-read-a-file-line-by-line-in-c