How do I handle the newline, and separator spacing in c? - c

The actual text file is just random stuff to test the lex and parse. The pic above is the result, the console is giving me during runtime. In the green it is calling an Identifier when it should be a newline or delim, so nothing should be needed. In the red it is not recognizing the separator, and in the yellow its not reading the something.something at all. I'm assuming it has something to do with with the previous c; not being seperated right.
So my question is how do I properly separate the tokens, and recognize the newline, or what am I doing wrong. Below is the code that I am using to do the separating and tokenizing.
#define _CRT_SECURE_NO_WARNINGS
#include <stdbool.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define BUFFER_SIZE 1024
// Returns 'true' if the character is a DELIMITER.
bool isDelimiter(char ch)
{
if (isspace (ch))
return (true);
return (false);
}
// Returns 'true' if the character is a SEPERATOR.
bool isSeperator(char str)
{
if (str == ',' || str == ';' || str == '>' ||
str == '<' || str == '(' || str == ')' || str == '[' || str == ']' ||
str == '{' || str == '}' || str == '.' )
return (true);
return (false);
}
// Returns 'true' if the character is an OPERATOR.
bool isOperator(char ch)
{
if (ch == '+' || ch == '-' || ch == '*' ||
ch == '/' || ch == '>' || ch == '<' ||
ch == '=')
return (true);
return (false);
}
// Returns 'true' if the string is a VALID IDENTIFIER.
bool validIdentifier(char* str)
{
if (str[0] == '0' || str[0] == '1' || str[0] == '2' ||
str[0] == '3' || str[0] == '4' || str[0] == '5' ||
str[0] == '6' || str[0] == '7' || str[0] == '8' ||
str[0] == '9' )
return (false);
return (true);
}
// Returns 'true' if the string is a KEYWORD.
bool isKeyword(char* str)
{
if (!strcmp(str, "if") || !strcmp(str, "else") ||
!strcmp(str, "while") || !strcmp(str, "do") ||
!strcmp(str, "break") || !strcmp(str, "elem") ||
!strcmp(str, "lout") || !strcmp(str, "file") ||
!strcmp(str, "console") || !strcmp(str, "read") ||
!strcmp(str, "write") || !strcmp(str, "mark") ||
!strcmp(str, "emblemnize") || !strcmp(str, "lin") ||
!strcmp(str, "send") || !strcmp(str, "dint") ||
!strcmp(str, "continue") || !strcmp(str, "int")
|| !strcmp(str, "double") || !strcmp(str, "float")
|| !strcmp(str, "return") || !strcmp(str, "char")
|| !strcmp(str, "case") || !strcmp(str, "char")
|| !strcmp(str, "sizeof") || !strcmp(str, "long")
|| !strcmp(str, "short") || !strcmp(str, "typedef")
|| !strcmp(str, "switch") || !strcmp(str, "unsigned")
|| !strcmp(str, "void") || !strcmp(str, "static")
|| !strcmp(str, "struct") || !strcmp(str, "goto"))
return (true);
return (false);
}
// Returns 'true' if the string is an INTEGER.
bool isInteger(char* str)
{
int i, len = strlen(str);
if (len == 0)
return (false);
for (i = 0; i < len; i++) {
if (str[i] != '0' && str[i] != '1' && str[i] != '2'
&& str[i] != '3' && str[i] != '4' && str[i] != '5'
&& str[i] != '6' && str[i] != '7' && str[i] != '8'
&& str[i] != '9' || (str[i] == '-' && i > 0))
return (false);
}
return (true);
}
// Returns 'true' if the string is a REAL NUMBER.
bool isRealNumber(char* str)
{
int i, len = strlen(str);
bool hasDecimal = false;
if (len == 0)
return (false);
for (i = 0; i < len; i++) {
if (str[i] != '0' && str[i] != '1' && str[i] != '2'
&& str[i] != '3' && str[i] != '4' && str[i] != '5'
&& str[i] != '6' && str[i] != '7' && str[i] != '8'
&& str[i] != '9' && str[i] != '.' ||
(str[i] == '-' && i > 0))
return (false);
if (str[i] == '.')
hasDecimal = true;
}
return (hasDecimal);
}
// Extracts the SUBSTRING.
char* subString(char* str, int left, int right)
{
int i;
char* subStr = (char*)malloc(sizeof(char) * (right - left + 2));
for (i = left; i <= right; i++)
subStr[i - left] = str[i];
subStr[right - left + 1] = '\0';
return (subStr);
}
// Parsing the input STRING.
void parse(char* str)
{
int left = 0, right = 0;
int len = strlen(str);
while (right <= len && left <= right)
{
if (isDelimiter(str[right]) == false)
right++;
if (isDelimiter(str[right]) == true && left == right)
{
if (isOperator(str[right]) == true)
printf("'%c' IS A OPERATOR\n", str[right]);
right++;
left = right;
}
if (isDelimiter(str[right]) == true && left == right)
{
if (isDelimiter(str[right]) == true)
printf("'%c' IS A DELIMITER\n", str[right]);
right++;
left = right;
}
if (isSeperator(str[right]) == true && left == right)
{
//needed to recognize seperator to the right
if (isSeperator(str[right]) == true)
printf("'%c' IS A SEPERATOR\n", str[right]);
right++;
left = right;
//needed to recognize seperator to the left
if (isSeperator(str[right]) == true)
printf("'%c' IS A SEPERATOR\n", str[left]);
right++;
left = right;
}
else if (isDelimiter(str[right]) == true && left != right
|| (right == len && left != right)) {
char* subStr = subString(str, left, right - 1);
if (isKeyword(subStr) == true)
printf("'%s' IS A KEYWORD\n", subStr);
else if (isInteger(subStr) == true)
printf("'%s' IS AN INTEGER\n", subStr);
else if (isRealNumber(subStr) == true)
printf("'%s' IS A REAL NUMBER\n", subStr);
else if (validIdentifier(subStr) == true
&& isDelimiter(str[right - 1]) == false
&& isSeperator(str[right - 1]) == false)
printf("'%s' IS A VALID IDENTIFIER\n", subStr);
left = right;
}
}
return;
}
int main(int argc, char *argv)
{
/* declare a file pointer */
FILE *file;
char *buffer;
long numbytes;
/* open an existing file for reading */
file = fopen("Text.txt", "r");
/* quit if the file does not exist */
if (file == NULL)
return 1;
/* Get the number of bytes */
fseek(file, 0L, SEEK_END);
numbytes = ftell(file);
/* reset the file position indicator to
the beginning of the file */
fseek(file, 0L, SEEK_SET);
/* grab sufficient memory for the
buffer to hold the text */
buffer = (char*)calloc(numbytes, sizeof(char));
/* memory error */
if (buffer == NULL)
return 1;
/* copy all the text into the buffer */
fread(buffer, sizeof(char), numbytes, file);
/* confirm we have read the file by
outputing it to the console */
printf(" The file called Text.txt contains this text \n \n %s \n\n", buffer);
parse(buffer); // calling the parse function
fclose(file);
/* free the memory we used for the buffer */
free(buffer);
return 0;
}

