簡體   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