How to read json packets for particular keyword in C? - c

This my json packet and I want to read "14.469121":
{"jsonrpc": "2.0", "method": "notifySpeed", "params": {"speed": "14.469121"}}
I tried some online solutions and implemented some logic.
ptr = strtok(parse_recData,", ");
while(ptr != NULL)
{
countTillMethod--;
if(countTillMethod == 0)
{
if(strcmp(ptr,"\"notifySpeed\"")==0)
{
if(!(strcmp(ptr,"\"Speed\"" )))
Speed = strtok(NULL,", ");
SpeedValue = atoi (Speed);
if (SpeedValue > PERMISSIBLE_LIMIT)
touchControl (DISABLE);
else
touchControl (ENABLE);
}
}
}
I want to read speed data.

Thank you everyone help, finally i implement successfully.
else if(strcmp(ptr,"\"notifySpeed\"")==0)
{
syslog(LOG_INFO,"Received Speed\n");
ptr1 = strstr(parse_recData_backup, "\"params\"");
ptr1 += strlen("params");
ptr1 = strstr(parse_recData_backup, "\"speed\": ");
ptr1 += strlen("\"speed\": ") + 1;
/* get the exect value */
for(i=0; ptr[i]!='\0'; ++i)
{
while (!((ptr1[i]>='0'&&ptr1[i]<='9') || (ptr1[i] == '.') || (ptr1[i] == '\0')))
{
for(j=i;ptr1[j]!='\0';++j)
{
ptr1[j]=ptr1[j+1];
}
ptr1[j]='\0';
}
}
syslog(LOG_INFO," %s \r\n", ptr1);
/* Converts the string to integer */
Speed = atoi(ptr1);
syslog(LOG_INFO," speed is %d \r\n", Speed);
/* Compare the speed with permissiable limit */
if (Speed > PERMISSIBLE_LIMIT)
touchControl (DISABLE);
else
touchControl (ENABLE);
}

char parse_recData[215] = {"jsonrpc": "2.0", "method": "notifySpeed", "params": {"speed": "14.469121"}};
char parse_recData_backup[215];
char *ptr1 = NULL;
int Speed = 0;
strcpy(parse_recData_backup, parse_recData);
ptr = strtok(parse_recData,", ");
while(ptr != NULL)
{
countTillMethod--;
if(countTillMethod == 0)
{
if(strcmp(ptr,"\"notifySpeed\"")==0)
{
syslog(LOG_INFO,"Received Speed\n");
ptr1 = strstr(parse_recData_backup, "\"speed\": ");
ptr1 += strlen("\"speed\": ") + 1;
/* Converts the string to integer */
Speed = atoi(ptr1);
syslog(LOG_INFO," speed is %d \r\n", Speed);
/* Compare the speed with permissiable limit */
if (Speed > PERMISSIBLE_LIMIT)
touchControl (DISABLE);
else
touchControl (ENABLE);
}
}
ptr = strtok(NULL, ",");
}

Related

Why am I getting this message in hackerrank "~ no response on stdout ~"? I don't know what I am missing>

