C++ String dissapears outside if statement [closed] - c++

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 8 years ago.
Improve this question
I'm quite a newbie regarding C++ and I'm struggling with one (maybe simple) thing. I want to write a code that checks the first word of the string line and copy the second word of the string line to the string x_start, x_end or num_steps if the first word of the string is equal to "x_start", "x_end" or "num_steps".
The problem I've to solve is the following. In the if statement the value of the second word (label) is copied to the string x_start, but when I go further to below in my debugger, the content of the string x_start disappears after the if statement end bracket. The first sentence of the output (cout) is now equal to: x_start =, where it should be: x_start = 0.
Does anyone know why this happens and how it can be solved? Thanks in advance!
#include <iostream>
#include <fstream>
#include <cassert>
#include <sstream>
#include <string>
int main(int argc, char** argv) {
std::string x_end;
std::string num_steps;
std::string x_start;
std::string line = "x_start 0";
std::istringstream linestream(line);
while (!linestream.eof()) {
std::string label;
std::string value;
linestream >> label >> value;
if(label.compare("x_start") == 0){
std::string x_start = value;
}
else if(label.compare("x_end") == 0){
std::string x_end = value;
}
else if(label.compare("num_steps") == 0){
std::string num_steps = value;
}
else{
std::cout<<"The format of the text in the file 'params.in' ";
std::cout<<"is not correct"<<std::endl";
break;
}
std::cout<<"x_start = "<<x_start<<std::endl;
std::cout<<"x_end = "<<x_end<<std::endl;
std::cout<<"num_steps = "<<num_steps<<std::endl;
}
return 0;
}

Instead of this
std::string x_start = value;
Write this
x_start = value;
Your code introduces new variable x_start that "hides" the existing variable with the same name. This new variable is set, and immediately afterwards destroyed. So, just don't introduce new variable, and all will be fine.
Repeat this also for x_end and num_steps.

When you do this
if(label.compare("x_start") == 0){
std::string x_start = value;
} //^^^^^^^^^^^
you are telling the compiler the following: "I need a new string variable called x_start. This variable will replace x_start from the outside until the end of the if statement".
This is not what you want, though: you want to assign the existing variable! Removing the declaration will fix this problem:
if(label.compare("x_start") == 0){
x_start = value;
}
Now you are assigning an existing variable - the one that would remain there after the if statement. Of course you need to do the same with other declarations that shadow variables outside of their statements.
Note: the technical term for which variable is visible at what part of your program is scope. Look it up to see what it means and how to work with it.

if(label.compare("x_start") == 0){
std::string x_start = value;
}
Should be
if(label.compare("x_start") == 0){
x_start = value;
}

Related