Looks like the problem is your isDelimiter function isn't picking up all possible values. If you change it to use isspace() it will match on all forms of whitespace.
bool isDelimiter(char ch)
{
if (isspace(ch))
return (true);
return (false);
}
As an example, here is a very simple state machine to give you an idea of what sort of thing I meant. It can be in either of one of two states - INSIDE_IDENTIFIER or OUTSIDE_IDENTIFIER - and it switches between those two states depending on what kind of character it is looking at.
#define OUTSIDE_IDENTIFIER (0)
#define INSIDE_IDENTIFIER (1)
void parse(char *str)
{
char *ch;
int state=OUTSIDE_IDENTIFIER;
char buffer[1000];
char *pos=buffer;
for(ch=str;*ch!='\0';ch++)
{
switch(state)
{
case INSIDE_IDENTIFIER:
if(isOperator(*ch))
{
*pos='\0';
printf("Identifier[%s]\n",buffer);
printf("Operator[%c]\n",*ch);
state=OUTSIDE_IDENTIFIER;
}
else if(isDelimiter(*ch))
{
*pos='\0';
printf("Identifier[%s]\n",buffer);
printf("Delimiter[%c]\n",*ch);
state=OUTSIDE_IDENTIFIER;
}
else if(isspace(*ch))
{
*pos='\0';
printf("Identifier[%s]\n",buffer);
printf("Space[%d]\n",*ch);
state=OUTSIDE_IDENTIFIER;
}
else
{
*pos=*ch;
pos++;
}
break;
case OUTSIDE_IDENTIFIER:
default:
if(isOperator(*ch))
{
printf("Operator[%c]\n",*ch);
}
else if(isDelimiter(*ch))
{
printf("Delimiter[%c]\n",*ch);
}
else if(isSeperator(*ch))
{
printf("Seperator[%c]\n",*ch);
}
else
{
state = INSIDE_IDENTIFIER;
pos=buffer;
*pos=*ch;
pos++;
}
break;
}
}
}

Related

Some Errors in my X and O game ( C language)