Why am I getting this message in hackerrank "~ no response on stdout ~"? I don't know what I am missing?
I am bit frustrated right now because I have no clue about what to do.
So I was left with only choice to post this query on Stackoverflow.
Here is the link to the problem
Here is my complete code:
char* readline();
// Complete the countingValleys function below.
int countingValleys(int n, char* s)
{
int dwnhl = 0, level = 0;
bool frmsurface = true;
int k = strlen(s);
for (int i = 0; i < k; i++)
{
if (level == 0)
{
frmsurface = true;
}
if (s[i] == 'D')
{
level--;
if ((level < 0) && (frmsurface == true))
{
dwnhl++;
frmsurface = false;
//printf("went downhill %d ",i);
}
}
else if (s[i] == 'U')
{ //printf("went uphill %d ",i);
level++;
}
// printf("\nhello - %c",s[i]);
}
printf("\nNumber of downhill = %d \n", dwnhl);
return (dwnhl);
}
int main()
{
FILE* fptr = fopen(getenv("OUTPUT_PATH"), "w");
char* n_endptr;
char* n_str = readline();
int n = strtol(n_str, &n_endptr, 10);
if (n_endptr == n_str || *n_endptr != '\0')
{
exit(EXIT_FAILURE);
}
char* s = readline();
int result = countingValleys(n, s);
printf("%d\n", result);
return 0;
}
char* readline()
{
size_t alloc_length = 1024;
size_t data_length = 0;
char* data = malloc(alloc_length);
while (true)
{
char* cursor = data + data_length;
char* line = fgets(cursor, alloc_length - data_length, stdin);
if (!line)
{
break;
}
data_length += strlen(cursor);
if (data_length < alloc_length - 1 || data[data_length - 1] == '\n')
{
break;
}
size_t new_length = alloc_length << 1;
data = realloc(data, new_length);
if (!data)
{
break;
}
alloc_length = new_length;
}
if (data[data_length - 1] == '\n')
{
data[data_length - 1] = '\0';
}
data = realloc(data, data_length);
return data;
}
One problem is the way you handle frmsurface
The first time you enter the loop frmsurface is set to true. If the events are UUDD, your code will still count a "valley" because you don't clear frmsurface when you go up.
Instead of
if(level==0)
{
frmsurface=true;
}
you could try:
frmsurface = (level == 0);
but I don't really understand why you want the boolean. Just test for level == 0 instead. Something like:
if(s[i]=='D')
{
if(level==0)
{
dwnhl++;
}
level--;
}
else if (s[i]=='U')
{
level++;
}
Also I wonder if this line:
printf("\nNumber of downhill = %d \n", dwnhl);
must be removed.
Notice that
int k=strlen(s);
for(int i=0;i<k;i++)
could probably just be
for(int i=0;i<n;i++)
^
as n is passed to the function

C Calculator Program with Stack