I need help swapping this string [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 1 year ago.
Improve this question
#include <iostream>
using namespace std;
int main()
{
string sentence;
string output;
string product1;
string product2;
char pr1;
string product;
int i;
getline (cin,sentence);
char pr2;
cin >> pr1;
cin >> pr2;
for (i=0; i < sentence.length();i++){
pr1 = sentence[i]; //asdfg---> g
pr2 = sentence[0]; //--> a
}
output += pr1+sentence+pr2;
cout << output;
return 0;
}
This code is made to swap letters, but for example when I enter asdfg I get gaasdfga. When I enter that, I want to swap g and a. Any idea what I should do? Any idea what's wrong, and how I can improve it?
The below assigns new values to pr1 and pr2. The characters you entered will be lost.
pr1 = sentence[i]; //asdfg---> g
pr2 = sentence[0]; //--> a
To swap the first found of each of the two entered characters, use std::string::find and then std::swap
Example:
#include <utility>
#include <string>
#include <iostream>
int main() {
std::string sentence = "asdfg";
char pr1 = 'g';
char pr2 = 'a';
auto pos1 = sentence.find(pr1);
auto pos2 = sentence.find(pr2);
if(pos1 != sentence.npos && pos2 != sentence.npos) {
std::swap(sentence[pos1], sentence[pos2]);
}
std::cout << sentence << '\n';
}
Output:
gsdfa
An alternative to std::swap(sentence[pos1], sentence[pos2]); would be to do the swap manually:
char temp = sentence[pos1];
sentence[pos1] = sentence[pos2];
sentence[pos2] = temp;
or via a user defined swapper function that you call just like you'd call std::swap:
template<class T>
void swapper(T& lhs, T& rhs) {
// move construct a temporary variable from the argument on the
// left hand side
T temp = std::move(lhs);
// move assign the left hand side from the right hand side
lhs = std::move(rhs);
// move assign the right hand side from the temporary variable
rhs = std::move(temp);
}

How to extract data from string in C++ [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 2 years ago.
Improve this question
Note: I am working using C++11 standard
I am looking to write a function that handles the following problem:
Given the following input: a,b,c I want it to print a and b and c
Given: a,b,c, I want it to print a and b and c and ""
Given: ,a I want it to print "" and a
Given , it should print "" and in case of empty string it shouldn't print anything
In other words I want to extract every value between two , plus to take care of the edges.
My current implementation is so buggy and I had edited it more than 8 times since I always find some edge cases.
void print(const string &command)
{
string vertex_title = "";
int i = 0;
while (i < command.lengh()) {
if (command[i] == ',') {
if (i==command.lengh()-1) return false;
std::cout<<vertex_title;
vertex_title = "";
i++;
continue;
}
vertex_title += command[i++];
}
Note: I don't know but maybe regex help here (I know nothing about it)
While you could implement such a function, I'd strongly suggest using existing solutions. There are quite a few.
I'm personally used to absl::StrSplit() (see https://abseil.io/docs/cpp/guides/strings) which by default will do what you want.
Thomas Sablik also wrote in a comment:
You can use boost::algorithm::split or std::strtok
I guess you need this. Even though it's ugly. You can run and debug it step by step.
#include <iostream>
#include <string>
using namespace std;
void print(const string &command)
{
std::string vertex_title = "";
int i = 0;
while (i < command.size()) {
if (command[i] == ',') {
cout << vertex_title;
vertex_title = "";
}
else {
vertex_title += command[i];
}
++i;
if (i == command.size())
cout << vertex_title;
}
}
int main()
{
print("a,b,c");
print("a,b,c,");
print(",a");
print(",");
return 0;
}

strcpy compiles on Windows but it doesn't on Linux [closed]

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 3 years ago.
Improve this question
I'm learning C++ and trying to write universal code (sorry, I don't know how you call the code that can compiles on Windows, Linux, MacOS, etc.).
I have written the function trimLeft:
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
const string rows = "rows:";
const string columns = "cols:";
const string data = "data:";
struct dimensions {
int rows;
int columns;
};
inline bool exists (const string& name) {
ifstream f(name.c_str());
return f.good();
}
string trimLeft(const string& input) {
if ((input.empty()) ||
((input.at(0) != ' ') && (input.at(0) != '\t')))
return input;
else {
char * tab2 = new char[input.length() + 1];
char *trimmed = new char[input.length() + 1];
strcpy(tab2, input.c_str());
bool skip = true;
int pos = 0;
for (unsigned int i = 0; i < (input.length() + 1); i++) {
if (skip) {
if ((tab2[i] == ' ') || (tab2[i] == '\t'))
continue;
else {
skip = false;
trimmed[pos] = tab2[i];
pos++;
}
}
else {
trimmed[pos] = tab2[i];
if (tab2[i] == '\0')
break;
else
pos++;
}
}
string stringTrimmed(trimmed);
return stringTrimmed;
}
}
It compiles on Windows showing this warning:
warning C4996: 'strcpy': This function or variable may be unsafe.
Consider using strcpy_s instead. To disable deprecation, use
_CRT_SECURE_NO_WARNINGS.
But in Linux, with the following command:
g++ FormatMatrix.cpp -o format
I get:
error: ‘strcpy’ was not declared in this scope
Are headers different on each operating system?
NOTE: And please, stop voting negative: I've got the message.
It is entirely possible that as an implementation detail for a particular compiler, <cstring>, which includes the declaration of strcpy, is included (perhaps much further up the inclusion tree) by another header you included.
To ensure that your code is truly portable and standard conforming include the header files for every class and function you call; never take for granted that you get the functionality of another header by including something different.

Losing first line element in file when converting from string to float [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 4 years ago.
Improve this question
I have the following problem and I don't know why and how it's happening.
This is my file:
###########################
###########################
POINTS
68.252 87.2389 -50.1819
68.2592 87.2451 -50.2132
68.2602 87.2436 -50.2133
68.2564 87.2333 -50.1817
68.2618 87.2475 -50.244
68.2476 87.2446 -50.182
68.2582 87.2466 -50.2131
68.2618 87.2475 -50.244
67.9251 87.2509 -49.8313
67.9311 87.2511 -49.8443
67.9786 87.196 -49.8365
67.9735 87.1946 -49.8231
67.9383 87.2513 -49.8574
67.9848 87.1975 -49.8499
68.0704 87.0819 -49.8067
68.0778 87.09 -49.8349
68.0002 87.2009 -49.8769
68.088 87.1 -49.8633
68.1689 86.9755 -49.8051
68.1709 86.9825 -49.8199
68.1672 86.9693 -49.7903
68.2164 86.9204 -49.7972
68.2157 86.913 -49.7821
...
END
##############################
TRIANGLES
...
What I want is to read each line of my file. Split on spaces and convert the string to a float. This is how I am doing it:
#include "pch.h"
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <sstream>
using namespace std;
int main()
{
string line;
ifstream inFile;
string path = "C:\\...";
inFile.open(path);
if (!inFile)
{
cerr << "Unable to the open file.";
exit(1);
}
Basic steps to read my file
int vc_size = numOfPoints(inFile); // A function I implemented to get the number of points
vector<float> my_coordinates(vc_size);
int current_pos = 0;
Initializing some variables
while (getline(inFile, line))
{
if (line == "POINTS")
{
while (getline(inFile, line, ' '))
{
if (line == "END" || current_pos >= vc_size)
break;
my_coordinates[current_pos] = atof(line.c_str());
current_pos++;
}
}
}
inFile.close();
for (size_t i = 0; i < vc_size; ++i)
cout << my_coordinates[i] << endl;
return 0;
}
Even though this seem logical, I have a huge problem.
The first value of all my lines (except the first one) disappears (meaning all the 68.something are not in my output).
And what is more confusing is that if I make my vector a vector<string> and do x_coordinates[current_pos] = line; then the code works.
This makes no sens to me because the only step that changes is the conversion from string to float (I tried to convert using stringstream but it's the same incorrect result).
The problem is that your code only accounts for space as a separator for your numbers but in fact you have space and newline as separators.
Change your inner loop to this, so it handles all whitespace
string item;
while (inFile >> item)
{
if (item == "END" || current_pos >= vc_size)
break;
x_coordinates[current_pos] = atof(item.c_str());
current_pos++;
}

C++ Help (ISO C++ forbids comparison between pointer and integer.) [closed]

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 9 years ago.
Improve this question
i'm trying to make a very simple program with stacks but i seem to be getting an error when i try to run it. The error says "ISO C++ forbids comparison between pointer and integer.". Any help is greatly appreciated.
My Code:
#include <iostream>
#include <string>
using namespace std;
const int maxstack = 5;
struct stacktype{
string name[maxstack];
int top;
};
void createstack(stacktype &stack);
void destroystack(stacktype &stack);
bool fullstack(stacktype stack);
void push(stacktype &stack, string &newelement);
bool emptystack(stacktype stack);
void pop(stacktype &stack, string &poppedelement);
int main(){
stacktype stack;
string newelement, poppedelement;
char quest;
createstack(stack);
cout<<"Do you want to enter data? (y/n)";
cin>>quest;
while((quest == "y" || quest == "Y") && !(fullstack(stack))){ //I get the error on this line
cout<<"Please enter name";
cin>>newelement;
push(stack, newelement);
cout<<"Do you want to enter data? (y/n)";
cin>>quest;
}
cout<<endl<<endl;
while(!emptystack(stack)){
pop(stack, poppedelement);
cout<<poppedelement<<endl;
}
destroystack(stack);
system("PAUSE");
return 0;
}
void createstack(stacktype &stack){
stack.top = -1;
}
void destroystack(stacktype &stack){
stack.top = -1;;
}
bool fullstack(stacktype stack){
if(stack.top == maxstack - 1){
return true;
}else{
return false;
}
}
void push(stacktype &stack, string &newelement){
stack.top++;
stack.name[stack.top] = newelement;
}
bool emptystack(stacktype stack){
if(stack.top == -1){
return true;
}else{
return false;
}
}
void pop(stacktype &stack, string &poppedelement){
poppedelement = stack.name[stack.top];
stack.top--;
}
quest is a char, yet "y" is a string literal with type const char[2]. When you try to compare these with quest == "y", the string literal is converted to a pointer to its first element, and so you are attempting to compare a char with a pointer. That's what the error is telling you.
Instead of a string literal, you want a character literal like 'y', which has type char.
quest is of char type, so it is single character, and you try to compare it with string literals like "y". Use single quotes for char literals: 'y'.
Since you are writing C++ code, you should use the string class instead of "y".