Concatenation of strings in C++ (Linux) - c++

I want to concatenate three string in C++.
I have a vector std::vector<std::string> my_list where the filenames are stored. I want to add the directory and filename extension for each of the filenames in order to read binary the information from the file, so i do it like that:
for (int i = 0; i < my_list.size(); i++) {
std::string tmp = prefix + my_list[i] + suffix;
std::ifstream file(tmp.c_str(), std::ifstream::binary);
}
where prefix ist std::string prefix = "directory/" and suffix ist std::string suffix = ".foo".
And it works in Windows. However it doesn't work in Linux.
Suffix overwrites "tmp"-string. It looks like foo/y_file_timestamp instead of out/my_file_timestamp.foo.
What should I do to prevent this overwriting?

The bug is not in the code you showed us.
The problem is that your strings have unexpected characters in them, specifically carriage returns ('\r') that cause the caret to return to the beginning of the line during output of your concatenated string to the terminal window.
Presumably this is a problem caused by careless parsing of input data with Windows-style line endings. You should normalise your data and be sure to strip all line-ending variants during parsing.
Always be sure to check the contents of your strings at the character-level when encountering a problem with string operations.

Thank you #BarryTheHatchet. I forgot to mention that vector my_list was filled this way:
std::string LIST_WITH_DATA = "data/list.scp"
const char* my_data = LIST_WITH_DATA.c_str();
std::ifstream my_file(my_data);
std::string my_line;
while (std::getline(my_file, my_line)) {
my_list.push_back(my_line);
}
data/list.scp looks like:
file1/00001-a
file2/00001-b
file3/00001-c
file4/00001-d
std::getline was my problem.
The solution I found here: Getting std :: ifstream to handle LF, CR, and CRLF?

Related

Weird results when I iterate through string with "ñ" char

I have a string of characters and one of those possible characters is the letter "ñ". My problem is, my string seems to behave in a weird way when I try to modify it or iterate through the string. For example if I have the code:
std::ifstream infile (argv[1]);
std::string texto_crudo((std::istreambuf_iterator<char>(infile)), std::istreambuf_iterator<char>());
for (int i = 0; i<texto_crudo.length(); i++){
if(es_enie(texto_crudo[i])) {
texto_crudo[i] = '$';
}
}
Where es_enie returns true if texto_crudo[i] = ñ. It seems like in the cell where ñ is located it behaves as if it has two values instead of one.
I managed to find a solution to my exact problem. As Some programmer dude commented, it was because my text was in UTF-8 and I needed to convert it to iso-8859-1 in order to be able to use "ñ" correctly.
Convert string from UTF-8 to ISO-8859-1

How can I read CSV file in to vector in C++

I'm doing the project that convert the python code to C++, for better performance. That python project name is Adcvanced EAST, for now, I got the input data for nms function, in .csv file like this:
"[ 5.9358170e-04 5.2773970e-01 5.0061589e-01 -1.3098677e+00
-2.7747922e+00 1.5079222e+00 -3.4586751e+00]","[ 3.8175487e-05 6.3440394e-01 7.0218205e-01 -1.5393494e+00
-5.1545496e+00 4.2795391e+00 -3.4941311e+00]","[ 4.6003381e-05 5.9677261e-01 6.6983813e-01 -1.6515008e+00
-5.1606908e+00 5.2009044e+00 -3.0518508e+00]","[ 5.5172237e-05 5.8421570e-01 5.9929764e-01 -1.8425952e+00
-5.2444854e+00 4.5013981e+00 -2.7876694e+00]","[ 5.2929961e-05 5.4777789e-01 6.4851379e-01 -1.3151239e+00
-5.1559062e+00 5.2229333e+00 -2.4008298e+00]","[ 8.0250458e-05 6.1284608e-01 6.1014801e-01 -1.8556541e+00
-5.0002270e+00 5.2796564e+00 -2.2154367e+00]","[ 8.1256607e-05 6.1321974e-01 5.9887391e-01 -2.2241254e+00
-4.7920742e+00 5.4237065e+00 -2.2534993e+00]
one unit is 7 numbers, but a '\n' after first four numbers,
I wanna read this csv file into my C++ project,
so that I can do the math work in C++, make it more fast.
using namespace std;
void read_csv(const string &filename)
{
//File pointer
fstream fin;
//open an existing file
fin.open(filename, ios::in);
vector<vector<vector<double>>> predict;
string line;
while (getline(fin, line))
{
std::istringstream sin(line);
vector<double> preds;
double pred;
while (getline(sin, pred, ']'))
{
preds.push_back(preds);
}
}
}
For now...my code emmmmmm not working ofc,
I'm totally have no idea with this...
please help me with read the csv data into my code.
thanks
Unfortunately parsing strings (and consequently files) is very tedious in C++.
I highly recommend using a library, ideally a header-only one, like this one.
If you insist on writing it yourself, maybe you can draw some inspiration from this StackOverflow question on how to parse general CSV files in C++.
You could look at getdelim(',', fin, line),
But the other issue will be those quotes, unless you /know/ the file is always formatted exactly this way, it becomes difficult.
One hack I have used in the past that is NOT PERFECT, if the first character is a quote, then the last character before the comma must also be a matching quote, and not escaped.
If it is not a quote then getdelim() some more, but the auto-alloc feature of getdelim means you must use another buffer. In C++ I end up with a vector of all the pieces of getdelim results that then need to be concatenated to make the final string:
std::vector<char*> gotLine;
gotLine.push_back(malloc(2));
*gotLine.back() = fgetch();
gotLine.back()[1] = 0;
bool gotquote = *gotLine.back() == '"'; // perhaps different classes of quote
if (*gotLine.back() != ',')
for(;;)
{
char* gotSub= nullptr;
gotSub=getdelim(',');
gotLine.push_back(gotSub);
if (!gotquote) break;
auto subLen = strlen(gotSub);
if (subLen>1 && *(gotSub-1)=='"') // again different classes of quote
if (sublen==2 || *(gotSub-2)!='\\') // needs to be a while loop
break;
}
Then just concatenate all these string segments back together.
Note that getdelim supports null bytes. If you expect null bytes in the content, and not represented by the character sequences \000 or \# you need to store the actual length returned by getdelim, and use memcpy to concatenate them.
Oh, and if you allow utf-8 extended quotes it gets very messy!
The case this doesn't cover is a string that ends \\" or \\\\". Ideally you need to while count the number of leading backslashes, and accept the quote if the count is even.
Note that this leave the issue of unescaping the quoted content, i.e. converting any \" into ", and \\ into \, etc. Also discarding the enclosing quotes.
In the end a library may be easier if you need to deal with completely arbitrary content. But if the content is "known" you can live without.

