C ++在读取文件时在字符串的开头添加回车符

时间:2009-05-10 21:16:24

标签: c++ random fstream

我有两个问题:

1)为什么我的代码在selected_line字符串的开始处添加回车符?
2)你认为我用来从文件中返回一个随机行的算法是否足够好并且不会引起任何问题?

示例文件是:

line
number one
#
line number two

我的代码:

int main()
{
    srand(time(0));
    ifstream read("myfile.dat");
    string line;
    string selected_line;
    int nlines = 0;
    while(getline(read, line, '#')) {
        if((rand() % ++nlines) == 0)
            selected_line = line;
    }
    // this is adding a \n at the beginning of the string
    cout << selected_line << endl; 
}

编辑:好的,你们有些人的建议很有意义。该字符串可能被读作“\ nmystring”。所以我现在的问题是,我如何从字符串中删除第一个\ n?

7 个答案:

答案 0 :(得分:1)

因为您没有将\n指定为分隔符。

答案 1 :(得分:1)

您的“随机”选择完全错误。实际上,它总是会选择第一行: rand() % 1始终为0.

如果不知道存在的行数,就无法统一选择随机行。

另外,为什么使用#作为分隔符?默认情况下,Getline获取一行(以\ n结尾)。

答案 2 :(得分:1)

新行可以从您打印的第二行显示。这是因为getline函数在看到#字符时停止,并在下次从它离开的位置调用时恢复,即根据输入文件调用#之后的字符是换行符。使用rand()有效阅读C FAQ 13.16

一个建议是一次性读取整个文件,将行存储在vector中,然后根据需要输出。

答案 3 :(得分:1)

你可能想要的是这样的:

std::vector<std::string> allParagraphs;
std::string currentParagraph;

while (std::getline(read, line)) {        
    if (line == "#") { // modify this condition, if needed
        // paragraph ended, store to vector
        allParagraphs.push_back(currentParagraph);
        currentParagraph = "";
    else {
        // paragraph continues...
        if (!currentParagraph.empty()) {
            currentParagraph += "\n";
        }
        currentParagraph += line;
    }          
}

// store the last paragraph, as well
// (in case it was not terminated by #)
if (!currentParagraph.empty()) {
    allParagraphs.push_back(currentParagraph);
}

// this is not extremely random, but will get you started
size_t selectedIndex = rand() % allParagraphs.size();

std::string selectedParagraph = allParagraphs[selectedIndex];

为了获得更好的随机性,您可以选择这样做:

size_t selectedIndex 
    = rand() / (double) (RAND_MAX + 1) * allParagraphs.size();

这是因为rand()返回的最低有效位往往表现得不那么随意。

答案 4 :(得分:0)

因为#是您的分隔符,所以在该分隔符之后存在的\ n将成为下一行的开头,从而使\ n位于您的行前面。

答案 5 :(得分:0)

1)您没有向\n添加selected_line。相反,通过指定'#',您只是不删除文件中的额外\n个字符。请注意,您的文件实际上看起来像这样:

    麻布     第一名\ n     #\ n     第二行\ n &LT; \&预GT;

所以第二行实际上是“\ nline number two \ n”。

2)否。如果您想随机选择一行,则需要先确定文件中的行数。

答案 6 :(得分:0)

在决定使用哪一行之后,您可以使用std :: string类的substr方法删除\ n:

if ( line.substr(0,1) == "\n" ) { line = line.substr(1); }

正如其他人所说,如果要选择具有均匀随机性的行,则需要先读取所有行,然后选择行号。你也可以使用if(rand()%(++ nlines + 1)),它将选择具有1/2概率的第1行,第2行具有1/2 * 1/3概率等等。