Hi I am completely stuck on this basic calculator. It runs almost perfectly but something goes wrong in the stack when I try inputting "5 / 5 + 9 * 2". The 1 from 5 / 5 seems to disappear when it is supposed to be addes to the 18 for the last loop. Happens for simular inputs like 2 * 2 - 9 / 2. Just need help finding this weird error that I have spent many hours trying to figure out with no luck! Thank you!
#include <stdio.h>
#include<string.h>
#include<stdlib.h>
#include <limits.h>
#include <curses.h>
#include<ctype.h>
struct StackNode
{
char* data;
struct StackNode* next;
};
struct StackNode* newNode(char* data)
{
struct StackNode* stackNode =
(struct StackNode*) malloc(sizeof(struct StackNode));
stackNode->data = data;
stackNode->next = NULL;
return stackNode;
}
int isEmpty(struct StackNode *root)
{
return !root;
}
void push(struct StackNode** root, char* data)
{
struct StackNode* stackNode = newNode(data);
stackNode->next = *root;
*root = stackNode;
printf("%s pushed to stack\n", data);
}
char* pop(struct StackNode** root)
{
if (isEmpty(*root))
return NULL;
struct StackNode* temp = *root;
*root = (*root)->next;
char* popped = temp->data;
free(temp);
printf("Popped: %s\n", popped);
return popped;
}
char* peek(struct StackNode* root)
{
if (isEmpty(root))
return NULL;
return root->data;
}
char buffer[64];
char *ca = &buffer[0];
size_t size = 64;
int bufferIndex;
int first = 0;
int isWhiteSpace (char c) {
if ((c == ' ') || (c == '\t') || (c == '\r')) {
return 1;
}
else {
return 0;
}
}
char* getToken() {
char* token = malloc(64);
int i = 0;
while ((isWhiteSpace(buffer[bufferIndex])) && bufferIndex < strlen(buffer)-1) {
bufferIndex++;
}
while (bufferIndex < strlen(buffer)-1) {
int num = isWhiteSpace(buffer[bufferIndex]);
if (num == 0) {
token[i] = buffer[bufferIndex];
i++;
bufferIndex++;
//printf("%s\n", token);
}
else {
bufferIndex++;
break;
}
}
token[i] = '\0';
first++;
return token;
}
int main() {
while (1) {
char* token = "test";
char* postFix = "test";
char* hold = malloc(64);
postFix = malloc(64);
int total = 0;
int pres1 = 0;
int pres2 = 0;
struct StackNode* root = NULL;
printf("Enter line: ");
getline(&ca,&size,stdin);
bufferIndex = 0;
if ((strcmp(token, "quit") == 0)) {
token = getToken();
if (strcmp(token, "") == 0) {
break;
}
else {
printf("Too many arguments. Try again.\n");
}
}
else {
while (strcmp(token, "") != 0) {
token = getToken();
//printf("%s\n", token);
//printf("Top of stack: %s\n", peek(root));
if (isdigit(*token) == 1) {
strcat(postFix, token);
strcat(postFix, " ");
printf("%s\n", postFix);
}
else if (peek(root) == NULL) {
push(&root, token);
}
else {
printf("Peek: %s\n", peek(root));
if (strcmp(token, "*") == 0) {
pres1 = 2;
}
else if (strcmp(token, "/") == 0) {
pres1 = 2;
}
else if (strcmp(token, "-") == 0) {
pres1 = 1;
}
else if (strcmp(token, "+") == 0) {
pres1 = 1;
}
else {
pres1 = 0;
}
if (strcmp(peek(root), "*") == 0) {
pres2 = 2;
}
else if (strcmp(peek(root), "/") == 0) {
pres2 = 2;
}
else if (strcmp(peek(root), "-") == 0) {
pres2 = 1;
}
else if (strcmp(peek(root), "+") == 0) {
pres2 = 1;
}
while((peek(root) != NULL) && (pres2 > pres1)) {
strcat(postFix, peek(root));
strcat(postFix, " ");
pop(&root);
printf("Postfix: %s\n", postFix);
}
push(&root, token);
}
}
do {
//printf("Peek in DO/WHILE: %s\n", peek(root));
strcat(postFix, peek(root));
strcat(postFix, " ");
pop(&root);
} while ((peek(root) != NULL));
printf("Postfix: %s\n", postFix);
//ca = NULL;
token = "1";
bufferIndex = 0;
for (int i = 0; i < strlen(postFix) + 1; i++) {
buffer[i] = postFix[i];
}
//size = strlen(postFix)+1;
//printf("TOKEN: %s\n", token);
while (strcmp(token, "") != 0) {
token = getToken();
if (isdigit(*token) == 1) {
//printf("--Token: %s\n", token);
push(&root, token);
}
else {
int operand1;
//operand1 = malloc(64);
int operand2;
//total = malloc(64);
printf("Peek: %s\n", peek(root));
operand2 = atoi(peek(root));
pop(&root);
printf("Operand2: %d\n", operand2);
if (strcmp(token, "") != 0) {
printf("Peek: %s\n", peek(root));
operand1 = atoi(peek(root));
pop(&root);
printf("Operand1: %d\n", operand1);
printf("Token: %s\n", token);
if (strcmp(token, "+") == 0) {
total = operand1 + operand2;
}
else if (strcmp(token, "/") == 0) {
total = operand1 / operand2;
}
else if (strcmp(token, "-") == 0) {
total = operand1 - operand2;
}
else if (strcmp(token, "*") == 0) {
total = operand1 * operand2;
}
sprintf(hold,"%d",total);
//printf("Peek: %s\n", peek(root));
push(&root, hold);
//pop(&root);
printf("Total: %d\n", total);
}
else {
//printf("Peek: %s\n", peek(root));
break;
}
}
}
}
printf("Total: %d\n", total);
}
return 0;
}
I am supposed to/am using this as a reference for the assignment: http://condor.depaul.edu/ichu/csc415/notes/notes9/Infix.htm
isdigit() should only be tested for zeroness
Instead of:
if (isdigit(*token) == 1) {
use:
if (isdigit((unsigned char)*token)) {
pointers make it easy to overwrite memory used elsewhere
The code does:
char* hold = malloc(64);
and then later on loops doing:
while (/* ... */) {
// ...
sprintf(hold,"%d",total);
push(&root, hold);
// ...
}
This causes all the values stored on the stack to share the same storage and to be overwritten whenever hold is changed.
The allocation must happen on every use:
char *hold;
// ...
while (/* ... */) {
// ...
hold = malloc(64);
sprintf(hold,"%d",total);
push(&root, hold);
// ...
}

read lines from file with fgets and compare each line with strncmp in c

i want to read every line from a file which looks something like this:
readEveryLine
{
"Bart [m]" -> "Marge [f]";
"Lisa [f]" -> "Homer [m]";
...
}
i want to use:
fgets() to read the file line by line
strncmp() to compare every line with a given string or see that it has just the right format
what i have:
while(fgets(*file_string, MAX_INPUT_STDIN, file) != NULL)
{
changeLastC(*file_string); // function to change \n into \0
if (strncmp(*file_string, "readEveryLine\0", 14) == 0)
{
if (strncmp(*file_string, "{\0", 2) == 0)
{
// check the first -> relation
}
}
else
{
printf("Error Parsing\n");
}
}
so the problem is that it just gives me an Error Parsing and i don`t know what i did wrong here.
Thanks a lot for helping me!
here i made a few things now (parsing the first two lines works now) :
maybe anyone has got a good tip for me what i could do better.
Thanks a lot.
if ((fp = fopen("df.dot","r")) == NULL)
{
printf("Error: File Open\n");
return 1;
}
int row = 0; // check row 1
while (fgets(buffer, MAX_PARSING, fp))
{
if ((row == 0) && strncmp(buffer, "readEveryLine\n", 14) == 0)
{
printf("%s", buffer);
}
else
{
printf("Parsing Error 1\n");
}
}
int row1 = 1; // check row 2
while (fgets(buffer, MAX_PARSING, fp))
{
if ((row1 == 1) && strncmp(buffer, "{\n", 2) == 0)
{
printf("%s", buffer);
}
else
{
printf("Parsing Error 2\n");
}
}
int row2 = 2; // check other rows (dynamic, could be even more or less)
while (fgets(buffer, MAX_PARSING, fp))
{
if ((row2 == 2) && strncmp(buffer, " ", 2) == 0)
{
const char *p1 = strstr(fp, "\"")+1;
const char *p2 = strstr(p1, " [m]\"");
const char *p3 = strstr(p1, " [f]\"");
// extract male persons
if (p1 && p2)
{
size_t len1 = p2 - p1;
char* res1 = (char*)malloc(sizeof(char)*(len1 + 1));
strncpy(res1, p1, len1);
res1[len1] = '\0';
// give res1 for functionMale() to work on that string
}
// extract female persons
else if (p1 && p3)
{
size_t len2 = p3 - p1;
char* res2 = (char*)malloc(sizeof(char)*(len2 + 1));
strncpy(res2, p1, len2);
res2[len2] = '\0';
// give res2 for functionFemale() to work on that string
}
else if (strcmp(buffer, " -> ") == 0)
{
// work in progress (quite complicated to do this i think)
// it has to be a realtion between two people
}
else if (strcmp(buffer, ";") == 0)
{
// work in progress
// this sign can either exist like this:
// "Bart [m]" -> "Marge [f]";
// or like this:
// "Marge [f]";
}
break;
}
else
{
printf("Parsing Error 3\n");
}
row2++;
}
// and the very last sign has to be }\n
Your algorithm is already broken.
You use the very same content of *file_string to compare it against tweo different strings.
If you find a match for "readEveryLine" you need to read the next line from your file before you can get the next match for strncmp().
Otherwise the line from the file must match both "readEveryLine" and "{" to pass your second if condition, which is impossible.
Edit:
Now as you have done some improvements I still think it will not work with your approach. The loops will not exit when they should and your if-else-cascade also does not seem to be a good idea.
In your approach you will get messed up with reading too many lines while only 1 line should be parsed.
Maybe you should read a bit about state machines.
Here is a quick approach how I would address the problem:
enum { STATE_HEADER1, STATE_HEADER2, STATE_BODY, STATE_END} state;
int done = 0;
state = STATE_HEADER1;
while (fgets(buffer, MAX_PARSING, fp) && !done) {
if (state == STATE_HEADER1) {
if (strcmp(buffer, "readEveryLine\n") == 0) {
printf("%s", buffer);
state = STATE_HEADER2;
}
else {
printf("Parsing Error 1\n");
done = 1;
}
}
else if (state == STATE_HEADER2) {
if (strcmp(buffer, "{\n") == 0) {
printf("%s", buffer);
state = STATE_BODY;
}
else {
printf("Parsing Error 2\n");
done = 1;
}
}
else if (state == STATE_BODY) {
if (strcmp(buffer, " ") == 0) {
const char *p1 = strstr(buffer, "\"");
const char *pm = strstr(p1, " [m]\"");
const char *pf = strstr(p1, " [f]\"");
char *res;
const char *ptemp;
int is_male;
if (p1 && pf) {
p1 ++;
is_male = 0;
size_t len1 = pf - p1;
res = malloc(len1 + 1);
strcpy(res, p1);
ptemp = pf+3; // point after closing \"
// give res for functionFemale() to work on that string
}
else if (p1 && pm) {
p1 ++;
is_male = 1;
size_t len1 = pm - p1;
res = malloc(len1 + 1);
strcpy(res, p1);
ptemp = pm+3; // point after closing \"
// give res for functionMale() to work on that string
}
else {
done = 1;
printf("Parsing Error 2\n");
}
// Now we have res and is_male holding name and gender.
if (!done)
{
if (strncmp(ptemp, " -> ", 4) == 0) {
// Handle this variant:
// this sign can either exist like this:
// "Bart [m]" -> "Marge [f]";
// Do similar stuff as above for first name
// Get second name + gender
// Also check trailing ';' here
}
else if (strcmp(temp, ";\n") == 0) {
// Handle this variant:
// or like this:
// "Marge [f]";
}
} // found " "
else {
if (strcmp(buffer, "}\n") == 0) {
state = STATE_END;
done = 1;
printf("That's it folks...\n");
}
else {
done = 1;
printf("Parsing Error 3\n");
}
}
}
} // STATE_BODY
} // while (fgets)
if (state == STATE_END) }
// Success. :)
} else {
// Something didn't match.
}
// close file, cleanup, etc.
I did not compile it yet but you should get the idea.

Segmentation Fault fgets() two pass assembler [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 6 years ago.
Improve this question
#include<string.h>
typedef struct{
char Mnemonic[7];
int code;
} code;
typedef struct{
char label[10];
unsigned int location;
} symbolTab;
int opLook(char * mnemonic, code * optable)
{
int i = 0;
int value = 0;
for(i ; i<25 ; i++)
{
if(strcmp(mnemonic, optable[i].Mnemonic) == 0)
{
value = optable[i].code;
return value;
}
}
return value;
}
int opValid(char * mnemonic, code * optable)
{
int i = 0;
for(i ; i<25 ; i++)
{
if(strcmp(mnemonic, optable[i].Mnemonic) == 0)
{
return 1;
}
}
return 0;
}
int labelcheck(char * label, symbolTab * Table, int counter)
{
int i = 0;
int flag = 0;
if (counter == 0)
{
return flag;
}
else
{
for(i; i <counter; i ++)
{
if(strcmp(label, Table[i].label) == 0)
{
flag = 1;
}
}
return flag;
}
}
unsigned int labelVal(char * label, symbolTab * Table, int counter)
{
int i = 0;
for(i; i <counter; i ++)
{
if(strcmp(label, Table[i].label) == 0)
{
return Table[i].location;
}
}
}
void Assemble(char* filename)
{
unsigned int locctr = 0; /*location counter*/
unsigned int prolen = 0; /*program length*/
int mnemoVal; /*mnemonic Value in Int*/
int labelctr = 0;
code Opta[25] = {{"ADD", 24},{"AND",88},{"COMP",40},{"DIV",36},{"J",60},
{"JEQ",48},{"JGT",52},{"JLT",56},{"JSUB",72},{"LDA",00},
{"LDCH",80},{"LDL", 8},{"LDX", 4},{"MUL",32},{"OR",68},
{"RD",216},{"RSUB",76},{"STA",12},{"STCH",84},{"STL",20},
{"STX",16},{"SUB",28},{"TD",224},{"TIX",44},{"WD",220}};
symbolTab symTab[500];
char buffer[255];
FILE * source;
FILE * interFile;
FILE * objF;
FILE * ListFile;
interFile = fopen("intermidiateFile.txt", "w+");
ListFile = fopen("ListingFile.txt", "w+");
objF = fopen("ObjectFile.txt", "w+");
source = fopen("source.txt", "r");
char * lab; /*label*/
char * mnemo; /*mnemonic*/
char * operand;
char * address = "adress";
unsigned int opeaddress;
fgets(buffer, 255, source);
if (buffer[0] != '.')
{
fprintf(interFile, "%s", buffer);
}
/*Getting first line and initialization of Location Counter*/
if(buffer[0] == '.') /* if the line is a comment continue with the next iteration of the loop*/
{
locctr = 0;
}
else
{
if(buffer[0] == ' ' || buffer[0] == '\t')
{
mnemo = strtok(buffer, " \t");
operand = strtok(NULL, " \t");
if(strcmp(mnemo, "START") == 0)
{
locctr = strtol(operand, NULL, 16);
}
else
{
/*error*/
}
}
else
{
lab =strtok(buffer, " \t");
mnemo = strtok(NULL, " \t");
operand = strtok(NULL, " \t");
if(strcmp(mnemo, "START") == 0)
{
locctr = strtol(operand, NULL, 16);
}
else
{
/*error*/
}
}
}
/* End of the location counter initialization */
/*start while loop*/
while(!feof(source))
{
memset(lab, '\0', strlen(lab));
memset(mnemo, '\0', strlen(mnemo));
memset(operand, '\0', strlen(operand));
fgets(buffer, 255, source);
fprintf(interFile, "%s", buffer);
if(buffer[0] == '.') /* if the line is a comment continue with the next iteration of the loop*/
{
continue;
}
else /* Else for... If it is not a comment, then check if it start with a character or a space*/
{
if(buffer[0] == ' ' || buffer[0] == '\t') /* If it start with a space, then it is just a mnemonic or mnemonic & operand*/
{
mnemo = strtok(buffer, " \t\n\r");
if (strcmp(mnemo, "END") == 0)
{
break;
}
if(strcmp(mnemo, "RSUB") == 0)
{
mnemoVal = opLook(mnemo, Opta);
fprintf(interFile, "%x %02x\n", locctr, mnemoVal);
}
else
{
operand = strtok(NULL, " \t\r\n");
mnemoVal = opLook(mnemo, Opta);
fprintf(interFile, "%x %02x %s\n", locctr, mnemoVal, operand);
}
}
else
{
lab = strtok(buffer, " \t\n\r"); /* it has a label, mnemonic and operand*/
if(labelcheck(lab, symTab, labelctr) == 0) /* check if the label is already in the symTab, if not, add it, otherwise it is an error*/
{
strcpy(symTab[labelctr].label, lab);
symTab[labelctr].location = locctr;
labelctr++;
mnemo = strtok(NULL, " \t\n\r");
if (strcmp(mnemo, "END") == 0)
{
break;
}
operand = strtok(NULL, " \t\n\r");
mnemoVal = opLook(mnemo, Opta);
}
else
{
mnemo = strtok(NULL, " \t\n\r");
if (strcmp(mnemo, "END") == 0)
{
break;
}
operand = strtok(NULL, " \t\n\r");
mnemoVal = opLook(mnemo, Opta);
}
fprintf(interFile, "%x %s %02x %s\n", locctr, lab, mnemoVal, operand);
}
}
if(strcmp(mnemo, "WORD") == 0 )
{
locctr = locctr + 3;
}
else if(strcmp(mnemo, "BYTE") == 0 )
{
unsigned int val;
if (operand[0] =='C')
{
val = strlen(operand) - 3;
locctr = locctr + val;
}
else
{
val = (strlen(operand) - 3)/2;
locctr = locctr + val;
}
}
else if(strcmp(mnemo, "RESB") == 0)
{
locctr = locctr + atoi(operand);
}
else if(strcmp(mnemo, "RESW") == 0)
{
locctr = locctr + (3*atoi(operand));
}
else
{
locctr= locctr + 3;
}
}
/* End of While loop*/
prolen = locctr - symTab[0].location;
fprintf(interFile, "\n%x", prolen);
fclose(source);
fclose(interFile);
interFile = fopen("intermidiateFile.txt", "r");
/*Start the Listing File and Object File ---------------------Pass 2----------- */
fgets(buffer, 255, interFile);
if(buffer[0] == '.') /* if the line is a comment continue with the next iteration of the loop*/
{
locctr = 0;
/*Error missung Start or Misplaced*/
}
else
{
if(buffer[0] == ' ' || buffer[0] == '\t')
{
mnemo = strtok(buffer, " \t");
operand = strtok(NULL, " \t");
if(strcmp(mnemo, "START") == 0)
{
locctr = strtol(operand, NULL, 16);
strcpy(address, operand);
fprintf(ListFile, "%X %s %s\n", locctr, mnemo, operand);
}
else
{
/*error*/
}
}
else
{
lab =strtok(buffer, " \t");
mnemo = strtok(NULL, " \t");
operand = strtok(NULL, " \t");
if(strcmp(mnemo, "START") == 0)
{
locctr = strtol(operand, NULL, 16);
fprintf(ListFile, "%x %s %s %s\n", locctr, lab, mnemo, operand);
fprintf(objF, "H%s__%06x%06x\n", lab, locctr, prolen);
}
else
{
/*error*/
}
}
}
while(!feof(interFile))
{
memset(lab, '\0', strlen(lab));
memset(mnemo, '\0', strlen(mnemo));
memset(operand, '\0', strlen(operand));
memset(address, '\0', strlen(address));
memset(buffer, '\0', strlen(buffer));
fgets(buffer, 255, interFile);
if (buffer[0] == '\r')
{
continue;
}
if(buffer[0] == ' ' || buffer[0] == '\t')
{
mnemo = strtok(buffer, " \t\n\r");
if (strcmp(mnemo, "END") == 0)
{
break;
}
if(strcmp(mnemo, "RSUB") == 0)
{
memset(buffer, '\0', strlen(buffer));
fgets(address, 255, interFile);
mnemoVal = opLook(mnemo, Opta);
fprintf(ListFile, "%s %s %X0000", address, mnemo, mnemoVal);
}
else
{
operand = strtok(NULL, " \t\r\n");
mnemoVal = opLook(mnemo, Opta);
memset(buffer, '\0', strlen(buffer));
fgets(address, 255, interFile);
if (labelcheck(operand, symTab, labelctr) == 1)
{
opeaddress = labelVal(operand, symTab, labelctr);
}
else
{
opeaddress = 0;
/* error*/
}
fprintf(ListFile, "%s %s %s %02X%04X", address, mnemo, operand, mnemoVal, opeaddress);
}
}
else if (buffer[0] == '.')
{
fprintf(ListFile, "%s\n", buffer);
}
else
{
lab = strtok(buffer, " \t\n\r");
mnemo = strtok(NULL, " \t\n\r");
operand = strtok(NULL, " \t\n\r");
mnemoVal = opLook(mnemo, Opta);
memset(buffer, '\0', strlen(buffer));
fgets(address, 255, interFile);
if (labelcheck(operand, symTab, labelctr) == 1)
{
opeaddress = labelVal(operand, symTab, labelctr);
}
else
{
opeaddress = 0;
/* error*/
}
fprintf(ListFile, "%s %s %s %s %02X%04X", address, lab, mnemo, operand, mnemoVal, opeaddress);
}
}
fclose(interFile);
fclose(objF);
fclose(ListFile);
}
The error occurs in the last while loop when executing fgets();
I have looked if I had any variable or syntax wrong, but everything looks fine.
This is a part of a two pass assemble. The error varies between the fgets in the last while loop. At first I thought that it was the memset function, but the error still happened when I mark them as comments
Because of
char * address = "adress";
address is pointing to Read Only Memory
Trying to modify string literals (in your case "adress") invokes undefined behavior.
Then in your last loop
strcpy(address, operand);
memset(address, '\0', strlen(address));
fgets(address, 255, interFile);
Are wrong.
You could change that variable to a simple array of chars with enough room for your needs, e.g.:
char address[128];

Countdown timer in C without freezing user input

I'm a newbie in C. I'm on the verge of finishing a program. Can anybody teach me how to make a countdown timer while being able to input something? I'm currently using sleep(), and as I've heard, it's bad for threading, and freezes input. Is that right?
Here's the function:
void nowPlaying(SONG * h, SONG * t, int * randPrev, int shuffleCon)
{
SONG * ptr;
ptr = h->next;
int random, randCount, mincount = 0, choice = 4, tot = 0, tot2 = 0;
if(h->next == t) {
printf("No songs to be played. Add some!\n");
}
else if(h->next != t) {
while(ptr->next != t) {
tot2 = tot = ((ptr->cdown.minutes*60) + ptr->cdown.secs);
do {
printf("------------------------YouTunes------------------------\n");
printf("========================================================\n");
printf("TITLE : %s \n", ptr->title);
printf("ARTIST: %s \n", ptr->artist);
printf("ALBUM : %s \n", ptr->album);
switch(ptr->genre) {
case 1:
printf("GENRE : POP \n");
break;
case 2:
printf("GENRE : OPM \n");
break;
case 3:
printf("GENRE : ROCK \n");
break;
case 4:
printf("GENRE : R&B \n");
break;
case 5:
printf("GENRE : ACOUSTIC \n");
break;
case 6:
printf("GENRE : CLASSICAL \n");
break;
}
while(tot2 >= 60) {
tot2 = tot2 - 60;
mincount++;
//if(time_left % 60 == 0) mincount++;
}
printf("TIME: ");
if(mincount < 10)
printf("0%d", mincount);
else
printf("%d", mincount);
printf(":");
if(tot2 < 10)
printf("0%d", tot2);
else if(tot2 == 60)
printf("00");
else
printf("%d", tot2);
printf("\n========================================================\n");
printf("[1] Prev [0]Exit [2] Next\n");
printf("Choice: ");
//scanf("%d", &choice);
//timeout(500);
tot--;
tot2 = tot;
mincount = 0;
sleep(1);
system("clear");
if(shuffleCon == 0) {
if(choice == 1) {
if(ptr->prev == h) {
//do nothing
}
else if(ptr->prev != h) {
ptr = ptr->prev;
}
}
else if(choice == 2) {
if(ptr->next == t) {
//do nothing
}
else if(ptr->next != t) {
ptr = ptr->next;
}
}
}
else if(shuffleCon == 1) {
if(choice == 1) {
random = shuffle(h, t, randPrev);
randCount = 0;
ptr = h->next;
while(randCount != random) {
ptr = ptr->next;
randCount++;
}
}
else if(choice == 2) {
random = shuffle(h, t, randPrev);
randCount = 0;
ptr = h->next;
while(randCount != random) {
ptr = ptr->next;
randCount++;
}
if(ptr == t) {
ptr = ptr->prev;
ptr = ptr->prev;
}
}
}
} while(tot != -1);
if(shuffleCon == 0)
ptr = ptr->next;
else if(shuffleCon == 1) {
random = shuffle(h, t, randPrev);
randCount = 0;
ptr = h->next;
while(randCount != random) {
ptr = ptr->next;
randCount++;
}
}
}
}
}
Broadly speaking, one of these:
Use SIGALRM (see the alarm man page), and rely on the signal to interrupt the system call expecting user input.
(Better, and certainly a more valuable programming exercise), write an event loop with select or poll and set the timeout to be the time remaining until the timeout.
For the sort of application you are talking about, (2) would be a better choice.

Resources