Bu kod parçasının istekleri ayrıştırması, URI yolunu ayıklaması, ardından her bir üstbilgiyi ve onun değerini ayıklaması ve ardından tüm bu ayıklanan değişkenleri son olarak iletilecek olan std::vector <const char*> cva
içine iletmesi gerekir.C++ vektörler, const char *, değişkenler kapsamı ve kullanım ömrü
std::vector<std::vector<const char*>> nv (config.nv.push_back(std::move(cva));)
için burada birkaç sorun vardır:
- ayrıştırma doğru oluyor ama yolu ben çıkarılan değişkenin içeriğini geçirerek/depolamak.Bu bir yanlış anlaşılma yüzünden ya düzgün çalışmıyor gibi görünüyor değişkenlerin nasıl saklandığını/retr C++ (ve büyük olasılıkla C++ öğrenmeye başladığımdan beri) ya da farkında olmadığım bazı daha büyük bir konu olan ben ve onların kapsamı.
- Ayrıştırma işlemimin doğru yapıldığını gösteren bazı
print
ifadelerini ekledim. Ancak,for
döngülerinin (sonunda) farklı çıktısı bekleniyor.
i
#include <vector>
#include <cstring>
#include <iostream>
#include <string>
namespace {
std::vector<std::string> explode(const std::string& str, const char& ch) {
std::string next;
std::vector<std::string> result;
// For each character in the string
for (std::string::const_iterator it = str.begin(); it != str.end(); it++) {
// If we've hit the terminal character
if (*it == ch) {
// If we have some characters accumulated
if (!next.empty()) {
// Add them to the result vector
result.push_back(next);
next.clear();
}
} else {
// Accumulate the next character into the sequence
next += *it;
}
}
if (!next.empty())
result.push_back(next);
return result;
}
}
int main() {
// this is an example of how my reqlines looks like
std::vector<std::string> reqlines;
reqlines.push_back("https://endpoint/test1");
reqlines.push_back("https://endpoint/test2\theader1:1234\tcookie:abcd");
reqlines.push_back("https://endpoint/test3\theader1:5678");
reqlines.push_back("https://endpoint/test4");
reqlines.push_back("https://endpoint/test5");
std::vector<std::string> paths;
std::vector<std::string> extraheaders;
std::vector<std::vector<std::string> > tokenized;
int count = 0; // keeps track of each request number so I can access its corresponding extra headers from extraheaders vector
bool cond = true;
if (cond){
// creating which will be used to store my requests paths as well as extra headers
// This has to be a const char * vector since it will be used by an external library which requires such type
std::vector<const char *> cva;
for (auto &req : reqlines){
unsigned int pos = req.find_first_of("\t", 0);
if (pos == -1){
paths.push_back(req);
extraheaders.push_back(" ");
} else {
paths.push_back(req.substr(0, pos));
extraheaders.push_back(req.substr(pos+1, std::string::npos));
}
}
for (auto &path : paths){
cva.push_back(":path");
cva.push_back(path.c_str()); // adding the URI path into cva variable
// explode function which returns a std::vector<std::string> when passing an std::string to it
tokenized.push_back(explode(extraheaders[count], '\t')); // extracting the vector<std::string> of all extra headers
// if (tokenized[count][0].compare(" ") == 0){
// printf(" %d element is empty is skipped \n");
// }else {
for (auto &tok : tokenized[count]){ // looping through extra headers of request number "count", parsing header name/value and adding it to cva
printf(" %d tok %s\n", __LINE__, tok.c_str());
printf(" %d tok address %d\n", __LINE__, &tok);
unsigned int pos = tok.find_first_of(":", 0);
if (pos == -1)
printf(" %d there are no headers \n", __LINE__);
else {
printf("header name: %s\n", (tok.substr(0, pos)).c_str());
printf("header value: %s\n", (tok.substr(pos+1, std::string::npos)).c_str());
cva.push_back((tok.substr(0, pos)).c_str());
cva.push_back((tok.substr(pos+1, std::string::npos)).c_str());
}
}
cva.push_back(":version"); // adding version header
cva.push_back("HTTP/1.1"); // adding version header number
cva.push_back(nullptr); // adding nullptr (which is how nv is expecting cva to be terminated)
count++;
// passing the cva content to nv
//config.nv.push_back(std::move(cva));
}
// Below are the printing statement to check the values of the different variables I created and populated
// above, my problem is that the population process puts some values into my variables however printing
// the content of the those variables shows different values from what I am expecting
std::cout << " " << std::endl << std::endl;
std::cout << "Printing cva" << std::endl;
for (auto &elem : cva){
if (elem == nullptr)
std::cout << static_cast<void*>(nullptr) << std::endl;
else
std::cout << &elem << " " <<elem << std::endl;
}
std::cout << " " << std::endl << std::endl;
std::cout << "Printing paths" << std::endl;
for (auto &path : paths){
std::cout << &path << " " << path << std::endl;
}
std::cout << " " << std::endl << std::endl;
std::cout << "Printing headers" << std::endl;
for (auto &hed : extraheaders) {
std::cout << &hed << " "<<hed << std::endl;
}
}
}
beklenen çıktı olmalıdır:
Printing cva
:path
endpoint:port/test1
:version
HTTP/1.1
0
:path
endpoint:port/test2
:header1
1234
:cookie
abcd
:version
HTTP/1.1
0
:path
endpoint:port/test3
:header1
5678
:version
HTTP/1.1
0
:path
endpoint:port/test4
:version
HTTP/1.1
0
:path
endpoint:port/test5
:version
HTTP/1.1
0
gerçek çıktı:
Printing cva
:path
endpoint:port/test1
:version
HTTP/1.1
0
:path
endpoint:port/test2
header1 // for test2 request, header1 value is 1234
5678
header1 // header 1 should not be printed twice
5678
// Missing cookie header and value
:version
HTTP/1.1
0
:path
endpoint:port/test3
header1
5678
:version
HTTP/1.1
0
:path
endpoint:port/test4
:version
HTTP/1.1
0
:path
endpoint:port/test5
:version
HTTP/1.1
0
Açıklama için teşekkürler. Const char * ''in cuma boşluğunun başka bir dış kütüphane tarafından kullanıldığını ve değiştiremediğini biliyorum. Bu tanımlanmamış davranışı atlamak için en iyi yaklaşım nedir. yani (tok.substr (0, pos)) içeriğini kopyalamalıyım. c_str() 've' (tok.substr (pos + 1, std :: string :: npos)). c_str() 'diğerlerine değişkenleri ve sonra bu değişkenleri 'cva.push_back()' ye iletin. veya bu kullanım durumunu ele almak için daha iyi, daha zarif bir yol var mı? –
Evet, gerçek dizeyi ayrı bir vektöre kopyalamanız gerekiyor ve ** tüm dizeler kopyalandıktan sonra, "const char *" için ayrı bir vektör oluşturun. –
Bu işe yaradı! Teşekkürler. C++ 'yı öğrendiğimden beri, çözdüğüm çözümü yayınladığımda sorun olur mu? Bu konuda bazı geri bildirimler alabilir ve en iyi uygulamalar nelerdir? Kodu daha zarif ve daha verimli hale getirecek bazı şeyler var ve C++ uzmanlarından bu tür geri bildirimler almak istiyorum! –