繁体   English   中英

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

[英]Trouble getting string to print random line from text file

我暂时拿起这段代码作为从文本文件中选择随机行并输出结果的方法。 不幸的是,它似乎只输出它选择的行的第一个字母,我无法弄清楚它为什么这样做或如何解决它。 任何帮助,将不胜感激。

#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;

我猜这是问题所在。

这里pick 本质上是指向数组的第一个元素char*的指针,所以当然*pickchar类型的,或者是数组的第一个字符。

另一种看待它的方法是*pick == *(pick +0) == pick[0]

有几种方法可以解决它。 最简单的是只做下面的事情。

return pick;

构造函数将自动为您进行转换。

由于您没有指定文件的格式,我将涵盖两种情况:固定记录长度和可变记录长度; 假设每个文本行都是记录。

读取随机名称,固定长度记录

这个是直截了当的。

  1. 确定所需记录的索引(随机)。
  2. 计算文件位置=记录长度*索引。
  3. 将文件设置到该位置。
  4. 使用std::getline从文件中读取文本。

读取随机名称,可变长度记录

这假设文本行的长度不同。 由于它们不同,因此无法使用数学来确定文件位置。

要从文件中随机选取一行,您必须将每行放入容器中,或者将行开头的文件偏移量放入容器中。

在您的容器建立后,确定随机名称编号并将其用作容器的索引。 如果存储了文件偏移量,请将文件定位到偏移量并读取该行。 否则,从容器中提取文本。

应该使用哪个容器? 这取决于。 存储文本更快但占用内存(您实际上是将文件存储到内存中)。 存储文件位置占用的空间较少,但最终会读取每一行两次(一次找到位置,第二次读取数据)。

对这些算法的增加是对文件进行内存映射,这是读者的练习。

编辑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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM