Whenever I input string such as Dizzy with key 10 for example the output is partially wrong. I am having something like this ===>ns��� while I should have nsjji.
Serial.print("KEY: ");
Serial.println(k);
if ((choice[0]=='e') || (choice[0]=='E')){
int i;
char ch;
for (i=0; str[i] != '\0'; i++){
ch=str[i];
if( ch >= 'a' && ch <= 'z'){
ch=ch+k;
if (ch >'z'){
ch=ch-'z'+'a'-1;
}
str[i]=ch;
}
else if(ch >='A' && ch <= 'Z'){
ch=ch+k;
if (ch > 'Z'){
ch=ch-'Z'+'A'-1;
}
str[i]=ch;
}
}
Serial.print("encrypt: ");
Serial.println(str);
The problem is that z has character value 122. Then you add 10 and you get 132.
A char in C is -128 to 127 (signed), you probably want it to be 0-255 and then it has to be unsigned.
So when you get above the maximum of 127 you get the problems..
Change
char ch;
To this instead:
unsigned char ch;
Related
I'm using QGeoCoordinate::tostring(), and I'd like to remove special character "°".For instance this is the return value about function: "41° 4' 11.1\" N, 30° 33' 15.0\" W";, I was able remove all special character, but not "°". This is my code:
QGeoCoordinate geo(41.0697, -30.5542);
QString strGeo = geo.toString(QGeoCoordinate::DegreesMinutesSecondsWithHemisphere);
strGeo .replace("°", "");
I tried with regular expression too, but nothing. This is visual studio and windows platform. Have you some idea?
Degree sign can be defined as unicode decimal 176. You could use QChar constructor taking unicode code point as integer and use QString::replace.
strGeo.replace(QChar(176), "");
I found a solution using c++:
QString clearBytes(std::string str)
{
QString res;
for (int i = 0; i < str.size(); i++)
{
if ((str[i]) >= ',' && str[i] <= '.')
res += QChar(str[i]);
if (str[i] >= '0' && str[i] <= '9')
res += QChar(str[i]);
if (str[i] >= 'A' && str[i] <= 'Z')
res += QChar(str[i]);
}
return res;
}
int main()
{
QString strGeo = geo.toString(QGeoCoordinate::DegreesMinutesSecondsWithHemisphere);
QString result=clearBytes(strGeo.toStdString());
return 0;
}
I didn't find a qt way.I also had an runtime error while using isalpha() standard library.
I created a function that compares strings, and as I was frustrated about it always missing the last character in the second string and always returning "identical strings" as a result, I noticed that I was messing around and used gets() instead of fgets() for the second string. I changed that and the function works as expected.
My question is, why does the gets() function subtract that last character? Shouldn't it subtract the null and leave it at that?
Does that mean that as a newcomer to C, I should avoid using gets() and focus on fgets() instead? I'm starting to think of them in the same way I think of strcmp() vs strncmp()
Thanks for your time everyone!
Note: I'm aware that I don't really need the (i==j) at the end, I just left it there (extra security, maybe?).
bool compare_string(const char *string1, const char *string2) {
int i = 0, j = 0, result = 0;
while (string1[i] != '\0') {
i++;
}
while (string2[j] != '\0') {
j++;
}
i = 0;
j = 0;
while ((string1[i] != '\0') && (string2[j] != '\0')) {
if (string1[i] < string2[j]) {
result = -1;
break;
} else if (string1[i] > string2[j]) {
result = 1;
break;
} else if (string1[i] == string2[j]) {
result = 0;
}
i++;
j++;
}
if ((result == 0) && (i==j)) {
printf("identical strings \n");
} else if (result == -1) {
printf("not identical, -1 \n");
} else if (result == 1) {
printf("not identical, 1 \n");
}
}
//in main
char str_compare1[STRING_LIMIT];
char str_compare2[STRING_LIMIT];
printf("enter 1st string to compare, (100) characters or less: \n");
fgets(str_compare1, STRING_LIMIT, stdin);
printf("enter 2nd string to compare, (100) characters or less \n");
fgets(str_compare2, STRING_LIMIT, stdin);
result = compare_string(str_compare1, str_compare2);
im trying to encrypt the f1.txt file by shifting the letter based off the number and write it to f2.txt. but im not sure if the contents of f1.txt go into ./cf
$ cat f1.txt | ./cf -e 3 > f2.txt
int main(int argc, char ** argv){
char alpha[26] = {'A','B','C','D','E','F','G','H','I','J','K','L', // alphabet arr
'M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z'};
//ifstream input(argv[0]);
string line = "";
if(input.fail()){
cout << "error opening file "<<endl;
exit(1);
}
string type = argv[1];
if(type == "-e"){
while(getline(input,line)){
char plain [line.length()]; // array to store plain text
strcpy(plain, line.c_str()); //putting input into char array
string cipher_text = ""; // variable to store plain text
int shift = atoi(argv[2]);
for(int x = 0; x < line.length(); x++){ //for loop runs through char array
//and add plain letter based on shift
if((char(plain[x]) >= 65) && (char(plain[x]) <= 90)){;
cipher_text += cipher_letter(alpha,shift,string(1,plain[x]));
}else
cipher_text += plain[x];
}
cout << cipher_text << endl;
}
}else if(type == "-d"){
while(getline(input,line)){
char cipher [line.length()]; // array to store plain text
strcpy(cipher, line.c_str()); //putting input into char array
string plain_text = ""; // variable to store plain text
int shift = atoi(argv[2]);
for(int x = 0; x < line.length(); x++){ //for loop runs through char array
//and add plain letter based on shift
if((char(cipher[x]) >= 65) && (char(cipher[x]) <= 90)){
plain_text += plain_letter(alpha,-shift,string(1,cipher[x]));
}else
plain_text += cipher[x];
}
cout<< plain_text << endl;
}
}
input.close();
}
I just saw that this could technically work, the only mistake I couldn´t resolve was the last ASCII character that gets printed everytime I test it out, I also tested this out without using the name variable, I mean just making a substraction of 32 to any lower case letter in ASCII should give me their upper case one and it does, but I´m curious on why I´m getting an additional char, wich from what I see in screen is apparently Û.
#include <stdio.h>
main()
{
char name[22];
int i;
fputs("Type your name ",stdout);
fgets(name,22,stdin);
for (i = 0; name[i] != '\0'; i = i + 1)
printf("%c",(name[i])-32); /*This will convert lower case to upper */
/* using as reference the ASCII table*/
fflush(stdin);
getchar();
}
Perhaps there is a line break character at the end of the string.
You can check the chararacter code, so that you only convert characters that actually are lower case letters:
for (i = 0; name[i] != '\0'; i = i + 1) {
char c = name[i];
if (c => 97 && c <= 122) {
c -= 32;
}
printf("%c", c);
}
void read_chararray(char in_array[], int* Length)
{
int Indx = 0, Indx2 = 0, Indx3 = 0; // int declarations for indexs of some loops
char cinput = { 0 }, word[255] = { 0 }, word2[255] = { 0 }; // declaration of cinput and first char array before punctiation removed
for (Indx = 0; (cinput = getchar()) != '\n'; Indx++) { // Loop for getting characters from user stop at <enter>
word[Indx] = cinput; // Placing char into array while changing to lowercase
}
Indx2 = Indx; // Set Indx2 to Indx for loop operation
for (Indx = 0; Indx < Indx2; Indx++) { // Loop to check and replace upper characters with lower
cinput = word[Indx];
if (cinput >= 65 && cinput <= 90) { // If cinput is within the ASCII range 65 and 90, this indicates upper characters
cinput += 32; // Add 32 to cinput to shift to the lower character range within the ASCII table
in_array[Indx] = cinput; // Input new value into array pointer
}
else if (cinput >= 97 && cinput <= 122) // scans if character are lower ASCII, places them in array irraticating punctuation and whitespce
in_array[Indx] = cinput; // Input remaining lower case into array pointer
}
*Length = Indx; // final size of array set to Length variable for future use
}
#include<stdio.h>
void upper(char);
void main()
{
char ch;
printf("\nEnter the character in lower case");
scanf("%c", &ch);
upper(ch);
}
void upper( char c)
{
printf("\nUpper Case: %c", c-32);
}
i have this string:
12 4 the quick 99 -1 fox dog \
what i want in my program:
myArray[] = {12, 4, 99, -1};
how i do a multiple number scanning?
See my answer to your other question here. It's a relatively simple matter to replace the strtok section to recognize non-numeric words and neither increment the count (in the first pass) nor load them into the array (in the second pass).
The code has changed as follows:
Using an input file of:
12 3 45 6 7 8
3 5 6 7
7 0 -1 4 5
12 4 the quick 99 -1 fox dog \
it produces output along the lines of:
0x8e42170, size = 6:
12 3 45 6 7 8
0x8e421d0, size = 4:
3 5 6 7
0x8e421e0, size = 5:
7 0 -1 4 5
0x8e42278, size = 4:
12 4 99 -1
Here's the code that produced that output:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>
// This is the linked list of integer arrays.
typedef struct _tIntArray {
int size;
int *array;
struct _tIntArray *next;
} tIntArray;
static tIntArray *first = NULL;
static tIntArray *last = NULL;
// Check that argument is numeric, optional minus sign followed by
// zero or more digits (you may want one or more).
static int isAllNumeric (char *word) {
char *s = word;
if (*s == '-')
s++;
for (; *s != '\0'; s++)
if ((*s < '0') || (*s > '9'))
return 0;
return 1;
}
// Add a line of integers as a node.
static int addNode (char *str) {
tIntArray *curr; // pointers for new integer array.
char *word; // word within string.
char *tmpStr; // temp copy of buffer.
int fldCnt; // field count for line.
int i;
// Count number of fields.
if ((tmpStr = strdup (str)) == NULL) {
printf ("Cannot allocate duplicate string (%d).\n", errno);
return 1;
}
fldCnt = 0;
for (word = strtok (tmpStr, " "); word; word = strtok (NULL, " "))
if (isAllNumeric (word))
fldCnt++;
free (tmpStr);
// Create new linked list node.
if ((curr = malloc (sizeof (tIntArray))) == NULL) {
printf ("Cannot allocate integer array node (%d).\n", errno);
return 1;
}
curr->size = fldCnt;
if ((curr->array = malloc (fldCnt * sizeof (int))) == NULL) {
printf ("Cannot allocate integer array (%d).\n", errno);
free (curr);
return 1;
}
curr->next = NULL;
for (i = 0, word = strtok (str, " "); word; word = strtok (NULL, " "))
if (isAllNumeric (word))
curr->array[i++] = atoi (word);
if (last == NULL)
first = last = curr;
else {
last->next = curr;
last = curr;
}
return 0;
}
int main(void) {
int lineSz; // current line size.
char *buff; // buffer to hold line.
FILE *fin; // input file handle.
long offset; // offset for re-allocating line buffer.
tIntArray *curr; // pointers for new integer array.
int i;
// Open file.
if ((fin = fopen ("qq.in", "r")) == NULL) {
printf ("Cannot open qq.in, errno = %d\n", errno);
return 1;
}
// Allocate initial line.
lineSz = 2;
if ((buff = malloc (lineSz+1)) == NULL) {
printf ("Cannot allocate initial memory, errno = %d.\n", errno);
return 1;
}
// Loop forever.
while (1) {
// Save offset in case we need to re-read.
offset = ftell (fin);
// Get line, exit if end of file.
if (fgets (buff, lineSz, fin) == NULL)
break;
// If no newline, assume buffer wasn't big enough.
if (buff[strlen(buff)-1] != '\n') {
// Get bigger buffer and seek back to line start and retry.
free (buff);
lineSz += 3;
if ((buff = malloc (lineSz+1)) == NULL) {
printf ("Cannot allocate extra memory, errno = %d.\n", errno);
return 1;
}
if (fseek (fin, offset, SEEK_SET) != 0) {
printf ("Cannot seek, errno = %d.\n", errno);
return 1;
}
continue;
}
// Remove newline and process.
buff[strlen(buff)-1] = '\0';
if (addNode (buff) != 0)
return 1;
}
// Dump table for debugging.
for (curr = first; curr != NULL; curr = curr->next) {
printf ("%p, size = %d:\n ", curr, curr->size);
for (i = 0; i < curr->size; i++)
printf (" %d", curr->array[i]);
printf ("\n");
}
// Free resources and exit.
free (buff);
fclose (fin);
return 0;
}