我一会儿拿起这段代码作为从文本文件中选择随机行并输出结果的方法。不幸的是,它似乎只输出它选择的行的第一个字母,我无法弄清楚它为什么这样做或如何解决它。任何帮助将不胜感激。
#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");
}
答案 0 :(得分:2)
firstName = *pick;
我猜这是问题所在。
pick
这里本质上是指向数组第一个元素的指针char*
,所以当然*pick
的类型为char
..或数组的第一个字符。
另一种看待它的方法是*pick == *(pick +0) == pick[0]
有几种方法可以解决它。最简单的就是执行以下操作。
return pick;
The constructor会自动为您进行转化。
答案 1 :(得分:0)
由于您没有指定文件的格式,我将涵盖两种情况:固定记录长度和可变记录长度;假设每个文本行都是记录。
这是直截了当的。
std::getline
。这假设文本行的长度不同。由于它们不同,因此无法使用数学来确定文件位置。
要从文件中随机选取一行,您必须将每行放入容器中,或者将行开头的文件偏移量放入容器中。
在您的容器建立后,确定随机名称编号并将其用作容器的索引。如果存储了文件偏移量,请将文件定位到偏移量并读取该行。否则,从容器中提取文本。
应该使用哪个容器?这取决于。存储文本更快但占用内存(您实际上是将文件存储到内存中)。存储文件位置占用的空间较少,但最终会读取每一行两次(一次找到位置,第二次读取数据)。
对这些算法的扩充是对文件进行内存映射,这是读者的练习。
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);
}
}