[英]Trouble getting string to print random line from text file
I picked up this bit of code a while back as a way to select a random line from a text file and output the result. 我暂时拿起这段代码作为从文本文件中选择随机行并输出结果的方法。 Unfortunately, it only seems to output the first letter of the line that it selects and I can't figure out why its doing so or how to fix it.
不幸的是,它似乎只输出它选择的行的第一个字母,我无法弄清楚它为什么这样做或如何解决它。 Any help would be appreciated.
任何帮助,将不胜感激。
#include "stdafx.h"
#include <stdio.h>
#include <iostream>
#include <fstream>
#include <string>
#include <time.h>
using namespace std;
#define MAX_STRING_SIZE 1000
string firstName()
{
string firstName;
char str[MAX_STRING_SIZE], pick[MAX_STRING_SIZE];
FILE *fp;
int readCount = 0;
fp = fopen("firstnames.txt", "r");
if (fp)
{
if (fgets(pick, MAX_STRING_SIZE, fp) != NULL)
{
readCount = 1;
while (fgets (str, MAX_STRING_SIZE, fp) != NULL)
{
if ((rand() % ++readCount) == 0)
{
strcpy(pick, str);
}
}
}
}
fclose(fp);
firstName = *pick;
return firstName;
}
int main()
{
srand(time(NULL));
int n = 1;
while (n < 10)
{
string fn = firstName();
cout << fn << endl;
++n;
}
system("pause");
}
firstName = *pick;
I am guessing this is the problem. 我猜这是问题所在。
pick
here is essentially a pointer to the first element of the array, char*
, so of course *pick
is of type char
.. or the first character of the array. 这里
pick
本质上是指向数组的第一个元素char*
的指针,所以当然*pick
是char
类型的,或者是数组的第一个字符。
Another way to see it is that *pick == *(pick +0) == pick[0]
另一种看待它的方法是
*pick == *(pick +0) == pick[0]
There are several ways to fix it. 有几种方法可以解决它。 Simplest is to just do the below.
最简单的是只做下面的事情。
return pick;
The constructor will automatically make the conversion for you. 构造函数将自动为您进行转换。
Since you didn't specify the format of your file, I'll cover both cases: fixed record length and variable record length; 由于您没有指定文件的格式,我将涵盖两种情况:固定记录长度和可变记录长度; assuming each text line is a record.
假设每个文本行都是记录。
This one is straight forward. 这个是直截了当的。
std::getline
. std::getline
从文件中读取文本。 This assumes that the length of the text lines vary. 这假设文本行的长度不同。 Since they vary, you can't use math to determine the file position.
由于它们不同,因此无法使用数学来确定文件位置。
To randomly pick a line from a file you will either have to put each line into a container, or put the file offset of the beginning of the line into a container. 要从文件中随机选取一行,您必须将每行放入容器中,或者将行开头的文件偏移量放入容器中。
After you have your container establish, determine the random name number and use that as an index into the container. 在您的容器建立后,确定随机名称编号并将其用作容器的索引。 If you stored the file offsets, position the file to the offset and read the line.
如果存储了文件偏移量,请将文件定位到偏移量并读取该行。 Otherwise, pull the text from the container.
否则,从容器中提取文本。
Which container should be used? 应该使用哪个容器? It depends.
这取决于。 Storing the text is faster but takes up memory (you are essentially storing the file into memory).
存储文本更快但占用内存(您实际上是将文件存储到内存中)。 Storing the file positions takes up less room but you will end up reading each line twice (once to find the position, second to fetch the data).
存储文件位置占用的空间较少,但最终会读取每一行两次(一次找到位置,第二次读取数据)。
Augmentations to these algorithms is to memory-map the file, which is an exercise for the reader. 对这些算法的增加是对文件进行内存映射,这是读者的练习。
include <iostream>
#include <fstream>
#include <vector>
#include <string>
using std::string;
using std::vector;
using std::fstream;
// Create a container for the file positions.
std::vector< std::streampos > file_positions;
// Create a container for the text lines
std::vector< std::string > text_lines;
// Load both containers.
// The number of lines is the size of either vector.
void
Load_Containers(std::ifstream& inp)
{
std::string text_line;
std::streampos file_pos;
file_pos = inp.tellg();
while (!std::getline(inp, text_line)
{
file_positions.push_back(file_pos);
file_pos = inp.tellg();
text_lines.push_back(text_line);
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.