I am trying to represent a variable in the form of a string to a integer, I have done so using;
atoi(str.c_str())
The string is originally obtained from a text file and stored into a;
CharArrayPtr cmemblock;
Which is then represented as a string;
string str;
for(int i = 0; i < numberofvalues; i++)
{
str = cmemblock[i];
int number = atoi(str.c_str());
cout << number;
}
If I was to change the 'cout' to print str;
str = cmemblock[i];
int number = atoi(str.c_str());
cout << str;
The number show correctly as stored in the text file
However, I require the output to be an integer so that I could represent it in a loop to search for a value stored in a array. So this is where 'number' comes into play, which is the reason why I am asking for your help, when;
cout << number;
Whenever a new line is read it is represented as '0' how would I go about removing this? If your require my full code it is in several different .cpp files and to prevent anyone copying my work I can only email it you, im sure you have already guessed it is part of a University Assignment.
Using Member Adosi code I came up with this;
std::string str;
for(int i = 0; i < numberofvalues; i++)
{
str = cmemblock[i];
std::stol(str);
int number = std::stoi(str);
cout << number;
}
I get an error R6010. Have I done this wrong?
std::stoi(str)
Use this instead of atoi
C++11 has this and a few other functions such as std::stol() for longs, std::stof() for floats, etc.
http://en.cppreference.com/w/cpp/string/basic_string/stol
If you dont have C++11 for std::stoi but do have boost you could use lexical cast
#include <boost/lexical_cast.hpp>
int main()
{
std::string s = "100";
try
{
int n = boost::lexical_cast<int>(s);
std::cout << "n = " << n << std::endl;
}
catch (boost::bad_lexical_cast)
{
std::cout << "conversion failed" << std::endl;
}
}
This ensures a valid conversion can take place and throws an exception if it cannot
Regarding your Edit - This requires a C++11 Compiler to work
std::string str;
for(int i = 0; i < numberofvalues; i++)
{
str = cmemblock[i];
//std::stol(str); -> This line is unneeded as it converts string to a long
// Ideally you should check that str is valid here etc. before changing it to an int
int number = std::stoi(str);
cout << number;
}
Another option is to use std::stringstream:
#include <sstream>
#include <string>
int string_to_int(const std::string &string) {
std::stringstream s(string);
s >> number;
if (!s.good()) {
throw std::exception();
}
return s;
}
int main(int argc, const char* argv[]) {
int number = string_to_int(argv[1]);
return 0;
}
This doesn't require any external libraries or C++11, and should be compatible with any C++ compiler out there.
Edit
Fleshed out the example to show how you could write your own string_to_int function to simplify the use of std::stringstream.
Related
I have prototype - int replace_char(string &, char);
I can't use library from string and ctype.h, I should write my own function.
So the task is to find in the text caharacter, which should I should replace with "*" .
example: In This is my text .
replace all t to * . Result will be - *his is my *ex*.
#include <iostream>
using namespace std;
int replace_char(string &, char);
int main ()
{
cout << ""Please insert text:"
cin >> str;
}
int replace_char(string str, char c1)
{
for (int i = 0 ; i < str.length(); i++)
{
if(str[i]==c1)
str[i]='*';
}
return str;
}
There were several errors in the code:
The function signature mismatches, the prototype is defined as std::string& but in the function definition, std::string only was used.
The program never converted the capital letter T or anything which is capital in order to convert them before comparing each letter with a single char.
The function is never used in the code.
cin >> str won't take longer texts followed by next whitespace character.
The function wants to return an integer, but actually returned type was a std::string, which is totally a misunderstanding.
The code redefined:
#include <iostream>
// taking a reference of std::string and a char
int replaceText(std::string&, char);
int main(void) {
std::string s;
int rep;
std::cout << "Enter a string: ";
std::getline(std::cin, s); // getline() to accept whitespaces
// since we're using a reference, the original variable is manipulated
int rep = replaceText(s, 't');
std::cout << "Output: " << s << std::endl;
std::cout << "Replaced number of chars: " << rep << std::endl;
return 0;
}
int replaceText(std::string& str, char c) {
size_t len = str.length();
static int count;
// changing each letter into lowercase without using any built-in functions
for (size_t i = 0; i < len; i++)
if (str[i] >= 'A' && str[i] <= 'Z')
str[i] = str[i] + 32;
// replacing the character, the main work
for (size_t i = 0; i < len; i++)
if (str[i] == c) {
str[i] = '*';
count++; // count a static variable
}
return count; // returning the overall counts
}
The program firstly takes an input from the user of type std::string and uses reference to the variable str. Now the program enters to the function code.
In the beginning, the function converts each letter to lowercase without using any library or a built-in function. Afterwards, it tries to compare each letter of the string carefully and as soon the given character matches a value containing in the string passed to the function, it replaces and counts a static variable which keeps the value save for the entire program life.
Thereafter, it simply displays the manipulated string.
It outputs something like:
Enter a string: This is a text
Output: *his is a *ex*
Replaced chars: 3
You seem to have a good start.
You need to declare str before reading input into it. Try string str;
Then you need to use your function in main. Either store its output into another string like string replaced = replace_char(str, 't');
Or put it into the output directly like cout << replace_char(str, 't') << endl;
Probably this is what you need
#include <iostream>
using namespace std;
int replace_char(string &, char);
int main ()
{
string str;
cout << "Please insert text:"
std::getline(cin, str);
int rlen = replace_text(str, 't')
cout << str << endl;
cout << "Number of replaced : " << rlen << endl;
return 0;
}
int replace_char(string str, char c1)
{
int rlen = 0;
for (int i = 0 ; i < str.length(); i++)
{
if(str[i]==c1) {
str[i]='*';
rlen++;
}
}
return rlen;
}
Given the prototype of the function, I'm guessing you need to return the number of chars replaced. This implementation should work:
#include <string>
#include <iostream>
using namespace std;
int replace_char(string &, char);
int main ()
{
cout << "Please insert text:";
string str;
getline(cin, str);
int nCharsReplaced = replace_char(str, 't');
}
int replace_char(string& str, char c1)
{
int count = 0;
for (int i = 0 ; i < str.length(); i++)
{
if(str[i]==c1)
{
str[i]='*';
count++;
}
}
return count;
}
Keep in mind there's no need to return the string, as you're passing it by reference, so the argument itself is modified.
Also, if you want the example you provided to work the replace_char functions cannot be case sensitive, since you replaced the capital 'T' with '*' too. In order to achieve that, you could implement a function that turns every char to lowercase (ideally, you would use tolower from ctype):
char to_lower_case(char c)
{
return c - ('Z' - 'z');
}
And replace the if condition with:
if (to_lower_case(str[i]) == c1)
If you don't understand how this work, take a look at how ASCII works.
#include<iostream>
#include<string>
using namespace std;
int STRLEN(char* s){
cout<<"\n1.";
int i=0;
while(s[i] != '\0'){
cout<<"\n2.";
i++;
}
return i;
}
int main(){
int i,j;
char* s1;
char* s2;
cout<<"\nEnter string : ";
cin.getline(s1,50);
cout<<s1;
cout<<"\nEnter string : ";
cin.getline(s2,50);
cout<<s2;
int L1=STRLEN(s1);
int L2=STRLEN(s2);
cout<<"\nL1 = "<<L1;
cout<<"\nL2 = "<<L2;
/*
for*(i=L1,j=0; i<L1+L2; i++,j++)
{
s1[i] = s2[j];
j++;
}
cout<<s1;*/
return 0;
}
the above code is giving me segmentation fault at line int L1=STRLEN(s1);
Please provide a solution , i want my string to be dynamically manipulated, so that i can extend the given string, also append new string to existing string without using inbuilt methods.
Also without using string data type
Actually, your function STRLEN looks norm (except couts inside and lack of const for s)
int STRLEN(const char* s)
{
int i=0;
while(s[i] != '\0')
{
i++;
}
return i;
}
The problem in memory allocation :getline does not allocate memory for you - you must allocate memory for strings
char* s1;
char* s2;
E.g. like:
char* s1 = malloc(100);
char* s2 = malloc(100);
Actually for your case with cin.getline(s2,50); 50 bytes will be enough:
char* s2 = (char*)malloc(50);
Here (char*) is explicit cast of a pointer type (see also static_cast for C++, and be informed that for C implicit cast is working in that case)
UPDATE:
Just to give you more examples and provoke more questions... the following is my modification of your program with comments for each section:
#include<iostream>
#include<string>
using namespace std;
int STRLEN(const char* s)
{
int i=0;
while(s[i] != '\0')
{
i++;
}
return i;
}
int main(void)
{
int i; // one counter will be enough
char* s1;
char* s2;
// allocation the memory
s1 = static_cast<char*>(malloc(50));
s2 = static_cast<char*>(malloc(50));
// check results of memory allocation
if(!s1 || !s2)
{
cerr << "Something went wrong!" << endl;
return 1;
}
// getting strings
cout<<"\nEnter the first string : ";
cin.getline(s1,50);
cout<< "S1 : [" << s1 << "]" << endl;
// clean input buffer before next string input
cin.clear(); // reset state of cin
cin.ignore(INT_MAX, '\n'); // clean the input buffer
// continue input
cout<<"\nEnter the second string : ";
cin.getline(s2,50);
cout<< "S2 : [" << s2 << "]" << endl;
// count sizes (like strlen)
int L1=STRLEN(s1);
int L2=STRLEN(s2);
// reallocate memory for resulting string in s1
if( !(s1 = static_cast<char*>(realloc(s1, L1+L2+1))) )
{
cerr << "Something went wrong while reallocating memory!" << endl;
return 1;
}
// manipulations with strings (like strcat)
for(i=0; i <= L2; i++) // <= to copy '\0' also
{
s1[i + L1] = s2[i];
}
cout<< "Result : [" << s1 << "]" << endl;
// deallocate memory
free(s1);
free(s2);
return 0;
}
And as molbdnilo rightly noted in the comments, in C++ it is better to use new and delete for memory allocation and deallocation, so after you figure out with my example try to get rid of C functions: malloc, realloc and free.
After that, like making your program even more C++ solution, consider changing the type of strings from char * to std::string this will definitely save you from memory allocation problem and make all other parts of program simpler (e.g. s1 += s2 operation will be possible). When you get to that read about getline for string
I need to convert a string in C++ to full upper case. I've been searching for a while and found one way to do it:
#include <iostream>
#include <algorithm>
#include <string>
using namespace std;
int main()
{
string input;
cin >> input;
transform(input.begin(), input.end(), input.begin(), toupper);
cout << input;
return 0;
}
Unfortunately this did not work and I received this error message:
no matching function for call to 'transform(std::basic_string::iterator, std::basic_string::iterator, std::basic_string::iterator,
I've tried other methods that also did not work. This was the closest to working.
So what I'm asking is what I am doing wrong. Maybe my syntax is bad or I need to include something. I am not sure.
I got most of my info here:
http://www.cplusplus.com/forum/beginner/75634/
(last two posts)
You need to put a double colon before toupper:
transform(input.begin(), input.end(), input.begin(), ::toupper);
Explanation:
There are two different toupper functions:
toupper in the global namespace (accessed with ::toupper), which comes from C.
toupper in the std namespace (accessed with std::toupper) which has multiple overloads and thus cannot be simply referenced with a name only. You have to explicitly cast it to a specific function signature in order to be referenced, but the code for getting a function pointer looks ugly: static_cast<int (*)(int)>(&std::toupper)
Since you're using namespace std, when writing toupper, 2. hides 1. and is thus chosen, according to name resolution rules.
Boost string algorithms:
#include <boost/algorithm/string.hpp>
#include <string>
std::string str = "Hello World";
boost::to_upper(str);
std::string newstr = boost::to_upper_copy("Hello World");
Convert a String In C++ To Upper Case
Try this small program, straight from C++ reference
#include <iostream>
#include <algorithm>
#include <string>
#include <functional>
#include <cctype>
using namespace std;
int main()
{
string s;
cin >> s;
std::transform(s.begin(), s.end(), s.begin(), std::ptr_fun<int, int>(std::toupper));
cout << s;
return 0;
}
Live demo
You could do:
string name = "john doe"; //or just get string from user...
for(int i = 0; i < name.size(); i++) {
name.at(i) = toupper(name.at(i));
}
Uppercase to Lowercase and viceversa using BitWise operators
1.
string s = "cAPsLock";
for(char &c: s)
c = c | ' '; // similar to: c = tolower(c);
cout << s << endl; // output: capslock
string s = "cAPsLock";
for(char &c: s)
c = c & ~' '; // similar to: c = toupper(c);
cout << s << endl; // output: CAPSLOCK
PS: for more info check this link
#include <iostream>
using namespace std;
//function for converting string to upper
string stringToUpper(string oString){
for(int i = 0; i < oString.length(); i++){
oString[i] = toupper(oString[i]);
}
return oString;
}
int main()
{
//use the function to convert string. No additional variables needed.
cout << stringToUpper("Hello world!") << endl;
return 0;
}
Like leemes said, you can use toupper(int). Like this:
void ToUpper(string &str) {
for (auto beg = str.begin(); beg != str.end(); ++beg) {
*beg = toupper(*beg);
}
}
It'll through in each character from str and convert it to upper. Example:
int main()
{
string name;
cout << "Insert a name: ";
cin >> name;
ToUpper(name);
cout << "Name in upper case: " << name << endl;
}
You can also use the function from code below to convert it to Upper-case.
#include<iostream>
#include<cstring>
using namespace std;
//Function for Converting Lower-Case to Upper-Case
void fnConvertUpper(char str[], char* des)
{
int i;
char c[1 + 1];
memset(des, 0, sizeof(des)); //memset the variable before using it.
for (i = 0; i <= strlen(str); i++) {
memset(c, 0, sizeof(c));
if (str[i] >= 97 && str[i] <= 122) {
c[0] = str[i] - 32; // here we are storing the converted value into 'c' variable, hence we are memseting it inside the for loop, so before storing a new value we are clearing the old value in 'c'.
} else {
c[0] = str[i];
}
strncat(des, &c[0], 1);
}
}
int main()
{
char str[20]; //Source Variable
char des[20]; //Destination Variable
//memset the variables before using it so as to clear any values which it contains,it can also be a junk value.
memset(str, 0, sizeof(str));
memset(des, 0, sizeof(des));
cout << "Enter the String (Enter First Name) : ";
cin >> str; //getting the value from the user and storing it into Source variable.
fnConvertUpper(str, des); //Now passing the source variable(which has Lower-Case value) along with destination variable, once the function is successfully executed the destination variable will contain the value in Upper-Case
cout << "\nThe String in Uppercase = " << des << "\n"; //now print the destination variable to check the Converted Value.
}
I need to read in a text file that contains only integers and each one is separated by new line. example would be:
0
1
2
...
64
repeating 0 to 64 64 times
Essentially the file is 64*64 lines long, containing an integer for each line.
I need to store each integer (line) in ldisk, my 2D array, but am having serious problems doing so. I understand my code has an error because I am trying to store a string in a char, but I am not sure how to get around this. By the way, ldisk must be a 2-D array of chars. I would love some advice/feedback on my current code posted below, or an alternative solution.
NOTE: I am a beginner at C++
PS:
I know similar topics exist, but mine is more to the problem of getting around the type conversion or just converting it properly so I can store more than a single digit integer into my 2D array, because I have it working where I can store only the first digit where I want in my 2D array, but run into problems if there is more than 1 digit.
int main(){
char **ldisk;
ldisk = new char*[64];
for (int i = 0; i<64; i++)
{
ldisk[i]= new char[64];
}
int counter = 0;
string line;
ifstream inFile("example2.txt");
while ( getline(inFile, line))
{
int first, second;
first = counter/64;
second = counter%64;
cout << line;
ldisk[first][second]= line;
}
return 0;
}
EDIT:
My apologies I have no idea how to do a table.
I want ldisk[0][0] to be 0,
then ldisk[0][1] to be 1,
then ldisk[0][2] to be 2,
etc,
etc,
then ldisk[0][63] to be 64
Eventually it will fill up such that ldisk[63][63] = 64
This is the problem:
ldisk[first][second]= line;
The type of ldisk[first][second] is char. You are trying to assign a std::string to it.
You can make your life a lot simpler by using a std::vector<std::string>.
#include <iostream>
#include <fstream>
#include <vector>
#include <string>
using namespace std;
int main(){
vector<string> ldisk;
int counter = 0;
string line;
ifstream inFile("example2.txt");
while ( getline(inFile, line))
{
cout << line;
ldisk.push_back(line);
}
return 0;
}
Update
If you must have char** ldisk, you can change main to:
int main()
{
char **ldisk;
ldisk = new char*[64];
for (int i = 0; i<64; i++)
{
ldisk[i]= new char[64];
}
int counter = 0;
string line;
ifstream inFile("example2.txt");
while ( getline(inFile, line) && counter < 64 )
{
cout << line << endl;
if ( line.size() >= 64 )
{
cout << "Line is longer than 63 characters. Copying only 63 characters from it.\n";
strncpy(ldisk[counter], line.c_str(), 63);
ldisk[counter][63] = '\0';
}
else
{
strcpy(ldisk[counter], line.c_str());
}
++counter;
}
return 0;
}
Change your loop to:
for (counter = 0; counter < 64*64; ++counter)
{
int item;
if ( !(inFile >> item) )
{
cerr << "File only contained " << counter << "items.\n";
return 1;
}
if ( item < CHAR_MIN || item > CHAR_MAX )
{
cerr << "Item " << counter << " invalid value " << item << "\n";
return 2;
}
ldisk[counter/64][counter%64] = item;
}
The missing ingredient is that you were not trying to convert the string in your file into an integer value. You may need #include <climits>.
I am trying to write a short line that gets a string using getline and checks it for an int using stringstream. I am having trouble with how to check if the part of the string being checked is an int. I've looked up how to do this, but most seem to throw exceptions - I need it to keep going until it hits an int.
Later I will adjust to account for a string that doesn't contain any ints, but for now any ideas on how to get past this part?
(For now, I'm just inputting a test string rather than use getline each time.)
int main() {
std::stringstream ss;
std::string input = "a b c 4 e";
ss.str("");
ss.clear();
ss << input;
int found;
std::string temp = "";
while(!ss.eof()) {
ss >> temp;
// if temp not an int
ss >> temp; // keep iterating
} else {
found = std::stoi(temp); // convert to int
}
}
std::cout << found << std::endl;
return 0;
}
You could make of the validity of stringstream to int conversion:
int main() {
std::stringstream ss;
std::string input = "a b c 4 e";
ss << input;
int found;
std::string temp;
while(std::getline(ss, temp,' ')) {
if(std::stringstream(temp)>>found)
{
std::cout<<found<<std::endl;
}
}
return 0;
}
While your question states that you wish to
get a string using getline and checks it for an int
using stringstream, it's worth noting that you don't need stringstream at all. You only use stringstreams when you want to do parsing and rudimentary string conversions.
A better idea would be to use functions defined by std::string to find if the string contains numbers as follows:
#include <iostream>
#include <string>
int main() {
std::string input = "a b c 4 e 9879";//I added some more extra characters to prove my point.
std::string numbers = "0123456789";
std::size_t found = input.find_first_of(numbers.c_str());
while (found != std::string::npos) {
std::cout << found << std::endl;
found = input.find_first_of(numbers.c_str(), found+1);
}
return 0;
}
And then perform the conversions.
Why use this? Think about happens if you use a stringstream object on something like the following:
"abcdef123ghij"
which will simply be parsed and stored as a regular string.
Exceptions should not scary you.
int foundVal;
found = false;
while(!found || !ss.eof()) {
try
{
foundVal = std::stoi(temp); //try to convert
found = true;
}
catch(std::exception& e)
{
ss >> temp; // keep iterating
}
}
if(found)
std::cout << foundVal << std::endl;
else
std::cout << "No integers found" << std::endl;