Make for loop continue until a goal is accomplished - loops

I need to be able to find 5 sequential bits of EEPROM memory, ideally closest to 2 (as I have bit #1 & 2 associated with other data and want things to be kept organized). I developed this code which works, but the for loop continues after it has found a good set of numbers.
Serial.println("got to assignment number finder");
for (int AssignCheck = 2; AssignCheck < 250; AssignCheck++){
Serial.println("Finding a good assignment number " + String(AssignCheck));
if (EEPROM.read(AssignCheck) == 255){ //Looks for a blank space which can be used to store the new card
if (EEPROM.read(AssignCheck + 1) == 255){
if (EEPROM.read(AssignCheck + 2) == 255){
if (EEPROM.read(AssignCheck + 3) == 255){
if (EEPROM.read(AssignCheck + 4) == 255){
Serial.println("Found assignment numbers " + String(AssignCheck) + " through to " + String(int(AssignCheck) + 4) + ". Scanner value = " + String(Scanner));
int StoreValue = AssignCheck;
}
}
}
}
}
}
I then thought I could put a while loop around it, and have the while loop stop once a variable is set to 0 as opposed to 1, so I wrote this: (notice the introduction of the while loop, the variable and the Scanner = 0 line in the middle).
Serial.println("got to assignment number finder");
int Scanner = 1;
while (Scanner == 1){
for (int AssignCheck = 2; AssignCheck < 250; AssignCheck++){
Serial.println("Finding a good assignment number " + String(AssignCheck) + ". Scanner value = " + String(Scanner));
if (EEPROM.read(AssignCheck) == 255){ //Looks for a blank space which can be used to store the new card
if (EEPROM.read(AssignCheck + 1) == 255){
if (EEPROM.read(AssignCheck + 2) == 255){
if (EEPROM.read(AssignCheck + 3) == 255){
if (EEPROM.read(AssignCheck + 4) == 255){
Scanner = 0;
Serial.println("Found assignment numbers " + String(AssignCheck) + " through to " + String(int(AssignCheck) + 4) + ". Scanner value = " + String(Scanner));
int StoreValue = AssignCheck;
}
}
}
}
}
}
}
It correctly identifies and sets the variable to 0 when I want, but the while loop doesn't seem to have an impact and the loop continues to produce sets of numbers which could work.
As a novice coder myself, I'm not sure what I could try next.
Any advice would be greatly appreciated.

In these case you can use the instruction break:
Serial.println("got to assignment number finder");
for (int AssignCheck = 2; AssignCheck < 250; AssignCheck++){
Serial.println("Finding a good assignment number " + String(AssignCheck));
if (EEPROM.read(AssignCheck) == 255){ //Looks for a blank space which can be used to store the new card
if (EEPROM.read(AssignCheck + 1) == 255){
if (EEPROM.read(AssignCheck + 2) == 255){
if (EEPROM.read(AssignCheck + 3) == 255){
if (EEPROM.read(AssignCheck + 4) == 255){
Serial.println("Found assignment numbers " + String(AssignCheck) + " through to " + String(int(AssignCheck) + 4) + ". Scanner value = " + String(Scanner));
int StoreValue = AssignCheck;
break;
}
}
}
}
}
}
As you can read here, it does exactly what you want.
Please note that your second attempt doesn't work because the for loop is inside the while: it completes before the whole for loop and, after, it compare the "scanner" variable of the while loop
You can correct it in this way:
Serial.println("got to assignment number finder");
int Scanner = 1;
for (int AssignCheck = 2; (AssignCheck < 250) && (Scanner == 1); AssignCheck++){
Serial.println("Finding a good assignment number " + String(AssignCheck) + ". Scanner value = " + String(Scanner));
if (EEPROM.read(AssignCheck) == 255){ //Looks for a blank space which can be used to store the new card
if (EEPROM.read(AssignCheck + 1) == 255){
if (EEPROM.read(AssignCheck + 2) == 255){
if (EEPROM.read(AssignCheck + 3) == 255){
if (EEPROM.read(AssignCheck + 4) == 255){
Scanner = 0;
Serial.println("Found assignment numbers " + String(AssignCheck) + " through to " + String(int(AssignCheck) + 4) + ". Scanner value = " + String(Scanner));
int StoreValue = AssignCheck;
}
}
}
}
}
}

Reading EEPROM is expensive, please consider this:
Serial.println("got to assignment number finder");
int Scanner = 1;
char rollingBuffer[5];
rollingBuffer[0] = EEPROM.read(2 + 0);
rollingBuffer[1] = EEPROM.read(2 + 1);
rollingBuffer[2] = EEPROM.read(2 + 2);
rollingBuffer[3] = EEPROM.read(2 + 3);
rollingBuffer[4] = EEPROM.read(2 + 4);
pointRoll = 0;
for (int AssignCheck = 7; (AssignCheck < 255); AssignCheck++)
{
if ((rollingBuffer[0] == 255) && (rollingBuffer[1] == 255) && (rollingBuffer[2] == 255) && (rollingBuffer[3] == 255) && (rollingBuffer[4] == 255))
{
Serial.println("Found assignment numbers " + String(AssignCheck-5) + " through to " + String(int(AssignCheck-1)) + ". Scanner value = " + String(Scanner));
int StoreValue = AssignCheck;
break;
}
rollingBuffer[pointRoll] = EEPROM.read(AssignCheck);
pointRoll++;
if (pointRoll > 4) pointRoll = 0;
}

Related

How to convert char string into hex value

I have one situation where i am receiving characters serially, byte by byte in USB Tx mode.
Now I'm stuck at where I am receiving 7 and a and my objective is to create 0x7a data.
Please provide me some workaround.
void converttohex(int recsize) {
BYTE ccount = 0;
//BYTE *recptr = (BYTE*)calloc(CommOP_Rx.bDataLength, sizeof(BYTE));
*recptr = 88;
*(recptr + 1) = 16;
*(recptr + 2) = 1;
*(recptr + 3) = 224;
*(recptr + 4) = 1;
for (xp = 12, s = 5; xp < (CommOP_Rx.bDataLength - 4); xp++,s++) {
if (xp == 12) {
for (xp = 12; (*(recimage + xp)) != ','; xp++)
ccount++;
if (ccount == 1) {
xp = 12;
xq = (*(recimage + xp) - 48);
*(recptr+s) = xq;
xp++;
} else
if (ccount == 2) {
xp = 12;
xq = (*(recimage + xp) - 48) * 10;
xw = (*(recimage + (++xp)) - 48);
*(recptr + s) = xq + xw;
xp++;
} else
if (ccount == 3) {
xp = 12;
xq = (*(recimage + xp) - 48) * 100;
xw = (*(recimage + (++xp)) - 48) * 10;
xe = (*(recimage + (++xp)) - 48);
*(recptr+s) = xq + xw + xe;
xp++;
}
}
xp++;
if (((*(recimage + xp)) == 'a') || ((*(recimage + (++xp))) == 'a')) {
--xp;
if (((*(recimage + xp)) == 'a')) {
xq = (*(recimage + xp) - 48) * 10;
} else
xq = (*(recimage + xp) - 48);
xw = 'a';
*(recptr + s) = xq +xw;
}
xq = (*(recimage + xp) - 48) * 10;
xw = (*(recimage + (++xp)) - 48);
*(recptr + s) = xq + xw;
}
for (xp = 0; xp < (CommOP_Rx.bDataLength - 4); xp++) {
*(recimage + xp) = *(recptr + xp);
}
Basically here i am sampling some data, which is the array of image in hex, and storing it in my MCU array. But here i have implemented that when i will receive a two consecutive data in which which is an Integer 0-9, then i am subtracting 48 into it as all the bytes are in character encoding, upto this it is working fine, but after receiving A-F of hex, lets suppose i have received '7' & 'a' and it has to be value=0x7a , thus i need this conversion help!!
Store it in a null-terminated string and read from it.
// Assume N is a big number
char str[N] = "7A";
int ret;
sscanf(str, "%x", &ret);
printf("%d", ret); // Output: 122
To do it repetitively, let the program construct this array:
int i = 0;
while (read_data(&ch)){
// Assume ch is in "0123456789ABCDEFabcdef"
str[i++] = ch;
}
str[i] = 0;
// Now parse it
int ret;
sscanf(str, "%x", &ret);
You can store the hex digits in an array of char, null terminate this array an use sscanf() or strtol() to convert the string to a number.
Your code seems quite complicated for me to understand. Just giving a glimpse of what can be done to get hexadecimal value based on your question and not based on your code. Sorry for that.
If you process the two inputs as string then the below approach will suite.
char num1[] = "7";
char num2[] = "a";
char num[10];
strcpy (num, num1);
strcat (num, num2);
Now num has 7a as hexadecimal string
If you have the two inputs as integers then this logic will work
int num1,num2,num3;
num1=0x7;
num2=0xa;
num3=(num1<<4)|(num2);
sprintf(str,"0x%x",num3);

Scanner cleared during loop: how do I still maintain a certain condition?

I am in the process of making a program which will display 3 problems of operation type which a user picks. I've used a loop to keep the program generating random numbers for each iteration as well as to display another problem. The problem I'm having is in trying to clear the scanner after taking user input as to not keep the wrong value stored and screw up the loop. I need the one value ("a") to be stored so that the loop continues with the next question. For this post I've taken out all options but addition just for debugging purposes. My code I will paste below:
public static void main(String[] args) {
Scanner stdin = new Scanner(System.in);
Random randGen = new Random(Config.RANDOM_SEED);
// Welcome
System.out.println("Hello and welcome to the Math Trainer!\n======================================");
System.out.println("Which math operation would you like to practice?");
// Create a counter for correct answers
int correctCount = 0;
// Create a for loop to generate multiple questions
for (int count = 0; count < Config.NUMBER_OF_QUESTIONS; count++) {
// Calculate random values from seed and shift them within range
int ran1 = randGen.nextInt(Config.MAX_VALUE - Config.MIN_VALUE + 1);
int ran2 = randGen.nextInt(Config.MAX_VALUE - Config.MIN_VALUE + 1);
int ran1Shift = ran1 + Config.MIN_VALUE;
int ran2Shift = ran2 + Config.MIN_VALUE;
// Initialize different answers per operation
double additionAnswer = (double) ran1Shift + ran2Shift;
double subtractionAnswer = (double) ran1Shift - ran2Shift;
double multiplicationAnswer = (double) ran1Shift * ran2Shift;
double divisionAnswer = (double) ran1Shift / ran2Shift;
double remainderAnswer = (double) ran1Shift % ran2Shift;
// Ask for user input on which to choose (only on first run of loop)
if (count == 0) {
System.out.println(" " + "[A]ddition");
System.out.println(" " + "[S]ubtraction");
System.out.println(" " + "[M]ultiplication");
System.out.println(" " + "[D]ivision");
System.out.println(" " + "[R]emainder");
System.out.print("Enter your choice:" + " ");
}
// Presentation of addition problems
if (stdin.nextLine().equalsIgnoreCase("a")) {
System.out.print(
"What is the solution to the problem:" + " " + ran1Shift + " " + "+" + " " + ran2Shift + " = ");
if (stdin.hasNextDouble()) {
double userNum = stdin.nextDouble();
stdin.nextLine();
if (userNum == additionAnswer) {
System.out.println("That is correct!");
correctCount++;
} else {
System.out.println("The correct solution is: " + additionAnswer + ".");
}
} else {
stdin.nextLine();
System.out.println("All solutions must be entered as decimal numbers.");
System.out.println("The correct solution is " + additionAnswer + ".");
}
} else {
System.out.println("I'm sorry, I only understand choices of: A, S, M, D, or R!");
count--;
}
}
// Program exit
System.out.println("*** You answered " + correctCount + " out of 3 questions correctly. ");
System.out.println("======================================");
System.out.println("Thank you for using the Math Trainer!");
}
}
The output I get if I enter the correct answer to the first problem (13) is:
https://gyazo.com/773f9be3b51f51f5086f38f36ed0c86b
In which I have to enter "a" again for the next question to show.
The output I should get is here:
https://gyazo.com/6609a9f0b44d0b446439d3331be51eb9
Please let me know if you have any questions and thank you very much for your help.
if (stdin.nextLine().equalsIgnoreCase("a")) this is the cause of your problem.
For a quick fix, move the codes asking for operationType to outside of the loop since it's only executed once.
System.out.println(" " + "[A]ddition");
System.out.println(" " + "[S]ubtraction");
System.out.println(" " + "[M]ultiplication");
System.out.println(" " + "[D]ivision");
System.out.println(" " + "[R]emainder");
System.out.print("Enter your choice:" + " ");
String operationType = stdin.nextLine();
for (int count = 0; count < Config.NUMBER_OF_QUESTIONS; count++) {
//codes
if (operationType.equalsIgnoreCase("a")) {
Might be better to use a switch statement for checking the operationType too.

Why does not this for-loop work?

Help, please.
This code does't work:
for (i = 0; i == userWhoIsInLineArray.GetNumberOfUsersOnline() - 1; i++) {
Log.d("DATA-----|", "UserName- "
+ userWhoIsInLineArray.GetUserName(i)
+ " UserHref- "
+ userWhoIsInLineArray.GetUserAccountHref(i));
}
When I write this one, all work!
while(i != userWhoIsInLineArray.GetNumberOfUsersOnline() - 1) {
Log.d("DATA-----|", "UserName- "
+ userWhoIsInLineArray.GetUserName(i)
+ " UserHref- "
+ userWhoIsInLineArray.GetUserAccountHref(i));
i++;
}
Why is happening?
I doubt you meant to use equality in your for loop test for continuance?
This bit:
i == userWhoIsInLineArray.GetNumberOfUsersOnline()-1
Perhaps you meant another comparison operator?
You should write as:
for (i = 0; i < userWhoIsInLineArray.GetNumberOfUsersOnline(); i++) {
Log.d("DATA-----|", "UserName- "
+ userWhoIsInLineArray.GetUserName(i)
+ " UserHref- "
+ userWhoIsInLineArray.GetUserAccountHref(i));
}
Only when the second sentence of for-clause is true, for-block is executed. So, when the variable i is smaller than userWhoIsInLineArray.GetNumberOfUsersOnline(), it must be true.
cf 1. i == userWhoIsInLineArray.GetNumberOfUsersOnline() means only when variable i equals userWhoIsInLineArray.GetNumberOfUsersOnline() it is true. Unless userWhoIsInLineArray.GetNumberOfUsersOnline() is 0, it results false for the first loop.
cf 2. In the same sence your while-loop is better to rewrite as:
int i = 0;
while (i < userWhoIsInLineArray.GetNumberOfUsersOnline()) {
Log.d("DATA-----|", "UserName- "
+ userWhoIsInLineArray.GetUserName(i)
+ " UserHref- "
+ userWhoIsInLineArray.GetUserAccountHref(i));
i++;
}

Vigenere Cypher Program in C

This program is supposed to crypt a certain message with the vigenere cypher. The program is supposed to be 'case sensitive' both the message and the keyword. If the program encounters any special characters or numbers, is also supposed to print them untouched.
The last part seems to be working, and the rest, even though the math seems to be right, it doesn't print as it's supposed to. I'm also converting the ASCII values to A-Z/0-26, doing the cypher formula, and them converting them back to ASCII.
// key validation
string kw = argv[1];
int kwl = strlen(kw);
for (int i = 0; i < kwl; i++)
{
if (!isalpha(kw[i]))
{
printf("Usage: ./vigenere keyword\n");
return 1;
}
}
// get message and length
string mssg;
mssg = GetString();
int lngth = strlen(mssg);
// cryptography
int k = 0;
for (int j = 0; j < lngth; j++)
{
if (isalpha(mssg[j]))
{
if (islower(mssg[j]))
{
if (islower(kw[k % kwl]))
printf("%c", (((mssg[j] - 97) + (kw[k % kwl] - 97)) & 26) + 97);
else
printf("%c", (((mssg[j] - 97) + (kw[k % kwl] - 65)) & 26) + 97);
k++;
}
else if (isupper(mssg[j]))
{
if (isupper(kw[k % kwl]))
printf("%c", (((mssg[j] - 65) + (kw[k % kwl] - 65)) & 26) + 65);
else
printf("%c", (((mssg[j] - 65) + (kw[k % kwl] - 97)) & 26) + 65);
k++;
}
}
else
printf("%c", mssg[j]);
}
printf("\n");
return 0;
}
I'm still getting an error somewhere on the math
The error is that you have & 26 instead of % 26.

Usage of dynamic memory management functions causing crashes [closed]

This question is unlikely to help any future visitors; it is only relevant to a small geographic area, a specific moment in time, or an extraordinarily narrow situation that is not generally applicable to the worldwide audience of the internet. For help making this question more broadly applicable, visit the help center.
Closed 10 years ago.
I've recently uptaken rewriting argument handling code I began to create, and I've added utilization of dynamic memory management functions (malloc, realloc, free), but after adding such I am getting strange crashes when I attempt to execute an example.
The following is output from my program:
charles#draton-generico:~/Documents/C/C89/SDL_Work/2D-game-base$ ./game-base-02-alt-2 --l
Successfully exited argument catching loop.
==>Continuing execution.
* glibc detected ./game-base-02-alt-2: realloc(): invalid next size: 0x000000000157c010 **
After outputting this much it just hangs.
The following is my code:
/*
* CREATED BY: Charles Edwin Swain 3rd
* DATE OF PROJECT BEGINNING: 28/1/2013
*/
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char** argv)
{
int* bse = malloc(3 + 5 + 5 + argc);
if (bse == NULL)
{
if (fprintf(stderr, "Call to malloc failed, bse = NULL.\n==>Will now exit.\n") <= 0) exit(-2);
exit(-1);
}
*(bse + 0) = 0;
while (*(bse + 0) < (3 + 5 + 5 + argc))
{
*(bse + *(bse + 0)) = 0;
*(bse + 0) = *(bse + 0) + 1;
}
*(bse + 0) = 0;
*(bse + 1) = -1;
/*THIS DETERMINES THE SIZE OF THE LARGEST ARGV CHARACTER STRING.*/
while (*(bse + 3) < argc)
{
while (*(bse + 4) != -1)
{
if (argv[*(bse + 3)][*(bse + 4)] == '\0')
{
if ((*(bse + 4) + 1) > *(bse + 5)) *(bse + 5) = *(bse + 4) + 1;
*(bse + 4) = -1;
}
else if (*(bse + 4) == 32766)
{
*(bse + 3 + 5 + 5 + *(bse + 3)) = 1;
*(bse + 4) = -1;
}
else *(bse + 4) = *(bse + 4) + 1;
}
*(bse + 3) = *(bse + 3) + 1;
*(bse + 4) = 0;
}
*(bse + 3) = 0;
/*ENSURING THAT SPACE FOR RETREIVED ARGV CHARACTER STRINGS IS AT LEAST THE SIZE OF THE LARGEST CHECKED FOR SPECIFIC STRING ON LINE BELOW.*/
if (*(bse + 5) < 10) *(bse + 5) = 10;
/*THIS IS (IN SOME CASES WAS) THE BIG ARGV CATCHING LOOP.*/
/*ERASED CONTENTS OF, AM REWRITING CODE.*/
while (*(bse + 3) < argc)
{
*(bse + 3) = argc;
}
if (fprintf(stdout, "Successfully exited argument catching loop.\n==>Continuing execution.\n") <= 0)
{
while ((*(bse + 1) <= 0)&&(*(bse + 2) < 50))
{
*(bse + 1) = fprintf(stderr, "A function (fprintf) failed when outputting a notification informing of having 'properly' left the argument catching loop.\n==>Will now exit.\n");
*(bse + 2) = *(bse + 2) + 1;
}
free(bse);
exit(-1);
}
/*SET DEFAULTS HERE*/
bse = realloc(bse, 3);
if (bse == NULL)
{
if (fprintf(stderr, "Call to realloc failed, bse = NULL.\n==>Will now exit.\n") <= 0) exit(-2);
exit(-1);
}
/*END OF CODE.*/
free(bse);
exit(0);
}
I'd love to turn this into a learning experience.
malloc() and realloc() have no idea about what kind of data type you're going to store in the memory pointed to by the returned pointers. So they just allocate some bytes - and they don't magically multiply their arguments by sizeof(int). So what you want is:
int *bse = malloc((3 + 5 + 5 + argc) * sizeof(*bse));
and the alike with realloc().

Resources