Split array of characters into alphanumeric and non-alphanumeric ones - c++

I'm just a student and I want to know about this array in c++.
How can I display all alphanumeric chars inputted on array k to array n
and all non-alphanumeric on array t?
This what I made, and I don't know what's next
int main(int argc, char *argv[])
{
char k[8], n[8], t[8];
int ctr, nctr, tctr;
for(ctr=0; ctr<8; ctr++){
cout << "Input 1st Element ";
cin >> k[ctr];
if (isalnum(k[ctr]))

#include <string.h>
#include <iostream>
using namespace std;
int main(void) {
char k[8], n[8], t[8];
strcpy(k,"--------");
strcpy(n,"--------");
strcpy(t,"--------");
for (int pos = 0, tcntr = 0, ncntr =0; pos < 8; pos++) {
cout<<"Input your char < : ";
cin>>k[pos];
if (isalnum(k[pos])) {
n[ncntr] = k[pos];
ncntr++;
} else {
t[tcntr] = k[pos];
tcntr++;
}
}
cout<<"Alpha numernic chars ::"<<n<<endl;
cout<<"Non Aplha numberic chars ::"<<t<<endl;
}
Input your char < : 3
Input your char < : ^
Input your char < : d
Input your char < : &
Input your char < : f
Input your char < : 1
Input your char < : 7
Input your char < : 1
Alpha numernic chars ::3df171--
Non Aplha numberic chars ::^&------

how can I display all alphanumeric chars inputted on array k to array n and all non-alphanumeric on array t?
I assume by "display" you mean "copy"? Just use a conditional:
int ctr, nctr = 0, tctr = 0; // note how I explicitly set the counters to 0
for (ctr = 0; ctr < 8; ctr++)
{
cout << "Input Element " << ctr << ": ";
cin >> k[ctr];
if (isalnum(k[ctr]))
{
n[nctr++] = k[ctr];
}
else
{
t[tctr++] = k[ctr];
}
}
If that's not what you wanted, please provide more information.

If it is allowed to use STL, this is when partition_copy is the best solution. You can split array k into two arrays n and t by checking given predicate (whether char is alphanumeric in your case). Like this:
#include <string>
#include <iostream>
#include <algorithm>
using namespace std;
int main(int argc, char *argv[])
{
const size_t len = 8;
char k[len], n[len], t[len];
// Input your data...
// Copy all alphanumeric chars in n and non-alphanumeric to t
partition_copy(k, k + len, n, t, isalnum);
}

Related

How to access c++ string by index for a integer number?

How do i edit this program for j to contain "1"?
Currently it shows 49 which is the ascii value i think.
#include <iostream>
using namespace std;
main()
{
string i = "123";
int j = i[0];
cout << j;
}
You can do this as shown below:
int main()
{
std::string i = "123";
int j = i[0] - '0'; //this is the important statement
std::cout << j;
}
Explanation
'0' is a character literal.
So when i wrote:
int j = i[0] - '0';
The fundamental reason why/how i[0] - '0' works is through promotion.
In particular,
both i[0] and '0' will be promoted to int. And the final result that is used to initialize variable j on the left hand side will be the resultant of subtraction of those two promoted int values on the right hand side.
And the result is guaranteed by the Standard C++ to be the integer 1 since from C++ Standard (2.3 Character sets)
...In both the source and execution basic character sets, the value of
each character after 0 in the above list of decimal digits shall be
one greater than the value of the previous.
So there is no need to use magic number like 48 etc.
Construct a new string from character.
Convert the substring to integer.
Example:
#include <iostream>
using namespace std;
main() {
string i = "123";
// Method 1, use constructor
string s1(1, i[0]);
cout << s1 << endl;
// Method 2, use convertor
int j = atoi(s1.c_str());
cout << j << endl;
}
The solution is simple , just cast j to char .
Example:
#include <iostream>
using namespace std;
main()
{
string i = "123";
int j = i[0];
cout << char(j);
}
You have to subtract ASCII '0' (48) from the character digit:
#include <iostream>
using namespace std;
int main()
{
string i = "123";
int j = i[0] - 48; // ASCII for '0' is 48
// or
// int j = i[0] - '0';
cout << j;
}
Change j to be a char instead of an int:
#include <iostream>
#include <string>
using namespace std;
int main()
{
string i = "123";
char j = i[0];
cout << j;
}

Recursively convert a given string to the number it represents

Write a recursive function to convert a given string into the number it represents. That is input will be a numeric string that contains only numbers, you need to convert the string into corresponding integer and return the answer.
I only get the first digit of my string as the output. E.g "1234" as 1 or "231" as 2. Which makes me think there may be an error in my recursive function (the base case seems fine though) but I cant figure out what it is.
#include <math.h>
#include <cmath>
#include <iostream>
using namespace std;
int lenght (char input[]){
int count = 0;
for (int i=0 ; input[i] != '\0' ; i++){
count++;
}
return count;
}
//helper
int stringToNumber(char input[], int start ) {
int len = lenght(input);
//base case
if(start ==0){
return int (input[start]) - 48;
}
int a = stringToNumber(input , start+1);
int b = int(input[start]) - 48;
int k = pow(10, len-1);
return k*b + a;
}
int stringToNumber(char input[]) {
return stringToNumber(input, 0);
}
int main() {
char input[50];
cin >> input;
cout << stringToNumber(input) << endl;
}
Sample Input 1 :
1231
Sample Output 1:
1231
What my code generates: 1
Converting string to decimal integer - is actually converting a number from decimal to binary form. I.e. each digit is a mod of 10.
I.e. for the 1234 it can be done done like 1 * 1000 + 2 * 100 + 3 * 10 + 4
or (1*10)+2, (12*10)+3, (123*10)+4. Second algorithm can be implemented like next recursive function:
constexpr uintmax_t atou(const char* a,uintmax_t ret = 0) noexcept {
return '\0' == *a ? ret : atou(a+1, (ret * 10) + ( *a - '0') );
}
i.e. you are scanning a string for digits, until '\0' end of line character (or std::isspace for example), if more digits in the string multiply result on 10 and add the next digit to the result.
static_assert( 1234 == atou("1234"), "1234 expected" );
Try this code:
#include <iostream>
#include <string.h>
#include <math.h>
using namespace std;
int convert(char c[]) {
if (c[0]=='\0') {
return 0;
} else {
int d = strlen(c) - 1;
int p = pow(10, d);
int k = int(c[0]) - 48; // ASCII value of '0' is 48
return (k * p + convert(c + 1));
}
}
int main() {
int n;
cin >> n;
char c[n];
cin >> c;
cout << convert(c);
}
public class solution {
public static int convertStringToInt(String input){
// Write your code here
if(input.length()<1)
{
return 0;
}
return input.charAt(input.length()-1)-'0'+(10*convertStringToInt(input.substring(0,input.length()-1)));
}
}

How to extract 2 integers from a char array C++ and storing them in 2 variables (Beginner)

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.

C++ check If a hexadecimal consists of ABCDEF1 OR 0

I have written a program below that converts a string to an int and then converts the decimal number to hexadecimal. I'm struggling to check if the hexadecimal consists only of these characters A, B, C, D, E, F, 1, 0. If so set a flag to true or false.
#include<iostream>
#include <stdlib.h>
#include <string>
#include <sstream>
string solution(string &S){
int n = stoi(S);
int answer;
cout << "stoi(\"" << S << "\") is "
<< n << '\n';
//decToHexa(myint);
// char array to store hexadecimal number
string hexaDeciNum[100];
// counter for hexadecimal number array
int i = 0;
while(n!=0)
{
// temporary variable to store remainder
int temp = 0;
// storing remainder in temp variable.
temp = n % 16;
// check if temp < 10
if(temp < 10)
{
hexaDeciNum[i] = temp + 48;
i++;
}
else
{
hexaDeciNum[i] = temp + 55;
i++;
}
n = n/16;
}
// printing hexadecimal number array in reverse order
for(int j=i-1; j>=0; j--){
cout << hexaDeciNum[j] << "\n";
return "";
}
int main() {
string word = "300";
cout << solution(word);
return 0;
}
OK, it is not the exact answer to what you are asking for, but it is a valuable alternative approach for the entire problem of conversion:
char letter(unsigned int digit)
{
return "0123456789abcdefg"[digit];
// alternatively upper case letters, if you prefer...
}
Now you don't have to differenciate... You can even use this approach for inverse conversion:
int digit(char letter)
{
int d = -1; // invalid letter...
char const* letters = "0123456789abcdefABCDEF";
char* l = strchr(letters, letter);
if(l)
{
d = l - letters;
if(d >= 16)
d -= 6;
}
// alternatively upper case letters, if you prefer...
}
Another advantage: This works even on these strange character sets where digits and letters are not necessarily grouped into ranges (e. g. EBCDIC).

Writing program in C++ using Microsoft VS, but I get a debug assertion message here. It runs on cpp.sh and repl.it fine, but not on VS. What can I do?

This function is meant to remove all special characters, numbers, and whitespace from the char array.
// Michael E. Torres II
// Vigenere Cipher
// February 4, 2018
// C++ code to implement Vigenere Cipher
#include <iostream>
#include <string>
#include <iomanip>
#include <fstream>
#include <algorithm>
#include <cctype>
#include <iterator>
#include <sstream>
#include <functional>
using namespace std;
// This function generates the key in
// a cyclic manner until it's length isi'nt
// equal to the length of original text
string generateKey(string str, string key)
{
int x = str.size();
for (int i = 0; ; i++)
{
if (x == i)
i = 0;
if (key.size() == str.size())
break;
key.push_back(key[i]);
}
return key;
}
// This function returns the encrypted text
// generated with the help of the key
string cipherText(string str, string key)
{
string cipher_text;
for (int i = 0; i < str.size(); i++)
{
// converting in range 0-25
int x = (str[i] + key[i]) % 26;
// convert into alphabets(ASCII)
x += 'A';
cipher_text.push_back(x);
}
return cipher_text;
}
// This function decrypts the encrypted text
// and returns the original text
string originalText(string cipher_text, string key)
{
string orig_text;
for (int i = 0; i < cipher_text.size(); i++)
{
// converting in range 0-25
int x = (cipher_text[i] - key[i] + 26) % 26;
// convert into alphabets(ASCII)
x += 'A';
orig_text.push_back(x);
transform(orig_text.begin(), orig_text.end(), orig_text.begin(), ::tolower);
}
return orig_text;
}
string removeNonAlpha(char *str)
{
unsigned long i = 0;
unsigned long j = 0;
char c;
while ((c = str[i++]) != '\0')
{
if (isalpha(c)) // this is where the breakpoint is automatically placed
{
str[j++] = c;
}
}
str[j] = '\0';
return str;
}
// Driver program to test the above function
int main(int argc, char *argv[])
{
string keyword = "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb";
stringstream ss;
char a[] = "“I think and think for months and years. Ninety-nine times, the conclusion is false. The hundredth time I am right.” – Albert Einstein “Imagination is more important than knowledge. For knowledge is limited, whereas imagination embraces the entire world, stimulating progress, giving birth to evolution.” – Albert Einstein";
int i = 0;
string str = removeNonAlpha(a);
str.append(512 - str.length(), 'X');
transform(str.begin(), str.end(), str.begin(), ::toupper);
transform(keyword.begin(), keyword.end(), keyword.begin(), ::toupper);
string key = generateKey(str, keyword);
string cipher_text = cipherText(str, key);
transform(cipher_text.begin(), cipher_text.end(), cipher_text.begin(), ::tolower);
transform(key.begin(), key.end(), key.begin(), ::tolower);
string orig = originalText(cipher_text, key);
cout << "Original/Decrypted Text : " << "\n";
for (int i = 0; i < orig.size(); i += 81)
orig.insert(i, "\n");
cout << orig;
cout << "\n\n" << "Ciphertext : " << "\n";
for (int i = 0; i < cipher_text.size(); i += 81)
cipher_text.insert(i, "\n");
cout << cipher_text;
cout << "\n\nPress ENTER key to Continue\n";
getchar();
return 0;
}
The char array works fine with this while loop, so long as there are no special characters [.,%$#!^]. As soon as there are any special characters in the char array, it gives me the debug assertion:
"Program: ...\Projects\ConsoleApplication17\Debug\ConsoleApplication17.exe
File: minkernel\crts\ucrt\src\appcrt\convert\isctype.cpp
Line: 42
Expression: c >= -1 && c <= 255
...
The program '[11048] ConsoleApplication17.exe' has exited with code 3 (0x3)."
If I run this on repl.it or cpp.sh, I get no issues though. I appreciate any help. Thank you.
It isn't done at all. It needs to be cleaned up a lot, but I'm just trying to test it as is.
see https://msdn.microsoft.com/en-us/library/xt82b8z8.aspx
isalpha expects a number between 0 and 0xFF:
The behavior of isalpha and _isalpha_l is undefined if c is not EOF or
in the range 0 through 0xFF, inclusive. When a debug CRT library is
used and c is not one of these values, the functions raise an
assertion.
You need to cast you char to an unsigned char before passing to isalpha.