What I'm trying to do here is a tie toe game, but when my code enters the do - while part, it ends the process by itself. Since I could not solve this part, I did not have a chance to try whether there are other problems with the code, unfortunately, I would be glad if you could help with this issue.
#include <stdio.h>
#include <string.h>
#include <stdbool.h>
char box_area[] = { '0','1','2','3','4','5','6','7','8','9' };
struct Player {
bool turn;
char mark;
int ID;
};
int main()
{
int return_result;
int player_number;
struct Player player1;
struct Player player2;
struct Player users[2];
users[0] = player1;
users[1] = player2;
(player1.mark = 'X') && (player2.mark = 'O');
(player1.turn = true) && (player2.turn = false);
(player1.ID = 1) && (player2.ID = 2);
do
{
box_creat();
for (int i = 0; i < 2; i++) {
if (users[i].turn == true)
{
make_move(users[i].ID);
box_creat();
users[i].turn = false;
users[i + 1].turn = true; \\ I made the logic of this section wrong
\\I will try to fix it, I realized after I sent the question
}
}
return_result = check_the_winner();
} while (return_result == 1 || return_result == -1);
return 0;
}
void box_creat(void) {
printf("| %c | %c | %c |", box_area[0], box_area[1], box_area[2]);
printf("\n\n");
printf("| %c | %c | %c |", box_area[3], box_area[4], box_area[5]);
printf("\n\n");
printf("| %c | %c | %c |", box_area[6], box_area[7], box_area[8]);
}
void make_move(int Player_ID)
{
int choice;
printf("Please select a area between 0-9 ");
scanf("%d", choice);
if (choice == '0' && box_area[0] == '0')
{
if (Player_ID == 1) {
box_area[0] = 'X';
}
else {
box_area[0] = 'O';
}
}
else if (choice == '1' && box_area[1] == '1')
{
if (Player_ID == 1) {
box_area[1] = 'X';
}
else {
box_area[1] = 'O';
}
}
else if (choice == '2' && box_area[2] == '2')
{
if (Player_ID == 1) {
box_area[2] = 'X';
}
else {
box_area[2] = 'O';
}
}
else if (choice == '3' && box_area[3] == '0')
{
if (Player_ID == 1) {
box_area[3] = 'X';
}
else {
box_area[3] = 'O';
}
}
else if (choice == '4' && box_area[4] == '0')
{
if (Player_ID == 1) {
box_area[4] = 'X';
}
else {
box_area[4] = 'O';
}
}
else if (choice == '5' && box_area[5] == '0')
{
if (Player_ID == 1) {
box_area[5] = 'X';
}
else {
box_area[5] = 'O';
}
}
else if (choice == '6' && box_area[6] == '0')
{
if (Player_ID == 1) {
box_area[6] = 'X';
}
else {
box_area[6] = 'O';
}
}
else if (choice == '7' && box_area[7] == '0')
{
if (Player_ID == 1) {
box_area[7] = 'X';
}
else {
box_area[7] = 'O';
}
}
else if (choice == '8' && box_area[8] == '0')
{
if (Player_ID == 1) {
box_area[8] = 'X';
}
else {
box_area[8] = 'O';
}
}
}
int check_the_winner(void)
{
if (box_area[0] && box_area[1] && box_area[2] == 'X' || 'O') {
return 1;
}
else if(box_area[3] && box_area[4] && box_area[5] == 'X' || 'O') {
return 1;
}
else if (box_area[6] && box_area[7] && box_area[8] == 'X' || 'O') {
return 1;
}
else if (box_area[2] && box_area[4] && box_area[6] == 'X' || 'O') {
return 1;
}
else if (box_area[0] && box_area[3] && box_area[6] == 'X' || 'O') {
return 1;
}
else if (box_area[2] && box_area[8] && box_area[5] == 'X' || 'O') {
return 1;
}
else if (box_area[0] && box_area[4] && box_area[8] == 'X' || 'O') {
return 1;
}
else if (box_area[1] && box_area[4] && box_area[7] == 'X' || 'O') {
return 1;
}
else {
return -1;
}
}
I tried out your program and found a few glitches that needed revision as well as adding in some additional bits of code just to neaten things up a bit. Following is your code with those revisions.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
char box_area[] = { '0','1','2','3','4','5','6','7','8','9' };
struct Player
{
bool turn;
char mark;
int ID;
};
void box_creat(void)
{
printf("| %c | %c | %c |", box_area[0], box_area[1], box_area[2]);
printf("\n\n");
printf("| %c | %c | %c |", box_area[3], box_area[4], box_area[5]);
printf("\n\n");
printf("| %c | %c | %c |", box_area[6], box_area[7], box_area[8]);
printf("\n"); /* Added for aesthetics */
}
void make_move(int Player_ID)
{
int choice;
printf("Player %d - please select a area between 0-9 ", Player_ID);
scanf("%d", &choice); /* Corrected missing ampersand */
printf("Player: %d makes a move\n", Player_ID);
if (choice == 0 && box_area[0] == '0') /* FYI - '0' is equivalent to integer value 48 */
{
if (Player_ID == 1)
{
box_area[0] = 'X';
}
else
{
box_area[0] = 'O';
}
}
else if (choice == 1 && box_area[1] == '1')
{
if (Player_ID == 1)
{
box_area[1] = 'X';
}
else
{
box_area[1] = 'O';
}
}
else if (choice == 2 && box_area[2] == '2')
{
if (Player_ID == 1)
{
box_area[2] = 'X';
}
else
{
box_area[2] = 'O';
}
}
else if (choice == 3 && box_area[3] == '3')
{
if (Player_ID == 1)
{
box_area[3] = 'X';
}
else
{
box_area[3] = 'O';
}
}
else if (choice == 4 && box_area[4] == '4')
{
if (Player_ID == 1)
{
box_area[4] = 'X';
}
else
{
box_area[4] = 'O';
}
}
else if (choice == 5 && box_area[5] == '5')
{
if (Player_ID == 1)
{
box_area[5] = 'X';
}
else
{
box_area[5] = 'O';
}
}
else if (choice == 6 && box_area[6] == '6')
{
if (Player_ID == 1)
{
box_area[6] = 'X';
}
else
{
box_area[6] = 'O';
}
}
else if (choice == 7 && box_area[7] == '7')
{
if (Player_ID == 1)
{
box_area[7] = 'X';
}
else
{
box_area[7] = 'O';
}
}
else if (choice == 8 && box_area[8] == '8')
{
if (Player_ID == 1)
{
box_area[8] = 'X';
}
else
{
box_area[8] = 'O';
}
}
}
int check_the_winner(void)
{
if ((box_area[0] == box_area[1]) && (box_area[1] == box_area[2]) && (box_area[0] != '0')) /* Corrected the testing for proper "and" conditioning */
{
return 1;
}
else if ((box_area[3] == box_area[4]) && (box_area[4] == box_area[5]) && (box_area[3] != '3'))
{
return 1;
}
else if ((box_area[6] == box_area[7]) && (box_area[7] == box_area[8]) && (box_area[6] != '6'))
{
return 1;
}
else if ((box_area[2] == box_area[4]) && (box_area[4] == box_area[6]) && (box_area[2] != '2'))
{
return 1;
}
else if ((box_area[0] == box_area[3]) && (box_area[3] == box_area[6]) && (box_area[0] != '0'))
{
return 1;
}
else if ((box_area[2] == box_area[5]) && (box_area[5] == box_area[8]) && (box_area[2] != '2'))
{
return 1;
}
else if ((box_area[0] == box_area[4]) && (box_area[4] == box_area[8]) && (box_area[4] != '4'))
{
return 1;
}
else if ((box_area[1] == box_area[4]) && (box_area[4] == box_area[7]) && (box_area[1] != '1'))
{
return 1;
}
else
{
return -1;
}
}
int main()
{
int return_result;
//int player_number; /* Compiler said that this wasn't being used */
int swap = 1;
int i;
struct Player player1;
struct Player player2;
struct Player *users[2]; /* Used these as address pointers to player "1" and player "2" */
users[0] = &player1; /* Before making these pointers, the users array just contained copies of the player structures */
users[1] = &player2;
(player1.mark = 'X') && (player2.mark = 'O');
(player1.turn = true) && (player2.turn = false);
(player1.ID = 1) && (player2.ID = 2);
do
{
box_creat();
swap += 1;
i = swap % 2;
if (i == 1)
{
make_move(users[1]->ID);
//box_creat(); /* Being performed at the top of the loop */
users[0]->turn = false;
users[1]->turn = true;
}
else
{
make_move(users[0]->ID);
//box_creat();
users[1]->turn = false;
users[0]->turn = true;
}
return_result = check_the_winner();
if (check_the_winner() == 1) /* Added when a winner has been sensed */
{
box_creat();
if (i == 1)
{
printf("Player 2 won!\n");
}
else
{
printf("Player 1 won!\n");
}
}
}
while (return_result != 1);
return 0;
}
I added comments to most of the places I had tweaked, but here are the highlights:
I shuffled some of the functions around so that the "main" function followed all of the helper functions (the compiler was giving warnings about the original sequence of the function positions).
I corrected the "choice" tests as "choice" is an integer, so the test of "choice" needed to be compared to an integer value (e.g. zero) as opposed to character '0' (which actually has a value of 48).
The tests for three letters in a row for either player do not work in that manner. Either a test needed to be made for each box for a certain row needed to tested for an "X" or an "O", and then if that test was true the test needed to be continued for the next box in the row, and then again for the third box in the row. In lieu of that route, the test was revised to basically say "if the character in the first box in the row is the same as the character in the second box in the row, and the character in the second box in the row is the same as the character in the third box in the row, and the first box does not contain a digit character (which means is contains an "X" or an "O"), then there is a winner.
It appears that an attempt was made to mirror the contents of "Player1" and "Player2" into an array of player structures. Although initially, structure "users[0]" contained the same data as "Player1" and structure "users[1]" contained the same data as "Player2", once the data in "Player1" and "Player2" were updated, those changes did to propagate over to the "users" array. So to utilize "users" in the spirit of this program, they were defined as pointers to their respective player structures.
Those were the most significant bits. The other bits were added for a logical conclusion of the game. Note that no logic was added for a draw.
Give that a test and see if that clarifies things and follows the spirit of the project.

