Hi, I'm having trouble trying to convert a line of numbers, e.g.: 100 101 102, to (stoul) an dynamically allocated unsigned integer; the expected is that I can access number by number as an array, in an variable length input.
#include <iostream>
#include <new>
#include <string> //Memset
int console(){
std::string console_buffer;
unsigned long int* integersConverted = NULL;
unsigned int integersNumberOf = 0;
for( ; ; ){
std::getline(std::cin, console_buffer);
integersConverted = console_defaultSyntaxProcessing(console_buffer, &integersNumberOf);
std::cout << "Found the following integers from conversion: ";
for(unsigned int debug_tmp0 = 0; debug_tmp0 < integersNumberOf; debug_tmp0++){
std::cout << integersConverted[debug_tmp0] << " ";
std::cout << std::endl;
}
delete integersConverted;
integersConverted = NULL;
}
return 0;
}
unsigned long int* console_defaultSyntaxProcessing(std::string console_buffer, unsigned int* integersNumberOfUpdate){
*integersNumberOfUpdate = 0;
unsigned int integersNumberOf = 0;
unsigned long int* integersFound = NULL;
integersFound = new unsigned long int(sizeof(unsigned long int) * 1024);
std::size_t stringPosition = 0;
for( ; stringPosition < console_buffer.length() && integersNumberOf < 1024; ){
integersFound[integersNumberOf] = std::stoul(console_buffer, &stringPosition, 10); //10 = Decimal
integersNumberOf++;
}
*integersNumberOfUpdate = integersNumberOf;
return integersFound;
}
I'm getting correct value if I input only one number, but the whole 1024 array is printed if I input two numbers or more and all positions get the first integer. I've tried to manually set the function std::string to constant, zero the console_buffer.length() so it finds '\0', etc; unfortunately not worked..
UPDATE --- 5 minutes after the topic first posting;
The problem is, as Yashas answered, at console_defaultSyntaxProcessing for loop; stoul &stringPosition returns number of characters read from, not the position of std::string.
Another problem using stoul is, if I input 100 ( 101, it doesn't work, so follows the fixed code but shall not be used.
As lamandy suggested, use std::stringstream instead.
std::size_t stringPosition = 0;
std::size_t stringPositionSum = 0;
for( ; stringPosition < console_buffer.length() && integersNumberOf < 1024; ){
try{
integersFound[integersNumberOf] = std::stoul(&console_buffer[stringPositionSum], &stringPosition, 10);
integersNumberOf++;
stringPositionSum = stringPositionSum + stringPosition;
}
catch(std::exception& exception){
break;
} //This catch will be used constantly by this buggy code.
for( ; stringPosition < console_buffer.length() && integersNumberOf < 1024; ){
integersFound[integersNumberOf] = std::stoul(console_buffer, &stringPosition, 10); //10 = Decimal
integersNumberOf++;
}
does not do what you want.
You are passing the same string to std::stoul again and again. Your std::stoul function keeps reading the first number every time. When you had just one number, the stringPosition < console_buffer.length() caused your loop to stop. When you have more than one number, stringPosition will never exceed console_buffer.length().
The second parameter of std::stoul does not take where in the string to start reading from; it gives you the number of characters processed.
For the task you are dealing with, stringstream is what you need.
#include <iostream>
#include <sstream>
#include <array>
int main ()
{
std::istringstream console_buffer("123 345 3 5 2 3 4 5 6 7 7 232 34 332 234 55");
std::array<unsigned long, 1024> integerArray;
size_t count = 0;
while(console_buffer && count < integerArray.size())
console_buffer >> integerArray[count++];
for(int i = 0; i < count; i++)
std::cout<<integerArray[i] << ' ';
return 0;
}
Consider using std::vector and std::stringstream to ease your job.
std::vector<unsigned long int> StringToIntegerVector(const std::string& input)
{
std::istringstream iss(input);
unsigned long int temp;
std::vector<unsigned long int> results;
while (iss >> temp)
results.push_back(temp);
return results;
}
Related
Consistently comparing digits symmetrically to its middle digit. If first number is bigger than the last , first is wining and I have to display it else I display last and that keep until I reach middle digit(this is if I have odd number of digits), if digit don't have anything to be compared with it wins automatically.
For example number is 13257 the answer is 7 5 2.
Another one 583241 the answer is 5 8 3.
For now I am only trying to catch when number of digits is odd. And got stuck.. This is my code. The problem is that this code don't display any numbers, but it compares them in the if statement(I checked while debugging).
#include <iostream>
using namespace std;
int countDigit(int n) {
int count = 0;
while (n != 0) {
count++;
n /= 10;
}
return count;
}
int main() {
int n;
cin >> n;
int middle;
int count = countDigit(n);
if (count % 2 == 0) {
cout<<"No mid digit exsist!!";
}
else {
int lastDigit = n % 10;
middle = (count + 1) / 2;
for (int i = 0; i < middle; i++) {
for (int j = lastDigit; j<middle; j--) {
if (i > j) {
cout << i <<' ';
}
else {
cout << j;
}
}
}
}
return 0;
}
An easier approach towards this, in my opinion, would be using strings. You can check the size of the string. If there are even number of characters, you can just compare the first half characters, with the last half. If there are odd numbers, then do the same just print the middle character.
Here's what I'd do for odd number of digits:
string n;
cin>>n;
int i,j;
for(i=0,j=n.size()-1;i<n.size()/2,j>=(n.size()+1)/2;i++,j--)
{
if(n[i]>n[j]) cout<<n[i]<<" ";
else cout<<n[j]<<" ";
}
cout<<n[n.size()/2]<<endl;
We analyze the requirements and then come up with a design.
If we have a number, consisting of digits, we want to compare "left" values with "right" values. So, start somehow at the left and the right index of digits in a number.
Look at this number: 123456789
Index: 012345678
Length: 9
in C and C++ indices start with 0.
So, what will we do?
Compare index 0 with index 8
Compare index 1 with index 7
Compare index 2 with index 6
Compare index 3 with index 5
Compare index 4 with index 4
So, the index from the left is running up and the index from the right is running down.
We continue as long as the left index is less than or equal the right index. All this can be done in a for or while loop.
It does not matter, wether the number of digits is odd or even.
Of course we also do need functions that return the length of a number and a digit of the number at a given position. But I see that you know already how to write these functions. So, I will not explain it further here.
I show you 3 different examples.
Ultra simple and very verbose. Very inefficient, because we do not have arrays.
Still simple, but more compressed. Very inefficient, because we do not have arrays.
C++ solution, not allowed in your case
Verbose
#include <iostream>
// Get the length of a number
unsigned int length(unsigned long long number) {
unsigned int length = 0;
while (number != 0) {
number /= 10;
++length;
}
return length;
}
// Get a digit at a given index of a number
unsigned int digitAt(unsigned int index, unsigned long long number) {
index = length(number) - index - 1;
unsigned int result = 0;
unsigned int count = 0;
while ((number != 0) && (count <= index)) {
result = number % 10;
number /= 10;
++count;
}
return result;
}
// Test
int main() {
unsigned long long number;
if (std::cin >> number) {
unsigned int indexLeft = 0;
unsigned int indexRight = length(number) - 1;
while (indexLeft <= indexRight) {
if (digitAt(indexLeft, number) > digitAt(indexRight, number)) {
std::cout << digitAt(indexLeft, number);
}
else {
std::cout << digitAt(indexRight, number);
}
++indexLeft;
--indexRight;
}
}
}
Compressed
#include <iostream>
// Get the length of a number
size_t length(unsigned long long number) {
size_t length{};
for (; number; number /= 10) ++length;
return length;
}
// Get a digit at a given index of a number
unsigned int digitAt(size_t index, unsigned long long number) {
index = length(number) - index - 1;
unsigned int result{}, count{};
for (; number and count <= index; ++count, number /= 10)
result = number % 10;
return result;
}
// Test
int main() {
if (unsigned long long number; std::cin >> number) {
// Iterate from left and right at the same time
for (size_t indexLeft{}, indexRight{ length(number) - 1 }; indexLeft <= indexRight; ++indexLeft, --indexRight)
std::cout << ((digitAt(indexLeft,number) > digitAt(indexRight, number)) ? digitAt(indexLeft, number) : digitAt(indexRight, number));
}
}
More modern C++
#include <iostream>
#include <string>
#include <algorithm>
#include <cctype>
int main() {
if (std::string numberAsString{}; std::getline(std::cin, numberAsString) and not numberAsString.empty() and
std::all_of(numberAsString.begin(), numberAsString.end(), std::isdigit)) {
for (size_t indexLeft{}, indexRight{ numberAsString.length() - 1 }; indexLeft <= indexRight; ++indexLeft, --indexRight)
std::cout << ((numberAsString[indexLeft] > numberAsString[indexRight]) ? numberAsString[indexLeft] : numberAsString[indexRight]);
}
}
You are trying to do something confusing with nested for-cycles. This is obviously wrong, because there is nothing “quadratic” (with respect to the number of digits) in the entire task. Also, your code doesn’t seem to contain anything that would determine the highest-order digit.
I would suggest that you start with something very simple: string’ify the number and then iterate over the digits in the string. This is obviously neither elegant nor particularly fast, but it will be a working solution to start with and you can improve it later.
BTW, the sooner you get out of the bad habit of using namespace std; the better. It is an antipattern, please avoid it.
Side note: There is no need to treat odd and even numbers of digits differently. Just let the algorithm compare the middle digit (if it exists) against itself and select it; no big deal. It is a tiny efficiency drawback in exchange for a big code simplicity benefit.
#include <cstdint>
#include <iostream>
#include <string>
using std::size_t;
using std::uint64_t;
uint64_t extract_digits(uint64_t source) {
const std::string digits{std::to_string(source)};
auto i = digits.begin();
auto j = digits.rbegin();
const auto iend = i + (digits.size() + 1) / 2;
uint64_t result{0};
for (; i < iend; ++i, ++j) {
result *= 10;
result += (*i > *j ? *i : *j) - '0';
}
return result;
}
int main() {
uint64_t n;
std::cin >> n;
std::cout << extract_digits(n) << std::endl;
}
If the task disallows the use of strings and arrays, you could try using pure arithmetics by constructing a “digit-inverted” version of the number and then iterating over both numbers using division and modulo. This will (still) have obvious limitations that stem from the data type size, some numbers cannot be inverted properly etc. (Use GNU MP for unlimited integers.)
#include <cstdint>
#include <iostream>
using std::size_t;
using std::uint64_t;
uint64_t extract_digits(uint64_t source) {
uint64_t inverted{0};
size_t count{0};
for (uint64_t div = source; div; div /= 10) {
inverted *= 10;
inverted += div % 10;
++count;
}
count += 1;
count /= 2;
uint64_t result{0};
if (count) for(;;) {
const uint64_t a{source % 10}, b{inverted % 10};
result *= 10;
result += a > b ? a : b;
if (!--count) break;
source /= 10;
inverted /= 10;
}
return result;
}
int main() {
uint64_t n;
std::cin >> n;
std::cout << extract_digits(n) << std::endl;
}
Last but not least, I would strongly suggest that you ask questions after you have something buildable and runnable. Having homework solved by someone else defeats the homework’s purpose.
So I'm pretty new to c++, and this is the second program I've ever written in it. The first program was a complete mess but it worked, this program I decided to just put all in one file. My problem is, it just runs incredibly slowly. I'm pretty sure it's because of just how many characters it has to iterate through, but the requirements are that it can crack a password of a specific length with any special characters like these. Other than the number of characters it has to go through I'm not sure what, if anything, is making it run so slowly. I'm wondering if it's something I've done that is improper and making it take so long. Is this just about how fast a password cracker like this can run?
// Password Cracker.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include <iostream>
#include <string>
#include <thread>
#include <atomic>
#include <vector>
#include <cmath>
#include <sstream>
std::string convertToString(char*, int);
void passwordBruteForcer(std::string, long long, long long);
std::atomic<bool> isPasswordFound = false;
std::string foundString;
int main()
{
// Given some count of the amount of symbols that can exist in the password
// We will calulcate how many possible passwords there are then divide work evenly between threads
// In this case the possible symbols are all ascii codes from 32 to 126
int numOfSymbols = 95;
// Declarations;
int numberOfThreads = 8;
std::string password;
std::vector<std::thread> vecOfThreads;
// Loop waits for correct user input (problem required that password length be 5, change this if you want)
while (true)
{
// Prompting user input
std::cout << "Please enter a password of length 5 \n";
std::cout << "password: ";
std::getline(std::cin, password);
if (password.length() == 5)
{
break;
}
else
{
std::cout << "Invalid password \n";
}
}
long long amountOfPossiblePasswords = pow(numOfSymbols, password.length());
// Creates threads running brute force cracker
for (int threadNumber = 1; threadNumber <= numberOfThreads; threadNumber++)
{
long long startingNumber = (amountOfPossiblePasswords * (threadNumber - 1)) / numberOfThreads;
long long endNumber = (amountOfPossiblePasswords * threadNumber) / numberOfThreads;
long long remainder = amountOfPossiblePasswords % numberOfThreads;
if (threadNumber == numberOfThreads)
{
vecOfThreads.push_back(std::thread(passwordBruteForcer, password, startingNumber, endNumber + remainder));
}
else
{
vecOfThreads.push_back(std::thread(passwordBruteForcer, password, startingNumber, endNumber));
}
}
// Wait to join thread
for (std::thread & th : vecOfThreads)
{
if (th.joinable())
th.join();
}
// Prints the password the algorithm found
if (isPasswordFound)
{
std::cout << foundString;
}
return 0;
}
// Will go through all "printable" ASCII characters
void passwordBruteForcer(std::string passStr, long long startingNumber, long long endNumber)
{
int firstChar = 32;
int lastChar = 126;
int length = passStr.length();
int numOfChar = 95;
int numOfTries = pow(numOfChar, length);
char* guess = new char[length];
// Converts decimal to base num of chars then puts that char into array
// For ex. 0 will be first char, and a 1 will be the next char, the number that represents the amount of possible passwords
// will set this to be all lastChar
long long numToBeConvert = startingNumber;
for (int i = (length - 1); i >= 0; i--)
{
guess[i] = firstChar + (numToBeConvert % numOfChar);
numToBeConvert /= numOfChar;
}
// This creates a string based on initialized guess then tests it
std::string comparisonPasswordString = convertToString(guess, length);
if (comparisonPasswordString == passStr)
{
isPasswordFound = true;
foundString = comparisonPasswordString;
delete[] guess;
return;
}
// This loop goes from startingNumber to endNumber testing all passwords
for(long long i = startingNumber; i < endNumber; i++)
{
if (isPasswordFound == true)
{
break;
}
long long numForGuess = i;
for (int j = (length - 1); j >= 0; j--)
{
guess[j] = firstChar + (numForGuess % numOfChar);
numForGuess /= numOfChar;
}
comparisonPasswordString = convertToString(guess, length);
if (comparisonPasswordString == passStr)
{
isPasswordFound = true;
foundString = comparisonPasswordString;
break;
}
}
delete[] guess;
}
std::string convertToString(char* charArr, int length)
{
std::string convString;
for (int i = 0; i < length; i++)
{
convString.push_back(charArr[i]);
}
return convString;
}
#include<iostream>
int fastFibonacci(int n)
{
int numbers[n+2]; // int numbers[n].
numbers[0] = 0;
numbers[1] = 1;
for (int i = 2; i <= n; i++)
{
numbers[i] = numbers[i - 1] + numbers[i - 2];
}
return numbers[n];
}
int main() {
int n;
std::cout << "Enter a Number";
std::cin >> n;
int result = fastFibonacci(n);
std::cout << result << "\n";
return 0;
}
in this code when i enter input 0 or 1 get correct answer. But the problem is that when i replace int numbers[n+2]; with the commented part it start giving me wrong answer when input is 0 or 1. why? anyone please explain me.
In this function
int fastFibonacci(int n)
{
int numbers[n+2]; // int numbers[n].
numbers[0] = 0;
numbers[1] = 1;
for (int i = 2; i <= n; i++)
{
numbers[i] = numbers[i - 1] + numbers[i - 2];
}
return numbers[n];
}
there is used a variable length array with n + 2 elements declared in this line
int numbers[n+2]; // int numbers[n].
Variable length arrays is not a standard C++ feature. It can be implemented as own language extension of a C++ compiler.
Using the variable length array makes the function very unsafe because there can occur a stack overflow.
As within the function there is explicitly used two elements of the array
numbers[0] = 0;
numbers[1] = 1;
then the array shall have at least two elements even when the parameter has a value less than 2.
To calculate the n-th Fibonacci number there is no need to declare an array of such a size.
Apart from this the function argument shall have an unsigned integer type. Otherwise the function can invoke undefined behavior if the user passes a negative number.
Also for big values of n there can be an integer overflow for the type int.
The function can be implemented in various ways.
Here is one of possible its implementations.
#include <iostream>
#include <functional>
unsigned long long fibonacci( unsigned int n )
{
unsigned long long a[] = { 0, 1 };
while ( n-- )
{
a[1] += std::exchange( a[0], a[1] );
}
return a[0];
}
int main()
{
const unsigned int N = 10;
for ( unsigned int i = 0; i < N; i++ )
{
std::cout << i << ": " << fibonacci( i ) << '\n';
}
return 0;
}
The program output is
0: 0
1: 1
2: 1
3: 2
4: 3
5: 5
6: 8
7: 13
8: 21
9: 34
int numbers[n+2]; is the declaration of an array of ints with space for n + 2 ints, this is a variable lenght array and is not part of C++ standard, though some compilers allow it it's not somenthing you should use.
If you need a variable lenght array use std::vector.
With int numbers[n+2]; if n is equal to 0 you still have space for 2 ints, if you have int numbers[n]; the array will have space for 0 ints, so the code will fail because you are trying to access memory that does not exist with numbers[0] and numbers[1].
There are several good ways to implement the Fibonacci sequence, in the site you can find many questions regarding this matter in several programming languages, here is one of them Fibonacci series in C++
Edit
So I've seen your comments about using a vector, for making the sequence you wouldn't need the vector just two variables to store the two numbers to add, to store the sequence in a vactor, you can do somenthing like:
#include <iostream>
#include <vector>
#include <iomanip>
//passing the vector by reference
void fastFibonacci(unsigned long long n, std::vector<unsigned long long>& sequence) {
unsigned long long first = 0;
unsigned long long second = 1;
sequence.push_back(first); //add first values to the vector
sequence.push_back(second); //add first values to the vector
for (unsigned long long i = 0, value = 0; i < n && value <= LLONG_MAX ; ++i) {
value = first + second;
first = second;
second = value;
sequence.push_back(value); //adding values to the vector
}
}
int main() {
unsigned long long limit; //number of values in the sequence
int num = 1;
std::vector<unsigned long long> sequence; //container for the sequence
std::cout << "Enter upper limit: ";
std::cin >> limit;
fastFibonacci(limit, sequence);
//print the sequence in a range based loop formatted with <iomanip> library
for(auto& i : sequence){
std::cout << std::setw(4) << std::left << num++ << " " << i << std::endl;
}
return 0;
}
If you want to print just one of the numbers in the sequence, just use, for instance:
std::cout << sequence[10];
Instead of the whole vector.
The code you post in the comment to the other answer won't work because the access to the vector is out of bounds in numbers[i] = numbers[i - 1] + numbers[i - 2];, if for instance i = 5, your vector only has 2 nodes but you are accessing the 6th node numbers[5].
i managed to extract a line from a .txt document and store it in a char array
ifStream inData;
inData.open("test.txt');
char range1[40];
inData.getline(range1, 40);
The output i get is:
BaseIdRange=0-8
I would like to store the numbers 0 and 8 in two different datatypes.
i.e. int1 = 0 and int2 = 8
All help is greatly appreciated.
This is an example that works for 2 unsigned-integers:
#include <sstream>
#include <string>
int main()
{
char buffer[32]{ "BaseIdRange=0-8" }; // Input line
// Clean all chars that are not one of 0-9):
std::string chars = "0123456789"; // 'unsigned int' legitimate chars
for (int i = 0; i < sizeof(buffer); i++) {
if (chars.find(buffer[i]) == std::string::npos) // I.e not one of 0-9
buffer[i] = ' ';
}
std::stringstream ss(buffer);
// Extract the 2 integers:
unsigned int data[2]{ 0 };
for (int i = 0; i < 2; i++) {
ss >> data[i];
}
/*
// Or (instead of the last for):
unsigned int a = 0, b = 0;
ss >> a;
ss >> b;
*/
return 0;
}
It's possible to use std::set<char> chars instead of std::string chars, and to change the if line to if (chars.find(buffer[i]) == chars.end()), but I preferred to keep it simpler - the initialization of std::set is less-obvious.
I've spent a few hours trying to figure out what's wrong with my program, but I can't figure it out. This is a minimum tour cost program. (TSP)
c is for city and a is for arc(cost for travel between 2 cities)
Inputs I'm using to test:
c 1
c 2
c 3
c 4
c 5
a 1 2 1400
a 1 3 1800
a 1 4 4000
a 1 5 3500
a 2 3 1200
a 2 4 3400
a 2 5 3600
a 3 4 2300
a 3 5 2700
a 4 5 2100
And here is my code. The above inputs should give 10500 minTour, but its showing 5600.
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cassert>
#include <sstream>
#include <cstdlib>
#include <string>
#include <stdint.h>
using namespace std;
static char gFirstCity = 0;
static unsigned graph[50][50] = {0};
static unsigned minTour = 0xffffffff;
void swap (char *x, char *y)
{
char temp;
temp = *x;
*x = *y;
*y = temp;
}
void permute(char* cities, unsigned start, unsigned length)
{
if (start == (length-1))
{
cout << endl;
unsigned cost =0;
cost+= graph[(unsigned)gFirstCity][(unsigned)*cities];
for(unsigned i = 0; i < length-1; i++ )
{
cost+=graph[(unsigned)cities[i]][(unsigned)cities[i+1]];
for(int i = 0; i < length; i++){
cout << (int)cities[i];
}
}
cost+=graph[(unsigned)cities[length-1]][(unsigned)gFirstCity];
for(int i = 0; i < length; i++){
cout << (int)cities[i];
}
if(cost<minTour){
minTour = cost;
}
}
else
{
for (unsigned j = start; j < length; j++)
{
swap((cities + start), (cities + j));
permute(cities, start + 1, length);
swap((cities + start), (cities + j));
}
}
}
int main()
{
string cities;
string line;
char command = 0;
unsigned city = 0;
while (getline(cin, line))
{
sscanf(line.c_str(), "%c %d", &command, &city);
if (command != 'c')
break;
cities.push_back((unsigned char)city);
}
gFirstCity = cities[0];
unsigned to = 0;
unsigned from = 0;
uint32_t cost = 0;
sscanf(line.c_str(), "%c %d %d %d", &command, &to, &from, &cost);
graph[to-1][from-1]=cost;
graph[from-1][to-1]=cost;
while (getline(cin, line))
{
sscanf(line.c_str(), "%c %d %d %d", &command, &to, &from, &cost);
graph[to-1][from-1]=cost;
graph[from-1][to-1]=cost;
}
permute((char*)cities.c_str()+1, 0, cities.length()-1);
cout << minTour << endl;
return EXIT_SUCCESS;
After adding a bit of debugging output to the code, the biggest problem appears to be that your algorithm mixes array indexes and cities inconsistently.
For example, your gStartCity is used as an array index (0-based), but is actually a city number (1-based).
You use array indexes 1-5 when actually obtaining costs, but you assign the costs to array indexes 0-4.
I believe you can get the expected result by changing both sets of graph[][] assignments to:
graph[to][from]=cost;
graph[from][to]=cost;
The definition of graph[][] will allow this without overwriting something else, and you won't live long enough for this algorithm to compute the optimal path for 49 cities, so the difference won't matter (49 cities would require about 6E+62 possible paths; even if you could check a million paths per second, this would only take about 20,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000 years to compute).
Your code is very difficult to read and follow, so I'm not sure how best to fix the fundamental problem that you are off by 1 on most of your array indices, but at least this should get it running closer to the way you expect.