Why this weird infinite loop occuring? - loops

I'm writing a arduino serial communication code where I'll send sentence through serial communication like "azyb"+sentence+"byza" where first and second part is to identify my sentence is going to begin and end . My code is here (just giving the loop function as other's working fine) :
void loop()
{
if (Serial.available() > 0)
{
int i=0, j=0, len=0;
char *sentance;
String line = Serial.readString();
len = line.length();
Serial.println(len);
Serial.println(line);
for (; i < len; i++)
if (line[i] == 'a' && line[i+1] == 'z' && line[i+2] == 'y' && line[i+3] == 'b'){
//first if
Serial.println("First");
i += 4;
while (i < len){
sentance[j] = line[i];
i++; j++;
if (line[i+1] == 'b' && line[i+2] == 'y' && line[i+3] == 'z' && line[i+4] == 'a'){
// second IF
Serial.println("Second");
sentance[j] = 'NULL';
encry_flag = true;
i = i + 4;
line = "";
break;
}
}
}
if (!encry_flag){
Serial.println("No code is send");
Write_text("damn "); // to write text in OLED display
}
else{
Serial.println(sentance);
Write_text(sentance); // to disply sentence in OLED display
encry_flag = false;
}
// clear the buffer
while (Serial.available() > 0)
char c= Serial.read();
}
}
But when I send a valid sentence like "azybanklonbyza" which will display "anklon" in OLED display , the code get trapped into a infinite loop which goes till first if condition came true but never run till the second if condition came true,and then circle back which should not be acting like this.
this infinite loop do not check the condition either encry_flag is true or false and never goes to the statement where buffer is being cleared.
From the screenshot you can understand that the for loop and the while loop within the for loop breaks as total strings is printed again and again which is done only once before for loop.
From where this infinite loop is created ? I'm totally lost.
FYI : if "azyb" and "byza" is not added at the beginning and end , the code ran just fine as it never fulfill any if condition. I tried using one character also ( "azybhbyza" to print "h" ) , but the result is same .

I am not familiar with arduino but
if (line[i+1] == 'b' && line[i+2] == 'y' && line[i+3] == 'z' && line[i+4] == 'a')
Should it not start with i ? And I see you used a character pointer "sentance" but you have not initialized it anywhere and as far as I know. The uninitialized pointer might lead to memory corruption depending on compiler memory management. Depending on hardware memory I am also considering the fact that it may corrupt some other memory contents also. Which may explain your variable "i" not reaching the end. Try initializing sentance with some space like
sentance = new char[25];
It may work. And also if you are testing on hardware, it may behave freaky at times.

Related

change output from character array

Once again i find myself relatively lost and seeking knowledge from my peers.
What I am needing to do is to write a program that takes in an encoded language that adds the leters 'u' 't' after ever consonant and output into english. So the input Hutelutluto would be outputted as hello. At first I thought i had it figured out, but then my professor said i had to store the initial input in a character array and display it. Then use that character array to output the modified translation.
I have tried several different angles, one trying to modify my readstring function to fit my modification parameters. It always ends up becoming a mess and giving me unexpected outputs.
Essentially I believe that I need help feeding the character array into the while loop, but when I try I get an error stating that i have a pointer comparison to integer error.
Here is my edition of my code where i believe I was the closest to solving the problem. At the moment the while works independently from the readstring function. I am sure I am overthinking the problem, but i just not sure how to work out the kinks.
:
/*
Tut language
By: Steven
*/
# include <stdio.h>
void readstring(char *, int);
int main (void){
char input [50];
char output;
char trash;
//initiation
printf("\n\t*Hi! Welcome to the assemble of Tut*\n");
printf("I can help you decode/encode a message to and from the code called Tut!\n");
printf("Enter a sentence to be translated frome Tut - English: ");
readstring(input, 50);
printf("Your Tut sencence is: %s \n",input);
while (output != '\n') {
output = getchar();
if(output == '\n'){//escape sequence
break;
}
if((output != 'a') && (output != 'e') && (output != 'i') && (output != 'o') && (output != 'u') && (output != 'y') && (output != ' ')){
putchar(output);
trash = getchar();
trash = getchar();
}else{
putchar(output);
}
}
return 0;
}// end main
//function lists start
void readstring(char * buffer, int size) {
int x;
char c = getchar( );
if( c == '\n' ) {
c = getchar( );
}
for(x = 0 ; (x < (size-1)) && c != '\n' ; x++) {
buffer[x] = c;
c = getchar( );
}
buffer[x] = '\0';
}
Any help or feedback will be greatly appreciated!
Thank your for your time!
p.s.
After taking your advice into consideration i edited my code, but it seems as if it is ignoring all input after the first. I even tried changing the !='\n' condition to just i < 50, but i got the same results.
Line of code after taking Tim's advice:
for (i = 0; input [i] != '\n'; ++i){
output = input[i];
if((output != 'a') && (output != 'e') && (output != 'i') && (output != 'o') && (output != 'u') && (output != 'y') && (output != ' ')){
putchar(output);
trash = getchar();
trash = getchar();
}else{
putchar(output);
}
}
The main problem is in your while loop. In this loop, you are using getchar, which tries to read from stdin. However, you have already read your input, and it is stored in buffer.
So, you should get your characters from buffer instead of reading them again.
Your readstring function already calls getchar to read characters from the user's terminal, so you should not need to call it again after readstring is done. Instead, use a for loop to set output to each character of the input string in turn:
int i;
for i = 0; input[i] != '\n'; ++i {
output = input[i]
if((output != 'a') && (output != 'e') && (output != 'i') && (output != 'o') && (output != 'u') && (output != 'y') && (output != ' ')){
...
… in a character array, i have no idea how I am going to skip
those next two character?
You skip characters by incrementing the array index. Change
trash = getchar();
trash = getchar();
to
input[++i] && input[++i] || --i; // step back if at end of string
Also, since the input string is terminated by \0 rather than \n, change
for (i = 0; input [i] != '\n'; ++i){
to
for (i = 0; input[i]; ++i)
{

Reading in from file in a certain format in C produces seg fault

Currently, I'm trying to read in numbers from a file that represent the solution to a Sudoku Puzzle. The file is supposed to be formatted as 9 numbers, with no spaces between, followed by a newline character, ending after the eighty-first number.
While reading in, I'm using fscanf, I can get it to work with a valid puzzle, but not with one that's not a valid format; those produce a segmentation fault. I tried to check the length of the array, but since it's set to 10 when I declared s, that doesn't catch strings that are too short or too long. am I going about this the wrong way? I'll post the code below.
FILE* puzzlefile;
char s[10];
int i=0, j=0, skip;
int form;
//opens the file so we can access the puzzle
puzzlefile = fopen(argv[1], "r");
for (i=0; i<9; i++){
form = fscanf(puzzlefile, "%s\n",s);
for (j=0; j<10; j++){
if (form == 0){
printf("Invalid format on input. Bad newline.\n");
return 1;
}
if(j<9){
if(s[j] == '1' || s[j] == '2' || s[j] == '3' || s[j] == '4' || s[j] == '5' || s[j] == '6' || s[j] == '7' || s[j] == '8' || s[j] == '9'){
puzzle[i][j] = (int)(s[j]-'0');
}
else{
printf("Invalid format on input.\n");
return 1;
}
}
}
}
Am I going about this the wrong way? If so, am I just misusing fscanf()? Or should I be using another type of input function? The files I'm testing include some that follow the format but with letters instead of numbers, one puzzle with an extra number on the first line, one puzzle that has newlines every 5 numbers, and one that is all numbers and no newlines. All of these produce a seg fault.
You don't check puzzlefile for NULL, you should ensure that the file was opened, in case it wasn't fopen() returns NULL, so checking the return value of fopen() as a very important thing to do.
You don't seem to check if argv[1] != NULL which would happen if you forget to pass arguments to the program, the consequences would be the program malfunctioning and you will recieve no clue of why.
The size of s is too small, and it's easy to overflow it, make fscanf() aware of how much space is there for the destination string, like this
form = fscanf(puzzlefile, "%9s\n", s);
/* ^ 9 characters + '\0' = 10 */
To prevent reading past the end of the string do this
for (i = 0 ; s[i] != '\0' ; ++i)
instead of
for (i=0; i<10; i++)
and the same with the inner loop.
It would be much better if you do this
if ((s[j] > '0') && (s[j] < 1 + '9'))
instead of
if(s[j] == '1' || s[j] == '2' || s[j] == '3' || s[j] == '4' || s[j] == '5' || s[j] == '6' || s[j] == '7' || s[j] == '8' || s[j] == '9')
You didn't post the declaration of puzzle, it could also be the problem if you are writing after it's end, you should be very careful with bound checking in c because writing past the end of a buffer, doesn not have a defined behavior, and in some situations nothing bad will happen when you test it, and of course the bug will stay silently there until it explodes.

C - getchar() producing erroneous output

I'm writing a program for my computing class that scores a tennis match. The program takes inputs for teams as 'A' and 'B' for teams, and 'S' to print the score out. It works fine until it gets to the deuce function.
The problem I'm having is that multiple inputs at one time break the program. So once the deuce has started, input of: 'A, Enter, B, Enter, B, Enter', works fine, but 'A, B, B, Enter' breaks it. Unfortunately the auto-marker at uni just shoves long strings of characters at it. This also makes it hard to test because I can't see what is happening at each stage of input.
I've got a while loop trying to consume some of the extra characters I was getting, but it's still not quite right. I've had problems before where an input of 'A' will output 'AA', I think it's something similar.
I'm just learning so I'm sure I just misunderstand how to use the getchar() function. Also I know there are parts of my code that could be simpler, but it's due really soon and I haven't had, and probably won't have, time to optimise it properly.
Thanks for any help!!!
EDIT: Sorry, reading back on my question I can see I worded it quite badly. It doesn't ever 'break' and -Wall gives no errors or warnings, it just gives the wrong output. For example, the input 'ABB' should go like this:
A: The program thinks that A has the advantage.
B: The program thinks that B has equalised, so the deuce restarts.
B: B should now have the advantage.
(If I hit 'Enter' after every input, the above output is exactly what happens.)
But if 'ABB' is typed in all at once, and then 'Enter' is pressed it exits the deuce function entirely, thinking that 'B' has won the deuce and keeps going with the normal tennis match. So I think what is happening is that an extra 'B' is being passed through the while loop.
void deuce ( int data_array[], int set_tally[], int team_select ){
int A_deuce_points = 0;
int B_deuce_points = 0;
int server = data_array[data_array[8]];
int ch = 0;
int winner = 0;
while ( A_deuce_points < 2 && B_deuce_points < 2){ // needs to be &&
ch = getchar();
printf("ch = %d\n", ch);
while ( ch == 10 || ch == -1 || ch == '\n' ){
ch = getchar();
}
if ( ch == 'A' ){
A_deuce_points++;
}
else if (ch == 'B'){
B_deuce_points++;
}
else if (ch == 'S' ){
printf("Team %c to serve:\n", server);
if ( server == 'A' ){
// Print sets
winner = server;
print_completed_sets( set_tally, winner );
// Print games
printf("%d-%d\n", data_array[4], data_array[5]);
if(A_deuce_points == B_deuce_points ){
printf("Deuce\n");
A_deuce_points = 0;
B_deuce_points = 0;
}
if(A_deuce_points - B_deuce_points == 1 ){
printf("Advantage Server\n");
}
if(B_deuce_points - A_deuce_points == 1 ){
printf("Advantage Receiver\n");
}
}
else if ( server == 'B' ){
// Print sets
winner = server;
print_completed_sets( set_tally, winner );
// Print games
printf("%d-%d\n", data_array[5], data_array[4]);
if(A_deuce_points == B_deuce_points ){
printf("Deuce\n");
A_deuce_points = 0;
B_deuce_points = 0;
}
if(B_deuce_points - A_deuce_points == 1 ){
printf("Advantage Server\n");
}
if(A_deuce_points - B_deuce_points == 1 ){
printf("Advantage Receiver\n");
}
}
}
}// end while loop
if ( A_deuce_points == 2 ){
data_array[4]++;
}
else if ( B_deuce_points == 2 ){
data_array[5]++;
}
data_array[2] = 0;
data_array[3] = 0;
A_deuce_points = 0;
B_deuce_points = 0;
change_serve( data_array);
}

Can't assign value to a variable inside a for loop

Here is what I want to do:
Read all characters from a '.c' file and store that into an array.
When a character from that array is '{', it will be pushed into a stack. And count of pushed characters will be increased by 1.
When a character from that array is '}', stack will pop and the count of popped characters will be increased by 1.
Compare those two counts to check whether there is a missing '{' or '}'
Here is my code:
int getLinesSyntax(char s[], int limit, FILE *cfile)
{
int i, c, push_count = 0, pop_count = 0;
int state = CODE;
int brackets[limit];
char braces[limit];
for(i = 0; i < 100; i++)
{
braces[i] = 0;
}
for(i = 0; i < limit - 1 && (c = getc(cfile)) != EOF && c != '\n'; i++)
{
s[i] = c;
if(s[i] == '{')
{
braces[0] = s[i];
//push(s[i], braces);
++push_count;
}
else if(s[i] == '}')
{
pop(braces);
++pop_count;
}
}
//Mor shiljih uyed array -n togsgold 0-g zalgana
if(c == '\n')
{
s[i] = c;
i++;
}
s[i] = '\0';
i = i -1; //Suuld zalgasan 0 -g toonoos hasna
if(c == EOF)
{
//just checking
for(i = 0; i < 100; i++)
{
printf("%d", braces[i]);
}
if(push_count != pop_count)
{
printf("%d and %d syntax error: braces", push_count, pop_count);
}
return -1;
}
else
{
return i;
}
}
Here is the output
0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
The problems is:
Assignments inside the for loop is not working. (It's working when I put that outside of the loop)
I would like to know if there's something wrong with my code :).
There are several problems.
Lets go through it step by step
1) Your array initialization loop:
int brackets[limit];
char braces[limit];
for(i = 0; i < 100; i++)
{
braces[i] = 0;
}
You declare the array having size of limit but only initialize 100 items. Change 100 to limit to fully initialize it depending on the parameter of the function.
2) The conditional statement of the main for loop:
i < limit - 1 && (c = getc(cfile)) != EOF && c != '\n'
Although the first substatement is correct I have two remarks:
Firstly (c = getc(cfile)) != EOF might be one reason why the loop is never accessed and still everything is 000000.... Check if the file exists, the pointer is not NULL or other silent errors occured.
Secondly the c != '\n'. What if one of these characters occurs? In this case you won't continue with the next iteration but break out of the entire forloop. Remove it there and put it in the first line of the body like this:
if(c == '\n')
{
i -= 1; // to really skip the character and maintain the index.
continue;
}
3) s[i] = c;
Can you be certain, that the array is indeed sizeof limit?
4) Checking for curly braces
if(s[i] == '{')
{
braces[0] = s[i];
//push(s[i], braces);
++push_count;
}
else if(s[i] == '}')
{
pop(braces);
++pop_count;
}
You assign to braces[0] always, why?
5) Uninitialized access
if(c == '\n')
{
s[i] = c;
i++;
}
s[i] = '\0';
i = i -1; //Suuld zalgasan 0 -g toonoos hasna
You're now using the function-global variable i, which is never initialized properly for this block. What you do is to use a variable that is used basically everywhere ( which is basically also no problem from the memory point of view. ), but you rely on legacy values. Is this done by purpose? If no, reinitialize i properly. I have to ask this since i can't read your comments in code.
What I'm quite unhappy about is that you entirely rely on one variable in all the loops and statements. Usually a loop-index should never be altered from inside. Maybe you can come up with a cleaner design of the function like an additional index variable you parallelly increase without altering i. The additional index will be used for array access where appropriate whereas i really remains just a counter.
I think the problem is in this condition "c != '\n'" which is breaking the for loop right after the first line, before it reaches any brackets. And hence the output.
For the task of counting whether there are balanced braces in the data, the code is excessively complex. You could simply use:
int l_brace = 0;
int r_brace = 0;
int c;
while ((c = getchar()) != EOF)
{
if (c == '{')
l_brace++;
else if (c == '}')
r_brace++;
}
if (l_brace != r_brace)
printf("Number of { = %d; number of } = %d\n", l_brace, r_brace);
Of course, this can be confused by code such as:
/* This is a comment with an { in it */
char string[] = "{{{";
char c = '{';
There are no braces that mark control-of-flow statement grouping in that fragment, for all there are 5 left braces ({) in the source code. Parsing C properly is hard work.

While loop printing twice during one loop

So I have this little while loop which seems to print out my text twice during one run.
So here is the code:
int main(void){
char cont;
int check = 1;
while(check == 1){
printf("Something");
cont = getchar();
if(cont == 'j')
check = 1;
}
}
Now the output of this is:
Something, now it waits for input
Something, Something and waits for input.
After the first print, it will print twice when I press j.
Why is that?
You press 'j' and the 'newline', so you typed two chars and loop executes twice before starting to read next line.
Your code is stuck in loop because you test check==1 and check is always 1
you can make else part
if(cont == 'j')
check = 1;
else
check =0;
It is an infinite loop. Always recheck your program.
Maybe you wanted
if(cont == 'j')
check = 0;

Resources