How to simplify large conditional statement

This conditional statement compares letters with numbers according to the keyboard of old button-phones.
In this statement, every if-else condition is the same. How can I shorten this piece of code?
//compares every name and pattern character
//every number represents some letters from latin alphabet
if(lowch >= 97 && lowch <= 99 && pattern[ptrch] == '2'){
ptrch++;
mir++;
}
else if(lowch >= 100 && lowch <= 102 && pattern[ptrch] == '3'){
ptrch++;
mir++;
}
else if(lowch >= 103 && lowch <= 105 && pattern[ptrch] == '4'){
ptrch++;
mir++;
}
else if(lowch >= 106 && lowch <= 108 && pattern[ptrch] == '5'){
ptrch++;
mir++;
}
else if(lowch >= 109 && lowch <= 111 && pattern[ptrch] == '6'){
ptrch++;
mir++;
}
else if(lowch >= 112 && lowch <= 115 && pattern[ptrch] == '7'){
ptrch++;
mir++;
}
else if(lowch >= 116 && lowch <= 118 && pattern[ptrch] == '8'){
ptrch++;
mir++;
}
else if(lowch >= 119 && lowch <= 122 && pattern[ptrch] == '9'){
ptrch++;
mir++;
}
else if(lowch == '+' && pattern[ptrch] == '0'){
ptrch++;
mir++;
}
else{
ptrch = 0;
mir = 0;
}
}
**ptrch- pattern char
*mir - matches in a row
Define a macro that encapsulates the comparisons, and then use a single condition with ||.
#define MATCH(start, end, ch) (lowch >= start && lowch <= end && pattern[ptrch] == ch)
if (MATCH('a', 'c', '2') ||
MATCH('d', 'f', '3') ||
MATCH('g', 'i', '4') ||
MATCH('j', 'l', '5') ||
MATCH('m', 'o', '6') ||
MATCH('p', 's', '7') ||
MATCH('t', 'v', '8') ||
MATCH('w', 'z', '9') ||
MATCH('+', '+', '0')) {
ptrch++;
mir++;
} else {
ptrch = 0;
mir = 0;
}
Another option would be to use an array of structures.
struct key {
char start,
char end,
char ch
} keys[] = {
{'a', 'c', '2'},
{'d', 'e', '2'},
...
{'+', '+', '0'}
};
bool found = false;
for (int i = 0; i < sizeof keys/sizeof keys[0]; i++) {
if (lowch >= keys[i].start && lowch <= keys[i].end && pattern[ptrch] == keys[i].ch) {
ptrch++;
mir++;
found = true;
break;
}
if (!found) {
ptrch = 0;
mir = 0;
}
A solution you might consider is to map the letters in an array.
// . . . . . . . . . . abcdefghijklmnopqrstuvwxyz
const char* numbers = "22233344455566677778889999";
char digit = (lowch >= 'a' && lowch <= 'z') ? numbers[lowch - 'a'] : 0;
if (digit == pattern[ptrch]) {
ptrch++;
mir++;
}
else if(lowch == '+' && pattern[ptrch] == '0') {
ptrch++;
mir++;
}
else {
ptrch = mir = 0;
}
Or (slightly overkill) you could build a full table to handle any character...
// Build the table once
char dialpad[1 << CHAR_BIT] = { 0 };
const unsigned char *map_from = "abcdefghijklmnopqrstuvwxyz+";
const char *map_to = "222333444555666777788899990";
for (int i = 0; map_from[i]; i++) dialpad[map_from[i]] = map_to[i];
// Later on...
if (dialpad[(unsigned char)lowch] == pattern[ptrch]) {
ptrch++;
mir++;
}
else {
ptrch = mir = 0;
}
All your characters (except the plus sign) are lower-case letters. In ASCII, these letters are in a contiguous range. You can therefore use an array to map lower-case letters to a number code:
// abcdefghijklmnopqrstuvwxyz
const char code[26] = "22233344455566677778889999";
if (lowch >= 'a' && lowch <= 'z' && code[lowch - 'a'] == pattern[ptrch]) {
ptrch++;
mir++;
} else if (lowch == '+' && pattern[ptrch] == '0') {
ptrch++;
mir++;
} else{
ptrch = 0;
mir = 0;
}
Before accessing the array, you must check whether lowch is a valid lower-case letter. The plus sign must be treated as special case here. (But you could make the array cover the whole 7-bit ASCII range, where the characters that don't have a umber code have a special value, perhaps '\0'.)

How to fix filling the struct with these data in c

I have struct input parameter and array of it called input_arr. I want to fill the array with the text as it gives the wrong value for the id and it work correctly with the name and nothing appear in visible.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct input_parameter {
int id;
char name[30];
int position;
char visible[5];
char required[5];
char parameter_type;
char client_id[5];
int min_length;
int max_length;
char confirm_required[5];
};
struct input_parameter input_arr[10];
char text[2*1024]="{\"success\": true,\"language\":
\"en\",\"action\":
\"GetServiceInputParameterList\",\"version\": 1,\"data\": {
\"input_parameter_list\": [{\"id\": 1489,\"service_id\":
12102,\"name\": \"Customer Number\",\"position\":
1,\"visible\":
true,\"required\": true,\"parameter_type\":
\"N\",\"client_id\":
true,\"min_length\": 11, \"max_length\":
11,\"confirm_required\":
false } ] }}";
Fill an array of structs with the text:
int main() {
int i = 0;
int Wstart = 0;
int Wend = 0;
char name[19] = {0x20};
char name1[19] = {0x20};
int menunum = 0;
int len = strlen(text);
while (1) // while ALL
{
if (i >= len) {
break;
}
if (text[i] == 'i' && text[i + 1] == 'd') {
while (1) { // while id
if (text[i] == ':') {
Wstart = i + 1;
Wend = 0;
i++;
} else if (text[i] == ',' || text[i] == '}') {
Wend = i;
strncpy(name, text + Wstart, Wend - Wstart);
input_arr[menunum].id = atoi(name);
memset(name, 0, sizeof(name));
i++;
break;
} else {
i = i + 1;
}
} // while id
} else if (text[i] == 'n' && text[i + 1] == 'a' && text[i + 2] == 'm' &&
text[i + 3] == 'e') {
while (1) { // while name
if (text[i] == ':') {
Wstart = i + 3;
Wend = 0;
i++;
} else if (text[i] == ',' || text[i] == '}') {
Wend = i - 1;
strncpy(name, text + Wstart, Wend - Wstart);
// name[Wend-Wstart] = '\0';
// memset(name1, 0, sizeof(name1));
if ((name[1] >= 'a' && name[1] <= 'z') ||
(name[1] >= 'A' && name[1] <= 'Z')) {
// printf("%c is an alphabet.",c);
strcpy(name1, name);
} else {
int vc = 0;
int ia = strlen(name) - 1;
for (ia = strlen(name) - 1; ia >= 0; ia--) {
name1[vc] = name[ia];
vc++;
}
}
strcpy(input_arr[menunum].name, name1);
menunum++;
memset(name, 0, sizeof(name));
i++;
break;
} else {
i = i + 1;
}
} // while name
} else if (text[i] == 'v' && text[i + 1] == 'i' && text[i + 2] == 's' &&
text[i + 3] == 'i' && text[i + 4] == 'b' &&
text[i + 5] == 'l' && text[i + 6] == 'e') {
while (1) { // while visible
if (text[i] == ':') {
Wstart = i + 3;
Wend = 0;
i++;
} else if (text[i] == ',' || text[i] == '}') {
Wend = i - 1;
strncpy(name, text + Wstart, Wend - Wstart);
// name[Wend-Wstart] = '\0';
memset(name1, 0, sizeof(name1));
if ((name[1] >= 'a' && name[1] <= 'z') ||
(name[1] >= 'A' && name[1] <= 'Z')) {
// printf("%c is an alphabet.",c);
strcpy(name1, name);
} else {
int vc = 0;
int ia = strlen(name) - 1;
for (ia = strlen(name) - 1; ia >= 0; ia--) {
name1[vc] = name[ia];
vc++;
}
}
strcpy(input_arr[menunum].visible, name1);
menunum++;
// memset(name, 0, sizeof(name));
i++;
break;
} else {
i = i + 1;
}
} // while visible
} else {
i++;
}
}
printf("id:%d \n name: %s \n visible: %s
\n",&input_arr[0].id,&input_arr[0].name,&input_arr[0].visible);
return 0;
}
Well you are printing address of id instead of its value using %d format specifier.
printf("id:%d\nname: %s\n visible: %d\n",&input_arr[0].id,&input_arr[0].name,&input_arr[0].visible);
should be
printf("id:%d \n name: %s \n visible: %d\n",input_arr[0].id,input_arr[0].name,input_arr[0].visible);

Struggling with TicTacToe in C

I tried to program a simple TicTacToe in C. The program itselfs compiles and show no errors.
So the program draws the field, reads the names and let a player put his symbol in a specific field. All this happens in a while loop, the should be run until its a draw or someone wins.
But the program just run the loop one time so there is only one turn then the program stops.
So here is my code:
main.c:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "game.h"
#define NAMELENGTH 20
int main(void) {
char names[2][NAMELENGTH];
// field positions
char field[9];
int winner = -1;
getnames(names);
printf("\n\n");
initField(field);
// set field positions to 'empty'
char actualPlayer = (char)(get_random_number()*10.0) % 2;
while (1) {
drawField(field);
turn(actualPlayer, names, field);
winner = isWinner(actualPlayer, field);
drawField(field);
if (winner >= 1) {
printwinner(winner, names);
return 0;
}
else if (winner == 0) {
printDrawGame(names);
return 0;
}
actualPlayer = (actualPlayer + 1) % 2;
}
return 0;
}
game.h Headerfile:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#define NAMELENGTH 20
#pragma warning(disable:4996)
extern void drawField(char *field);
extern void getnames(char nameField[][NAMELENGTH]);
extern void initField(char *field);
extern void turn(char actualPlayer, char names[][NAMELENGTH], char *field);
extern char isWinner(char actualPlayer, char *field);
extern void printwinner(char winnerNumber, char names[][NAMELENGTH]);
extern void printDrawGame(char names[][NAMELENGTH]);
extern double get_random_number();
and then my game.c where I defined my functions:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include "game.h"
#define NAMELENGTH 20
#pragma warning(disable:4996)
void drawField(char *field) {
printf("________________________\n");
printf("| | | |\n");
printf("| %c | %c | %c |\n", field[0], field[1], field[2]);
printf("|_______|_______|______|\n");
printf("| | | |\n");
printf("| %c | %c | %c |\n", field[3], field[4], field[5]);
printf("|_______|_______|______|\n");
printf("| | | |\n");
printf("| %c | %c | %c |\n", field[6], field[7], field[8]);
printf("|_______|_______|______|\n");
}
void getnames(char nameField[][NAMELENGTH]) {
printf("Name of the first player: ");
scanf("%s", nameField[0]);
printf("Name of the second player: ");
scanf("%s", nameField[1]);
}
void initField(char *field) {
for (int i = 0; i <= 8; i++)
{
field[i] = i + '1';
}
}
void turn(char actualPlayer, char names[][NAMELENGTH], char *field) {
char symbol = ' ';
int p1fieldnumber;
int p2fieldnumber;
if (actualPlayer == 0)
{
do {
printf("\nIts Player %s's turn.", names[0]);
char symbol = 'X';
printf("\nNumber of the field which you want to put your symbol in: ");
scanf("%d", &p1fieldnumber);
if (field[p1fieldnumber] == 'X' || field[p1fieldnumber] == 'O')
{
printf("\nField is already occupied!");
p1fieldnumber = 10;
}
} while (p1fieldnumber < 1 || p1fieldnumber > 9);
field[p1fieldnumber-1] = 'X';
}
else {
do {
printf("\nIts Player %s's turn.", names[1]);
char symbol = 'O';
printf("\nNumber of the field which you want to put your symbol in: ");
scanf("%d", &p2fieldnumber);
if (field[p2fieldnumber] == 'X' || field[p2fieldnumber] == 'O')
{
printf("\nField is already occupied!");
p2fieldnumber = 10;
}
} while (p2fieldnumber < 1 || p2fieldnumber > 9);
field[p2fieldnumber-1] = 'O';
}
}
char isWinner(char actualPlayer, char *field) {
char pwinner = '3';
if (((field[0] == 'O') && (field[1] == 'O') && (field[2] == 'O')) ||
(field[3] == 'O') && (field[4] == 'O') && (field[5] == 'O') ||
(field[6] == 'O') && (field[7] == 'O') && (field[8] == 'O') ||
(field[0] == 'O') && (field[4] == 'O') && (field[8] == 'O') ||
(field[2] == 'O') && (field[4] == 'O') && (field[6] == 'O') ||
(field[0] == 'O') && (field[3] == 'O') && (field[6] == 'O') ||
(field[1] == 'O') && (field[4] == 'O') && (field[7] == 'O') ||
(field[2] == 'O') && (field[5] == 'O') && (field[8] == 'O'))
{
pwinner = '2';
}
else if (((field[0] == 'X') && (field[1] == 'X') && (field[2] == 'X')) ||
(field[3] == 'X') && (field[4] == 'X') && (field[5] == 'X') ||
(field[6] == 'X') && (field[7] == 'X') && (field[8] == 'X') ||
(field[0] == 'X') && (field[4] == 'X') && (field[8] == 'X') ||
(field[2] == 'X') && (field[4] == 'X') && (field[6] == 'X') ||
(field[0] == 'X') && (field[3] == 'X') && (field[6] == 'X') ||
(field[1] == 'X') && (field[4] == 'X') && (field[7] == 'X') ||
(field[2] == 'X') && (field[5] == 'X') && (field[8] == 'X'))
{
pwinner = '1';
}
else if (((field[0] == 'X') || (field[0] == 'O')) && ((field[1] == 'X') || (field[1] == 'O')) && ((field[2] == 'X') || (field[2] == 'O')) ||
((field[3] == 'X') || (field[3] == 'O')) && ((field[4] == 'X') || (field[4] == 'O')) && ((field[5] == 'X') || (field[5] == 'O')) ||
((field[6] == 'X') || (field[6] == 'O')) && ((field[7] == 'X') || (field[7] == 'O')) && ((field[8] == 'X') || (field[8] == 'O')) ||
((field[0] == 'X') || (field[0] == 'O')) && ((field[4] == 'X') || (field[4] == 'O')) && ((field[8] == 'X') || (field[8] == 'O')) ||
((field[2] == 'X') || (field[2] == 'O')) && ((field[4] == 'X') || (field[4] == 'O')) && ((field[6] == 'X') || (field[6] == 'O')) ||
((field[0] == 'X') || (field[0] == 'O')) && ((field[3] == 'X') || (field[3] == 'O')) && ((field[6] == 'X') || (field[6] == 'O')) ||
((field[1] == 'X') || (field[1] == 'O')) && ((field[4] == 'X') || (field[4] == 'O')) && ((field[7] == 'X') || (field[7] == 'O')) ||
((field[2] == 'X') || (field[2] == 'O')) && ((field[5] == 'X') || (field[5] == 'O')) && ((field[8] == 'X') || (field[8] == 'O')))
{
pwinner = '0';
}
return pwinner;
}
void printwinner(char winnerNumber, char names[][NAMELENGTH]) {
if (winnerNumber == '1') {
printf("Player %s won!", names[0]);
}
else if (winnerNumber == '2') {
printf("Player %s won!", names[1]);
}
}
void printDrawGame(char names[][NAMELENGTH]) {
printf("Draw!");
}
static int _initialized;
double get_random_number() {
if (!_initialized) {
srand(time(NULL));
_initialized = 1;
}
return (double)rand() / ((double)(RAND_MAX)+1);
}
There are multiple issues
isWinner returns characters '0', '1', '2' and '3'. Replace them with numbers 0, 1, 2, 3, because your are comparing with numbers in main.
In main instead of checking if (winner >= 1) {, which is true even if 3 is returned by isWinner, check for if (winner == 1 || winner == 2) {.
Suggest to use parentheses in isWinner around each condition separated by ||.
Parentheses as shown below for the first condition
if (((field[0] == 'O') && (field[1] == 'O') && (field[2] == 'O')) ||
((field[3] == 'O') && (field[4] == 'O') && (field[5] == 'O')) ||
((field[6] == 'O') && (field[7] == 'O') && (field[8] == 'O')) ||
((field[0] == 'O') && (field[4] == 'O') && (field[8] == 'O')) ||
((field[2] == 'O') && (field[4] == 'O') && (field[6] == 'O')) ||
((field[0] == 'O') && (field[3] == 'O') && (field[6] == 'O')) ||
((field[1] == 'O') && (field[4] == 'O') && (field[7] == 'O')) ||
((field[2] == 'O') && (field[5] == 'O') && (field[8] == 'O')))

GPRMC string is not showing after extracting the data - C

Im working around PIC with GPS module. My GPS modules send NMEA data
$GPRMC,000036.799,V,,,,,0.00,0.00,060180,,,N*40
$GPVTG,0.00,T,,M,0.00,N,0.00,K,N*32
$GPGGA,000036.799,,,,,0,0,,,M,,M,,*4A
$GPGSA,A,1,,,,,,,,,,,,,,,*1E
$GPGSV,1,1,00*79
$GPGLL,,,,,000036.799,V,N*78
$GPTXT,01,01,02,ANTSTATUS=OPEN*2B
Here my intention is to extract "GPRMC" data string from the above. I think i've sucessfully took it off the "GPRMC", but the problem is the exracted data string doesnt have GPRMC string. here is the screenshot of my hyperterminal window
Here is my code:
while (1)
{
//memset(gpsdata,0,sizeof(gpsdata));
char c = uartrec2();
if (c == '$')
{
char c1 = uartrec2();
if (c1 == 'G')
{
char c2 = uartrec2();
if (c2 == 'P')
{
char c3 = uartrec2();
if (c3 == 'R')
{
char c4 = uartrec2();
if (c4 == 'M')
{
char c5 = uartrec2();
if (c5 == 'C')
{
for (i = 0 ; i < 100 ; i++)
{
gpsdata[i] = uartrec2();
/* while (gpsdata[i] == '\r' || gpsdata[i] == '\n')
{
break;
} */
if (gpsdata[i] == '\r' ) // Checking for '\r'
{
gpsdata[i] = '\0';
}
}
}
}
}
else
{
printf("Bad GPS data");
}
}
}
}
uart_str(gpsdata);
uart_str("\r\n");
}
The first thing you should do is try to figure out a better way to write this program, this could be
int done;
done = 0;
while (done == 0)
{
const char *string;
int valid;
valid = 1;
string = "$GPRMC";
while ((*string != '\0') && ((valid = (uartec2() == *string)) != 0))
string++;
if (valid != 0)
{
for (int i = 0 ; i < 100 ; ++i)
{
gpsdata[i] = uartec2();
if (gpsdata[i] != '\r')
continue;
gpsdata[i] = '\0';
}
uart_str(gpsdata);
uart_str("\r\n");
}
}
How about just adding it since you know there was it?
if (c5 == 'C')
{
gpsdata[0] = '$';
gpsdata[1] = 'G';
gpsdata[2] = 'P';
gpsdata[3] = 'R';
gpsdata[4] = 'M';
gpsdata[5] = 'C';
for (i = 6 ; i < 100 ; i++)
{
gpsdata[i] = uartrec2();
/* while (gpsdata[i] == '\r' || gpsdata[i] == '\n')
{
break;
} */
if (gpsdata[i] == '\r' ) // Checking for '\r'
{
gpsdata[i] = '\0';
}
}
}

Resources