C ++ l'aggiunta di un ritorno a capo ad inizio stringa quando la lettura del file

StackOverflow https://stackoverflow.com/questions/846121

  •  21-08-2019
  •  | 
  •  

Domanda

Ho due domande:

1) Perché il mio codice di aggiunta di un ritorno a capo alla beggining della stringa selected_line?
2) Pensi che l'algoritmo che sto usando per restituire una riga a caso dal file è abbastanza buono e non causerà alcun problema?

Un esempio di file è:

line
number one
#
line number two

Il mio codice:

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

Modifica OK, quello che alcuni di voi hanno suggerito fa un sacco di senso. La stringa viene probabilmente letto come "\ nmystring". Quindi credo che la mia domanda ora è, come faccio a rimuovere il primo \ n dalla stringa?

È stato utile?

Soluzione

Che probabilmente si desidera è qualcosa di simile:

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

Per una migliore casualità, si potrebbe optare per questo, invece:

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

Questo perché i bit meno significativi restituiti da rand() tendono a comportarsi in modo non casuale affatto.

Altri suggerimenti

Perché non si specifica \n come delimitatore.

La sua selezione "random" è completamente sbagliato. Infatti, sarà sempre selezionare la prima riga: rand() % 1 è sempre 0.

Non v'è alcun modo per selezionare in modo uniforme una riga a caso senza conoscere il numero di linee presenti.

Inoltre, perché stai usando # come delimitatore? Getline, per impostazione predefinita, ottiene una linea (che termina con \ n).

Le nuove righe possono apparire dalla seconda linea di stampare. Questo perché, la funzione getline ferma vedendo il # carattere e riprende la prossima volta che viene chiamato da dove si è di vale a dire un personaggio oltre la rand(), che secondo il vostro file di input è un ritorno a capo. Leggi la C FAQ 13.16 sul modo efficace utilizzando vector.

Un suggerimento è quello di leggere l'intero file in una volta, memorizzare le righe in un <=> e poi uscita come richiesto.

A causa # è il vostro delimeter, il \ n che esiste subito dopo delimeter sarà l'inizio della riga successiva, rendendo così il \ n essere davanti della vostra linea.

1) Lei non è l'aggiunta di un \n a selected_line. Invece, specificando '#' non si sta semplicemente rimuovendo il <=> caratteri supplementari nel file. Si noti che il file è in realtà qualcosa di simile:

    biancheria     numero uno \ n     # \ N     numero di riga due \ n <\ Pre>

Quindi, la linea numero due è in realtà "il numero nline \ due \ n".

2) No. Se si desidera selezionare in modo casuale una linea, allora è necessario determinare il numero di righe nel file prima.

È possibile utilizzare il metodo substr della classe std :: string per rimuovere il \ n Dopo aver deciso la linea da utilizzare:

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

Come altri hanno detto, se si desidera selezionare le linee con casualità uniforme, è necessario leggere tutte le linee e poi selezionare un numero di linea. Si potrebbe anche usare if (rand ()% (++ nlines + 1)) che selezionerà la linea 1 con 1/2 di probabilità, la linea 2 con 1/2 * 1/3 di probabilità, ecc.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top