简体   繁体   English

无法从字符串打印文本文件中的随机行

[英]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*的指针,所以当然*pickchar类型的,或者是数组的第一个字符。

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. 假设每个文本行都是记录。

Reading Random Names, Fixed Length Records 读取随机名称,固定长度记录

This one is straight forward. 这个是直截了当的。

  1. Determine the index (random) of the record you want. 确定所需记录的索引(随机)。
  2. Calculate the file position = record length * index. 计算文件位置=记录长度*索引。
  3. Set file to the position. 将文件设置到该位置。
  4. Read text from file, using std::getline . 使用std::getline从文件中读取文本。

Reading Random Names, Variable Length Records 读取随机名称,可变长度记录

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. 对这些算法的增加是对文件进行内存映射,这是读者的练习。

Edit 1: Example 编辑1:示例

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.

相关问题 从文本文件中选择随机行 - Picking a random line from a text file 在C ++中从文本文件中选择一条随机行 - Pick a random line from text file in C++ C ++:从文本文件读取随机行 - C++ : Read random line from text file 无法将文本文件中的行读入字符串 - Unable to read line from text file into string 使用ReadFile()从文本文件读取字符串时遇到麻烦 - Trouble using ReadFile() to read a string from a text file 将文本文件中的随机行转换为数字,然后输出数字,用户必须猜测原始行 - converting a random line from a text file into numbers and then outputting the numbers, with the user having to guess the original line (C++) 我正在尝试从文本文件中读取和输出随机行,并且在运行它时我不断收到“浮点异常(核心转储)” - (C++) I am trying to read and output a random line from a text file and I keep getting "Floating Point Exception (Core Dumped)" when running it 在C ++中一次从一行文本文件读取int的麻烦(先输入char,然后进行转换) - Trouble reading ints (well chars and then converting) from text file one line at a time in C++ 将一行文本从文件复制到C ++中的字符串 - Copy one line of text from a file to a string in c++ C ++在文本文件中将字符串与行分开 - C++ Separate string from line in text file
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM