I need to create an utility that "updates" its output, much like curl which keeps changing its last line:
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 8434 100 8434 0 0 4064 0 0:00:02 0:00:02 --:--:-- 7695
I think using something like curses is not the way to go here. I don't want to manipulate the window, I want to simply change my last line of output.
The solution I have in mind is to print a number of backspaces enough to rewrite the line. But I haven't tested this yet. I'd like to know if this is a "correct" way of doing it, or if there is a better one.
Also, in my case I need to update the last line. So I don't need a so large number of backspaces (if that's the solution); however (to make it generic) if I need to update the -10 line, rewriting the same thing from -9th line on might not be that efficient (or maybe it is...).
You can backspace over the line, or (generally easier) print a carriage return, and just re-print the entire line. When you do, be sure to rewrite the whole line though -- if (for example) you have a number counting down to 0, when it drops from 100 to 99 (for example) it won't necessarily overwrite the '1' unless you assure that a space gets printed there.
In DOS, you can simply print the carriage return without the line feed and overwrite the last line.
Related
I have test.csv (300 lines) file as below
10 20 100 2 5 4 5 7 9 10 ....
55 600 7000 500 25
3 10
2 5 6
....
Each line has different number of integers (maximum number of records =1000) and I need to proceed these records line by line. I tried as below
integer,dimension(1000)::rec
integer::i,j
open(unit=5,file="test.csv",status="old",action="read")
do i=1,300
read(unit=5,fmt=*) (rec(j),j=1,1000)
!do some procedue with rec
enddo
close(unit=50)
but it seems like that rec array is not constructed by line by line. It means that when i=n, rec get the numbers from non-nth line. How can I solve this problem.
thank you
List directed formatting (as specified by the star in the read statement) reads what it needs to satisfy the list (hence it is "list directed"). As shown, your code will try and read 1000 values each iteration, consuming as many records (lines) as required each iteration in order to do that.
(List directed formatting has a number of surprising features beyond that, which may have made sense with card based input forms 40 years ago, but are probably misplaced today. Before using list directed input you should understand exactly what the rules around it say.)
A realistic and robust approach to this sort of situation is to read in the input line by line, then "manually" process each line, tokenising that line and extracting values as per whatever rules you are following.
(You should get in touch with whoever is naming files that have absolutely no commas or semicolons with an extension ".csv", and have a bit of a chat.)
(As a general rule, low value unit numbers are to be avoided. Due to historical reasons they may have been preconnected for other purposes. Reconnecting them to a different file is guaranteed to work for that specific purpose, but other statements in your program may implicitly be assuming that the low value unit is still connected as it was before the program started executing - for example, PRINT and READ statements intended to work with the console might start operating on your file instead.)
Please refer to the following code snippet, I will be referring to the line numbers on it:
https://gist.github.com/wilbertcr/474c6a13e377dc8ce51a
As you can see on line 172-200, I created a modified version of the original back_over function, which just moves the pointer without erasing the character that's moving over.
Outside of the function in_process, and as a global variable, I created int verase, see line 1, which I use on line 82 to indicate CTRL+H has been pressed(ch == tp->tty_termios.c_cc[VERASED]).
My idea is to use this as a flag so I can catch the next character, which should be the number of spaces I need to back_over, and do that by calling back_over the number of times indicated by that next character.
The problem I am having is that I don't know how to turn that next character into its corresponding int so that I can use it on the for loop. Lines 27-38 show a failed attempt to do that, however, no matter how small the key I press(I've tried 1 and 2 and 3), it always takes me to the beginning of the line(luckily back_over doesn't go beyond a line break--see line 185).
It seems like the for loop is being executed more than the it should, which I suspect is happening because "number" is not really 1 or 2 or 3 but something else, something the for loop is interpreting as much bigger than the number I am pressing in the keyboard. I would appreciate some help on how can I turn it into an int.
It turned out it was just a matter of doing:
ch=ch-'0'
I'm writing a business application in C in which I'm keeping track of a timer by writing the value to a temporary file. The counter starts at 96, and counts backwards all the way to 0. The logic works fine, except when it switches over from 10 to 9, the 9 only overwrites the 1, so instead of 10 -> 9, the value goes 10 -> 90, causing the countdown to start back from this point. Is there a way I can have my application write the value successfully?
I'm using the following two functions to control output to the file"
fprintf(fileFd, "%d" , counter);
rewind(fileFd);
I print the value to my file, then move the access point back to the head of the file for the next entry. Any advice on how this can be done? Thanks, all.
EDIT: Thank you all for the suggestions. I tried the methods suggested below, by calling %02d to write to two place values, and for some reason that completely broke the application. The loops won't happen at all.....then when I recompile, it still won't work until I delete my temp file and create a new one. Now, when writing to the file, it tells me at the bottom (this is a UNIX system) the filename, [Incomplete last line], 1 line 2 characters. Would this make any kind of difference to specifying the number of places to write to?
fprintf(fileFd, "%02d", counter);
Check with:
fprintf(fileFd, "%02d" , counter);
write to the file taking up certain number of digits, and fill unused digit with 0.
fprintf(fileFd, "%07d", counter);
The above code will allow time values upto 7 digits.
In C, I want to scan only some lines from input to save runtime of my program. For eg:
Say my input file contains some random numbers like:
5 1
1 2
1 7
5 6
3 4
1 6
2 5 3
1 5 4
3 1 1
Here I want to skip all the numbers that are in doubles and start from those that are in triples i.e.
2 5 3
1 5 4
3 1 1
Can I redirect the scanf() such that it starts scanning from somewhere in the middle?
You can use the fseek function to jump the file cursor to an arbitrary offset in the file, provided that you know the number of bytes that you need to skip.
If you don't know in advance how many characters you need to skip over, your best option would be to continuously read lines from the file and skip over those that don't match your criteria. In your case, you could skip all lines that just have one space character in them, and could resume reading once you find a line that has two spaces in it.
Hope this helps!
You can read and ignore data until you reach what you want. For example, read a line with fgets, then use sscanf to try to convert that line to three numbers. If the return from sscanf isn't 3, it couldn't convert three numbers, so continue to the next line. When sscanf does return 3, then you can save the results in an array (or whatever).
To truly skip to a later point in the file, you'd need to know the offset to skip to, and feed that to fseek. That seems unlikely to apply here though.
If your file is large and you know (for sure) that it consists solely of 2-number lines followed by 3-number lines, you could do something like a binary search to find the first 3-number line. You'd start by finding the file length, then seek (about) halfway into the file. Read and ignore one line (because you probably didn't seek to the beginning of a line). Then read the next line and try to convert it as above. If it has three numbers, then you're past the point that the three-number lines started, so try again about halfway back to the beginning (and if it's only a 2-number line, halfway further to the end).
You probably don't want to keep this up too long -- when you're within a few kilobytes (or so) of the beginning of the three-number lines, it's probably faster to just read sequentially until you find the beginning instead of doing a lot more seeking to find exactly the right point.
I have a 100GB file, and need to remove the last two lines of it.
I do not want to read from it since it will take about an hour to get to the bottom of it so sed does not seem to be an option.
My disk is also too small to be able to copy that file.
What are my options here ?
Thanks.
I'm pretty sure in .Net you can open a FileStream to a file, then move the pointer to a specific byte (which you could calculate), and modify it from there. However, I'm not sure if it has to pass the whole stream when you try to save it, so this might be more useful if you needed to copy just the last 2 lines.
In C/POSIX, you should be able to use fseek with the SEEK_END option to back up a little bit from the end of the file (say 512 bytes), then read those 512 bytes into memory.
From that, you can figure out exactly where the second last line starts and then use truncate or ftruncate to actually truncate the file at that point.
If the last two lines are more than 512 bytes (ie, the start of the second last line doesn't show up in the chunk you read), just increase the value to 1024 and try again. Keep going until you find it.