How to read a File and save specific occuring strings?

I need to read a file, which is an .asc document using QT Framework.
I need to check the file for specific Strings, for example "(Name)".
The Numbers after the specific String have to be saved in another .txt file.
So I tried to use a for loop connected with a getline() statement, whilst an if statement should be checking if the predefined String was found already.
If the String was found I am using a string variable .assign() method to input the whole matching line to another string.
But sadly it is still not working, maybe there is a logical failure, so I am asking for your help!
std::string line;
std::string search = "(Name)";
std::string content;
std::ifstream ifs("C:/PROG/EMS/LD1/analyse_led");
for(unsigned int curLine = 0; std::getline(ifs, line); curLine++) {
if (line.find(search) != std::string::npos) {
content.assign( (std::istreambuf_iterator<char>(line) ),
(std::istreambuf_iterator<char>() ) );
}
}
Of course I implemented all related include files above, thanks for your help!
If you need more information let me know in the comments.
content and line are both std::strings, just do
content = line;
or
content = std::move(line);
if you don't need to do anything else with line afterwards. (line will be empty after this).
I'm not sure what you are trying to achieve with istreambuf_iterator, but I'm sure it isn't going to work...

Converting strings to char arrays using cstring

I have a small assignment which partly requires me to take inputs from a file in the form of strings and place them into char arrays so I can check if the string contains any '*' character at the end of it.
I have been able to extract the strings from the files successfully, however i have failed to find a way in which to place them in char arrays so i can process them.
I would be very grateful if someone would let me know how to place a string into char arrays using cstring library. Please keep in mind that the strings are taken from a file and not as user input.
some of the ways i tried is the following:
//Try 1
char CstringArray[] = LineFromFile;
//Try 2
char CstringArray[100] = LineFromFile;
//Try 3
ifstream Test("Test.txt");
Test>>CstringArray;
//Try 4
ifstream Test("Test.txt");
Test>>CstringArray[0];
Thank you very much
Since this is an assignment, your professor will probably not be happy with you using all of C++'s functionality, particularly if you don't understand it, but since it's a one liner I figured I'd tell you how I'd print all strings ending in an asterisks. Given that you have successfully opened the file to ifstream Test you can do:
copy_if(istream_iterator<string>(Test), istream_iterator<string>(), ostream_iterator<string>(cout, " "), [](const auto& i) { return !empty(i) && i.back() == '*'; })
EDIT:
I'm using an istream_iterator to read in each string in Test and istream_iterator, I'm operating on these values immediately, but if you needed to start by saving all the strings to a vector<string> you could also do this: vector<string> CstringArray{ istream_iterator<string>(Test), istream_iterator<string>() }
I'm using an ostream_iterator to directly stream out my selected strings rather than storing them
I'm using copy_if to iterate over all the strings that are streamed in, selecting only those that meet a given criteria
I'm using the lambda: [](const auto& i) { return !empty(i) && i.back() == '*'; } to conditionally select non-empty strings which end with an asterisks character

How to read a word into a string ignoring a certain character

I am reading a text file which contains a word with a punctuation mark on it and I would like to read this word into a string without the punctuation marks.
For example, a word may be " Hello, "
I would like the string to get " Hello " (without the comma). How can I do that in C++ using ifstream libraries only.
Can I use the ignore function to ignore the last character?
Thank you in advance.
Try ifstream::get(Ch* p, streamsize n, Ch term).
An example:
char buffer[64];
std::cin.get(buffer, 64, ',');
// will read up to 64 characters until a ',' is found
// For the string "Hello," it would stream in "Hello"
If you need to be more robust than simply a comma, you'll need to post-process the string. The steps might be:
Read the stream into a string
Use string::find_first_of() to help "chunk" the words
Return the word as appropriate.
If I've misunderstood your question, please feel free to elaborate!
If you only want to ignore , then you can use getline.
const int MAX_LEN = 128;
ifstream file("data.txt");
char buffer[MAX_LEN];
while(file.getline(buffer,MAX_LEN,','))
{
cout<<buffer;
}
EDIT: This uses std::string and does away with MAX_LEN
ifstream file("data.txt");
string string_buffer;
while(getline(file,string_buffer,','))
{
cout<<string_buffer;
}
One way would be to use the Boost String Algorithms library. There are several "replace" functions that can be used to replace (or remove) specific characters or strings in strings.
You can also use the Boost Tokenizer library for splitting the string into words after you have removed the punctuation marks.