<cffile action="read" file="#ExpandPath( './text.txt' )#" variable="pag">
How to display a random line from a file on the screen?
This txt file contains lines 10k.
Thank
Treat the file as a chr(10) delimited list. Use listToArray to convert it to an array. Use arrayLen to get the number of lines and randRange to get a random number. Then output the line.
You could do something like this:
<cfscript>
pag = FileOpen(ExpandPath( './text.txt' ), "read");
counter = 0;
randomLine = randRange(1, 10000);
while(NOT FileisEOF(myfile)) {
counter++;
if (counter==randomLine) {
x = FileReadLine(pag); // read line
WriteOutput("#x#");
break;
}
}
FileClose(pag);
</cfscript>
It's not very efficient to do it that way, and also it relies on you knowing the number of lines in the file. If you need to do it multiple times, then it would be much better to read the file once and store each line in a database or persistent storage scope. You could then quite easily grab any record from it. For example:
<cfscript>
// read the file once
pag = FileOpen(ExpandPath( './text.txt' ), "read");
lines = [];
while(NOT FileisEOF(myfile)) {
arrayAppend(lines, FileReadLine(pag)); // read line
}
FileClose(pag);
// store the `lines` in a persistent scope or db etc
// here I'm using application scope as a simple example
application.filelines = lines;
</cfscript>
Then you can grab a random line without re-reading the file
<cfscript>
totalLines = arrayLen(application.filelines);
randomLine = randRange(1, totalLines);
writeOutput(application.filelines[randomLine]);
</cfscript>
Related
I need to write an 8 ball code that has eleven options to display and it needs to pull from a text file. I have it taking lines from the text file but sometimes it takes an empty line with no writing. And I need it to only take a line that has writing.
Here are that options it needs to draw from:
Yes, of course!
Without a doubt, yes.
You can count on it.
For sure!Ask me later.
I'm not sure.
I can't tell you right now.
I'll tell you after my nap.
No way!I don't think so.
Without a doubt, no.
The answer is clearly NO.
string line;
int random = 0;
int numOfLines = 0;
ifstream File("file.txt");
srand(time(0));
random = rand() % 50;
while (getline(File, line))
{
++numOfLines;
if (numOfLines == random)
{
cout << line;
}
}
}
IMHO, you need to either make the text lines all the same length, or use a database (table) of file positions.
Using File Positions
Minimally, create a std::vector<pos_type>.
Next read the lines from the file, recording the file position of the beginning of the string:
std::vector<std::pos_type> text_line_positions;
std::string text;
std::pos_type file_position = 0;
while (std::getline(text_file, text)
{
text_line_positions.push_back(file_position);
// Read the start position of the next line.
file_position = text_file.tellg();
}
To read a line from a file, get the file position from the database, then seek to it.
std::string text_line;
std::pos_type file_position = text_line_positions[5];
text_file.seekg(file_position);
std::getline(text_file, text_line);
The expression, text_line_positions.size() will return the number of text lines in the file.
If File Fits In Memory
If the file fits in memory, you could use std::vector<string>:
std::string text_line;
std::vector<string> database;
while (getline(text_file, text_line))
{
database.push_back(text_line);
}
To print the 10 line from the file:
std::cout << "Line 10 from file: " << database[9] << std::endl;
The above techniques minimize the amount of reading from the file.
I have a text file which had 1000 lines, and I want to copy a part of every line and past it at the end of the same line after adding a semicolon, but that must be done for 1000 lines.
I have imported the text file to excel so I can do it, but I did not get any hint to do it at one go.
here is for example how look likes the first line:
{"loginId":"gcdmtest_bp_pr_acc_po_20000#trash-mail.com","password":"test1234"};dc9b88ce-f26e-43fa-a2c1-6b67cc628404
I want to add a semicolon at the end of the line, and then copy the email pattern at the end of the same line like:
;gcdmtest_bp_pr_acc_po_20000#trash-mail.com
I'm just giving you a general guide to do this.
Read the text file (using C#, Java, whatever you are comfortable with)
Use a for loop to go through each line, extract the email portion, then add to the end of the line.
Save the new text file.
Thanks guys I found the solution on this code:
File mFile = new File(newfile);
FileInputStream fis = new FileInputStream(mFile);
BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(mFile))) ;
String result = "";
String line = "";
while( (line = br.readLine()) != null){
String emailpattern = line.substring(12, 54);
result += line + ";"+emailpattern + System.getProperty("line.separator");
}
result = result;
mFile.delete();
FileOutputStream fos = new FileOutputStream(mFile);
fos.write(result.getBytes());
fos.flush();
I need to remove duplicates if
key = anything
but NOT
key=anything
the key can be anything too
e.g.
edit_home=home must be in place
while
edit_home = home or even other string must be removed IF edit_home is a duplicate
for all the lines of the document
thank you
p.s. clearer example:
one=you are
two=we are
three_why=8908908
one = good
two = fine
three_4 = best
three_why = win
from that list i only need to keep:
one=you are
two=we are
three_why=8908908
three_4 = best // because three_4 doesn't have a duplicate
I found a method to do it, but I would need a better search list support by regex or a plugin or a direct regex (which I don't know).
That is: I have two files to compare.
One has the full keys, the other has incomplete.
I merge in a new file all the keys from the first file with those ones of the second, in groups (because the keys are in groups e.g. many keys titled one, many titled two and so on...). Then I regex replace all the keys in the new file by
find (.*)(\s\=\s) replace with \1\=
So they all become key=anything
Then I replace everything after = with empty to isolate the keys.
Then remove the duplicates.
At this point I have trouble to do something like
^.*(^keyone\b|^keytwo\b|^keythree\b).*$
to find all those keys in the document I need. So from that I can select all and replace with the correct keys.
Why? Because in this example the keys are 3 only BUT indeed the keys are many and the find field breaks at a certain point.
How to do it right?
Update: I found Toolbucket plugin which allows to search for many strings, but another issue is that in addition to duplicate, I also have to remove the original.
That is, if I find 2 times the same key "one" I have to remove all the lines containing one.
Ctrl + F
Find tab
Find what: ^.*\S=\S.*$
Find All in Current Document
Copy result from result window to a new window (the list of Line 1: Line 2: Line 3: ...)
Ctrl + F
Replace tab
(the following will remove the leading "Line number:" from every line)
Find what: ^.*?\d:\s
Replace with: Empty
ok, after all that i wrote, one solution could be (therefore, once i have the merged keys)
(?m)^(.*)$(?=\r?\n^(?!\1).*(?s).*?\1)
with this i can mark/highlight all the duplicated keys :-) so then i can manage those only, removing them from the first list and adding what remains to the second file...
If someone has a solution with a direct regex will be really appreciated
Here is a commented UltraEdit script for this task.
// Note: This script does not work for large files as it loads the
// entire file content into very limited scripting memory for fast
// processing even with multiple GB of RAM installed.
if (UltraEdit.document.length > 0) // Is any file opened?
{
// Define environment for this script and select entire file content.
UltraEdit.insertMode();
UltraEdit.columnModeOff();
UltraEdit.activeDocument.selectAll();
// Determine line termination used currently in active file.
var sLineTerm = "\r\n";
if (typeof(UltraEdit.activeDocument.lineTerminator) == "number")
{
// The two lines below require UE v16.00 or UES v10.00 or later.
if (UltraEdit.activeDocument.lineTerminator == 1) sLineTerm = "\n";
else if (UltraEdit.activeDocument.lineTerminator == 2) sLineTerm = "\r";
}
else // This version of UE/UES does not offer line terminator property.
{
if (UltraEdit.activeDocument.selection.indexOf(sLineTerm) < 0)
{
sLineTerm = "\n"; // Not DOS, perhaps UNIX.
if (UltraEdit.activeDocument.selection.indexOf(sLineTerm) < 0)
{
sLineTerm = "\r"; // Also not UNIX, perhaps MAC.
if (UltraEdit.activeDocument.selection.indexOf(sLineTerm) < 0)
{
sLineTerm = "\r\n"; // No line terminator, use DOS.
}
}
}
}
// Get all lines of active file into an array of strings
// with each string being one line from active file.
var asLines = UltraEdit.activeDocument.selection.split(sLineTerm);
var nTotalLines = asLines.length;
// Process each line in the array.
for(var nCurrentLine = 0; nCurrentLine < asLines.length; nCurrentLine++)
{
// Skip all lines not containing or starting with an equal sign.
if (asLines[nCurrentLine].indexOf('=') < 1) continue;
// Get string left to equal sign with tabs/spaces trimmed.
var sKey = asLines[nCurrentLine].replace(/^[\t ]*([^\t =]+).*$/,"$1");
// Skip lines beginning with just tabs/spaces left to equal sign.
if (sKey.length == asLines[nCurrentLine].length) continue;
var_dump(sKey);
// Build the regular expression for the search in all other lines.
var rRegSearch = new RegExp("^[\\t ]*"+sKey+"[\\t ]*=","g");
// Ceck all remaining lines for a line also starting with
// this key string case-sensitive with left to an equal sign.
var nLineCompare = nCurrentLine + 1;
while(nLineCompare < asLines.length)
{
// Does this line also has this key left to equal
// sign with or without surrounding spaces/tabs?
if (asLines[nLineCompare].search(rRegSearch) < 0)
{
nLineCompare++; // No, continue on next line.
}
else // Yes, remove this line from array.
{
asLines.splice(nLineCompare,1);
}
}
}
// Was any line removed from the array?
if (nTotalLines == asLines.length)
{
UltraEdit.activeDocument.top(); // Cancel the selection.
UltraEdit.messageBox("Nothing found to remove!");
}
else
{
// If version of UE/UES supports direct write to clipboard, use
// user clipboard 9 to paste the lines into file with overwritting
// everything as this is much faster than using write command in
// older versions of UE/UES.
if (typeof(UltraEdit.clipboardContent) == "string")
{
var nActiveClipboard = UltraEdit.clipboardIdx;
UltraEdit.selectClipboard(9);
UltraEdit.clipboardContent = asLines.join(sLineTerm);
UltraEdit.activeDocument.paste();
UltraEdit.clearClipboard();
UltraEdit.selectClipboard(nActiveClipboard);
}
else UltraEdit.activeDocument.write(asLines.join(sLineTerm));
var nRemoved = nTotalLines - asLines.length;
UltraEdit.activeDocument.top();
UltraEdit.messageBox("Removed " + nRemoved + " line" + ((nRemoved != 1) ? "s" : "") + " on updated file.");
}
}
Copy this code and paste it into a new ASCII file using DOS line terminators in UltraEdit.
Next use command File - Save As to save the script file for example with name RemoveDuplicateKeys.js into %AppData%\IDMComp\UltraEdit\MyScripts or wherever you want to have saved your UltraEdit scripts.
Open Scripting - Scripts and add the just saved UltraEdit script to the list of scripts. You can enter a description for this script, too.
Open the file with the list, or make this file active if it is already opened in UltraEdit.
Run the script by clicking on it in menu Scripting, or by opening Views - Views/Lists - Script List and double clicking on the script.
Let's say I write some information in a file, and it writes with n cycles, for example as follows:
a,a,a,a,
b,b,b,b,
c,c,c,c,
a,a,a,a,
b,b,b,b,
c,c,c,c,
.......
a,a,a,a,
b,b,b,b,
c,c,c,c,
Now I want to open the file check the first line, find where it repeats and delete everything after that. For my example case let's say I want to wind where a,a,a,a, meets again, and to delete it, and everything after that, getting the follows instead:
a,a,a,a,
b,b,b,b,
c,c,c,c,
Q: How can I do that?
You can use QTextStream to stream your file (so, do not care about RAM).
Then use readLine() function to read one line at a time to QString, and compare with new line.
Here some code sample:
int lineCounter = 0; //count for line
QFile f(filePath);
if (!f.open(QIODevice::ReadOnly | QIODevice::Text))
return false;
QTextStream stream(&f);
QString line;
// read the first line
line = stream.readLine();
lineCounter++;
QString hash = QString(QCryptographicHash::hash(line.toAscii(), QCryptographicHash::Md5).toHex());
do
{
line = stream.readLine();
if (QString(QCryptographicHash::hash(line.toAscii(), QCryptographicHash::Md5).toHex()).compare(hash) == 0)
{
// Save data from 1st line to "lineCounter" to new file, or do your own works;
// and then break;
}
lineCounter++;
} while (!line.isNull());
You want to remove duplicate lines in a file. If you follow the next steps you will get what you want.
Create a vector that will store the hashes of unique lines ( QVector<QString>) Notice that using QMap would be faster.
Create an ouput file
For every line in the file calculate it's hash. Use QCryptographicHash or qHash (in this case you should have a vector of uints.
If the calculated hash is contained in the vector skip this line
Otherwise add the hash to the vector and print the line to the output file.
At the end the output file should contain only unique instances of the input file.
I'm trying to read the whole contain of the txt file, not line by line, but the whole contain
and print it on screen inside a textfield in xcode
i'm using a mix of obj-c and c++ lang:
while(fgets(buff, sizeof(buff), in)!=NULL){
cout << buff; // this print the whole output in the console
NSString * string = [ NSString stringWithUTF8String:buff ] ;
[Data setStringValue:string]; // but this line only print last line inside the textfield instead of printing it all
}
I'm trying to print the whole contain of the file like:
something...
something...
etc...
but instead it just printing the last line to the textfield, please help me
Is there a reason you aren't using Obj-C to read the file? It would be as simple as:
NSData *d = [NSData dataWithContentsOfFile:filename];
NSString *s = [[[NSString alloc] initWithData:d encoding:NSUTF8StringEncoding] autorelease];
[Data setStringValue:s];
Edit: To use the code you have now I would try something like this:
while(fgets(buff, sizeof(buff), in)!=NULL){
NSMutableString *s = [[Data stringValue] mutableCopy];
[s appendString:[NSString stringWithUTF8String:buff]];
[Data setStringValue:s];
}
Read a file, return the content as a C++ string:
// open the file
std::ifstream is;
is.open(fn.c_str(), std::ios::binary);
// put the content in a C++ string
std::string str((std::istreambuf_iterator<char>(is)),
std::istreambuf_iterator<char>());
In your code you are using the C api (FILE* from cstdio). In C, the code is more complex:
char * buffer = 0; // to be filled with the entire content of the file
long length;
FILE * f = fopen (filename, "rb");
if (f) // if the file was correctly opened
{
fseek (f, 0, SEEK_END); // seek to the end
length = ftell (f); // get the length of the file
fseek (f, 0, SEEK_SET); // seek back to the beginning
buffer = malloc (length); // allocate a buffer of the correct size
if (buffer) // if allocation succeed
{
fread (buffer, 1, length, f); // read 'length' octets
}
fclose (f); // close the file
}
To answer the question of why your solution didn't work:
[Data setStringValue:string]; // but this line only print last line inside the textfield instead of printing it all
Assuming that Data refers to a text field, setStringValue: replaces the entire contents of the field with the string you passed in. Your loop reads and sets one line at a time, so at any given time, string is one line from the file.
Views only get told to display when you're not doing anything else on the main thread, so your loop—assuming that you didn't run it on another thread or queue—does not print one line at a time. You read each line and replace the text field's contents with that line, so when your loop finishes, the field is left with the last thing you set its stringValue to—the last line from the file.
Slurping the entire file at once will work, but a couple of problems remain:
Text fields aren't meant for displaying multiple lines. No matter how you read the file, you're still putting its contents in a place that isn't designed for such contents.
If the file is large enough, reading it will take a significant amount of time. If you do this on the main thread, then, during that time, the app will be hung.
A proper solution would be:
Use a text view, not a text field. Text views are built to work with text of any number of lines, and when you create one in a nib, it comes wrapped in a scroll view for free.
Read the file one line or other limited-size chunk at a time, but not in a for or while loop. Use NSFileHandle or dispatch_source, either of which will call a block you provide whenever they read another chunk of the file.
Append each chunk to the text view's storage instead of replacing the entire text with it.
Show a progress indicator when you start reading, then hide it when you finish reading. For extra credit, make it a determinate progress bar, showing the user how far you've gotten through the file.