string — Strncpy, вызывающий переполнение стека ошибки сегментации

У меня есть программа на C ++, которая читает текстовый файл, а затем преобразует этот текстовый файл в строку. Затем он преобразует строку в массив символов, используя strncpy. Я уже видел вопрос stackoverflow на strncpy и принял необходимые меры предосторожности, чтобы избежать проблем, которые он вызывает при создании массива. Может кто-нибудь объяснить, почему это все еще вызывает ошибку стека.

#include <iostream>
#include <string.h>
#include <random>
#include <fstream>
#include <istream>
#include <sstream>
#include <stdio.h>

using namespace std;

int main()
{
//open a stream reader
ifstream fin;
//opens the text file in the stream reader
fin.open("songlyrics.txt");
//will be used to aggregate all characters in text file
string song;
//used as a pointer when reading each character in text file
char ch;
//while the end of file is not reached
while(!fin.eof())
{
//get the character from the file and add it to the song string
fin.get(ch);
song += ch;
}
//close the file
fin.close();
//make a character array called lyrics_ with a length of the length of song
char lyrics_[song.length()];
//use strncpy to convert song to a char array, lyrics_
strncpy(lyrics_, song.c_str(), sizeof(lyrics_));
//avoid the segmentation fault
lyrics_[sizeof(lyrics_) - 1] = 0;
cout<<lyrics_;
return 0;
}

0

Решение

Это:

char lyrics_[song.length()];
//           ^^^^^^^^^^^^^
//           not a compile-time constant

Является массивом переменной длины и не стандарт C ++.

Кроме того, вам не нужно перерабатывать std::string в массив символов. Это уже вид:

char* lyrics = &song[0]; // assuming you don't append to song in the future

Если вам действительно нужен отдельный символьный буфер, вам придется его динамически распределять:

char* lyrics = new char[song.length() + 1];
memcpy(lyrics, song.c_str(), song.length() + 1); // this will copy the null terminator
delete [] lyrics; // don't forget this
3

Другие решения

C ++ не поддерживает функцию массива переменной длины из C. VLA была стандартной функцией C.1999 и дополнительной функцией в C.2011.

Если вы хотите сделать копию содержимого строки в массив динамического размера charВы можете использовать vector:

std::vector<char> lyrics_(song.begin(), song.end());
lyrics_.push_back('\0');
std::cout << &lyrics_[0];
1

По вопросам рекламы [email protected]