So, I got to a point where I have a string with words and punctuation marks ( a full sentence to be exact). I wanted to change one word in that sentence. The number of letters of the new word may not be the exact with the previous one. I also have a 2-d matrix with the words of the sentence changed now so that it has the new word instead of the old one. So I managed to trade all words in my original string with a * and keep the punctuation marks so that I can change the * with the words of the altered 2-d matrix and keep the punctuation marks. So my real question is how can I change the * of the string with whole words and then add the punctuation marks where needed.
Example:
Original string: HELLO PEOPLE. HELLO WORLD. HOW ARE YOU TODAY?
Word for change: WORLD --> MAN
String with '*': * *. * *.* * * *?
Result I want: HELLO PEOPLE. HELLO MAN. HOW ARE YOU TODAY?
I tried this (with text3 string with'*' and text 4 the result I want):
l1=0;sum3=0;
for (k=0;k<sum2;k++){
if (text3[k]=='*'){
strcpy(&text4[sum3],textb1[l1]);
l1++;
sum3=sum3+strlen(textb1[l1]);
}
else {
text4[sum3]=text3[k];
sum3++;
}
}
printf("%s\n",text4);
But I only manage to get the first HELLO printed.
Here is a full program, based on my "stack" idea, to demonstrate:
split then store words on spaces and punctuation;
store into a basic stack;
print out with spaces added where needed;
output new word whenever old word was in input.
The latter replaces every occurrence of old with new, as it was not specified the replacement should only occur once. Overflow handling of stack and memory cleanup omitted for clarity.
Pro
Spaces are always concatenated into one single space.
Easily adjustable for other scenarios.
Con
Spaces are always concatenated into one single space.
It only checks for alphanumerics and a basic punctuation set.
Handling of punctuation is very basic. For instance, initially I added () to punct as well, but these need further adjustments in the output routine that insert spaces. If necessary, you could, for instance, make stack a struct and add a spaceAfter member and save where the original spaces occurred.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
char *stack[256];
int stack_depth = 0;
const char *punct = ".,:;!?";
int main (int argc, char **argv)
{
char *ptr, *find, *change;
int i;
if (argc != 3)
{
ptr = strrchr (argv[0], '/');
if (!ptr)
ptr = strrchr (argv[0], '\\');
if (ptr)
ptr++;
else
ptr = argv[0];
printf ("usage: %s \"original string\" \"original --> new\"\n", ptr);
return 0;
}
ptr = argv[1];
while (*ptr)
{
while (*ptr == ' ')
ptr++;
i = 0;
while (ptr[i])
{
/* do not store spaces */
if (ptr[i] == ' ')
break;
/* stop on punctuation */
if (strchr (punct, ptr[i]))
break;
i++;
}
if (i)
{
stack[stack_depth] = malloc(i+1);
if (stack[stack_depth] == NULL)
{
printf ("oh wow, out of memory\n");
return -1;
}
strncpy (stack[stack_depth], ptr, i);
stack[stack_depth][i] = 0;
stack_depth++;
ptr += i;
}
if (*ptr && strchr (punct, *ptr))
{
i = 0;
while (ptr[i] && strchr (punct, ptr[i]))
i++;
stack[stack_depth] = malloc(i+1);
if (stack[stack_depth] == NULL)
{
printf ("oh wow, out of memory\n");
return -1;
}
strncpy (stack[stack_depth], ptr, i);
stack[stack_depth][i] = 0;
stack_depth++;
ptr += i;
}
}
printf ("Original string: ");
for (i=0; i<stack_depth; i++)
{
if (i > 0 && !strchr (punct, stack[i][0]))
printf (" ");
printf ("%s", stack[i]);
}
printf ("\n");
/* fetch change words */
ptr = strstr (argv[2], " --> ");
if (!ptr)
{
printf ("bad syntax!\n");
return -1;
}
/* fetch the length of 'find' */
i = ptr-argv[2];
find = malloc (i+1);
strncpy (find, argv[2], i);
find[i] = 0;
/* fetch the length of 'change' */
/* this is the 5 characters ' --> ' after start */
ptr += 5;
i = strlen(ptr);
change = malloc (i+1);
strncpy (change, ptr, i);
change[i] = 0;
printf ("Word for change: %s --> %s\n", find, change);
printf ("Result: ");
for (i=0; i<stack_depth; i++)
{
if (i > 0 && !strchr (punct, stack[i][0]))
printf (" ");
if (strcmp (stack[i], find))
printf ("%s", stack[i]);
else
printf ("%s", change);
}
printf ("\n");
}
Test run:
replace "HELLO PEOPLE. HELLO WORLD. HOW ARE YOU TODAY?" "WORLD --> MAN"
Original string: HELLO PEOPLE. HELLO WORLD. HOW ARE YOU TODAY?
Word for change: WORLD --> MAN
Result: HELLO PEOPLE. HELLO MAN. HOW ARE YOU TODAY?
A few bugs:
l1=0;sum3=0;
for (k=0;k<sum2;k++){
if (text3[k]=='*'){
strcpy(&text4[sum3],textb1[l1]);
/*l1++; */ /* You are incrementing the wrong length I think.... */
sum3=sum3+strlen(textb1[l1]);
l1++;
}
else {
text4[sum3]=text3[k];
sum3++;
}
}
text4[sum3] = 0; /* Null terminate */
printf("%s\n",text4);
Related
I tried to dynamically allocate a string using a function I named ALLO, but when I execute I get an error, which is my function ALLO can't get the string using getc, it gets skipped.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void ALLO(char *str){
char c=0;
int i = 0, j = 1;
str = (char*)malloc(sizeof(char));
printf("Enter String : ");
while (c != '\n') {
// read the input from keyboard standard input
c = getc(stdin);
// re-allocate (resize) memory for character read to be stored
str = (char*)realloc(str, j * sizeof(char));
// store read character by making pointer point to c
str[i] = c;
i++;
j++;
}
str[i] = '\0'; // at the end append null character to mark end of string
printf("\nThe entered string is : %s", str);
free(str); // important step the pointer declared must be made free
}
int main(){
char *NomAF;
int NAF;
printf("Entrer le nombre des ateliers : ");
scanf("%d",&NAF);
ALLO(NomAF);
return 0 ;
}
The semantics are wrong.
You ask the user for the names of the athletes, and then you scan it into an integer. You should ask for the number of athletes first. Then, after that, you allocate memory to accommodate each name.
int num_names;
scanf("%d", &num_names);
After you know the number of names, you then allocate a buffer for each name, separately.
char **names;
names = malloc(num_names * sizeof(char **));
for(int i = 0; i < num_names; i++)
ALLOC(&names[i]);
Also, you shouldn't be using scanf for user input. Use fgets instead, which is a little better.
Then, you also should be using a pointer to pointers to get those strings.
A little modified version of your code (which you should review and fix, as needed):
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void ALLO(char **str){
/* use INT for getc() return */
int c=0, i = 0;
/* you are gettting 1 byte of memory */
*str = malloc(sizeof **str);
/* should use fprintf(stderr...) or fflush(stdout) to guarantee
* the sentence will be seen by user
*/
printf("Enter String : ");
while (c != '\n') {
// read the input from keyboard standard input
c = getc(stdin);
// re-allocate (resize) memory for character read to be stored
/* i = 0 in the first run,
*
* and you have 1 byte alloced in the first run.
*
* so you get 1 byte for actual getc() return
* 1 byte for next character + NULL byte
*
* NOTE: you are STORING the NULL byte in your string. You only
* check for it AFTER you do the assignment, so your strings
* contain a newline before the NULL byte.
*/
*str = (char*)realloc(*str, (i + 2) * sizeof **str);
// store read character by making pointer point to c
(*str)[i] = c;
// you can use only 'i' for this...
i++;
/* #i
*
* Using only 'i' requires that you understand what #i is doing
* during execution. #i will keep the current buffer position,
* and you know you need one more position for the next
* character and one more for the NULL byte.
*
* Therefore, in your realloc statemente, you need #(i + 2)
*/
}
(*str)[i] = '\0'; // at the end append null character to mark end of string
printf("\nThe entered string is : %s", *str);
// if you free here, you can't get the string at #main for printing.
// free is the last step
//free(str); // important step the pointer declared must be made free
}
int main(){
char **NomAF;
int NAF, i;
char buf[100];
printf("Number of athlets : ");
fgets(buf, sizeof(buf), stdin);
NAF = atoi(buf);
NomAF = malloc(NAF * sizeof *NomAF);
// check malloc errors
// get names
for(i = 0; i < NAF; i++) {
ALLO(&NomAF[i]);
printf("New name: %s\n", NomAF[i]);
}
// print names, then free() then
for(i = 0; i < NAF; i++) {
printf("Name: %s\n", NomAF[i]);
free(NomAF[i]);
}
// free the base pointer
free(NomAF);
return 0 ;
}
Add this
while((c=getchar()!='\n')&&c!=EOF);
before getc it skips white space.
Because after this scanf("%d",&NAF); take you are giving input 5(+enter) this goes 5'\n' 5 is got by scanf and '\n' is in buffer and this new line is got by your getc.
and change this str[i] = '\0'; to str[i-1] = '\0';, it replaces the newline with NULL and you allocated memory for i characters only.
You can return the string by return str; and change function return type as char* or if don't want that take a parameter that allocated by malloc.
See this:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void ALLO(char *str)
{
char c=0;
int i = 0;
printf("Enter String : ");
while (c != '\n')
{
while((c=getchar()!='\n')&&c!=EOF);
c = getc(stdin);
str = (char*)realloc(str, (i+1) * sizeof(char));
if(!str) exit(1);
str[i] = c;
i++;
}
str[i-1] = '\0';
}
int main()
{
char *NomAF;
int NAF;
NomAF=malloc(sizeof(char));
if(!NomAF) exit(1);
printf("Entrer le nombre des ateliers : ");
scanf("%d",&NAF);
ALLO(NomAF);
printf(NomAF);
free(NomAF);
return 0 ;
}
output:
Entrer le nombre des ateliers : 5
Enter String : a
s
d
f
g
----->newline to stop the loop
asdfg
Process returned 0 (0x0) execution time : 8.205 s
Press any key to continue.
I entered it as a string not character by character, its not practical to ask the user the enter letter by letter
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
char * inputword(char **);
int main()
{
char *word;
printf("Enter Word:");
word=inputword(NULL);
printf("Word Entered:%s",word);
free(word);
printf("\nEnter Word 2:");
inputword(&word);
printf("Word Entered:%s",word);
free(word);
return 0 ;
}
char *inputword(char **word)
{
char *str=NULL,ch,*memerr="Memory Error";
int i=0,flag=1;
do
{
str=realloc(str,((i+1)*sizeof(char)));
if(!str)
{
printf(memerr);
exit(1);
}
ch = getch();
switch(ch)
{
case 13:
str[i] = '\0';
putc('\n',stdout);
flag=0;
break;
case '\b':
if(i>0) i--;
str[i--]='\0';
printf("\b \b");
break;
default:
str[i] = ch;
putc(ch,stdout);
}
i++;
}while(flag);
if(word!=NULL)
*word=str;
return str;
}
output:
Enter Word:Hai, How are You?(1 String)
Word Entered:Hai, How are You?(1 String)
Enter Word 2:Hai, How are You?(2 string)
Word Entered:Hai, How are You?(2 string)
Process returned 0 (0x0) execution time : 58.883 s
Press any key to continue.
Whenever a word from wordlist passes as a valid word, strcat(code,wordlist[i]) is called to add the word to world list.
So if at the first line "am" is put, code=am.
Or if abhcgmsopa bqcedpwon abmnpc abcdponm dfajbbmmn cabnmo is put at the first line, the three corresponding valid words are put.
However at the second line the values in code get overwritten and extra characters are put, even though code is initialized outside the while-loop and strcat should append the values to the end of code. Then when the while-loop ends, code is replaced by the entirely by "xq", where x was the first letter put into code and q is from "quitting".
Code isn't reinitialized or changed aside from what is appended to it.
How can I prevent this?
Thanks
*Edit: I defined some stack functions before the main but edited it out here to minimize the code
int main(int argc, char const *argv[])
{
char input[300];
char code[]="";
int ci;
/* set up an infinite loop */
while (1)
{
//break;
/* get line of input from standard input */
printf ("\nEnter input to check or q to quit\n");
fgets(input, 300, stdin);
/* remove the newline character from the input */
int i = 0;
while (input[i] != '\n' && input[i] != '\0')
{
i++;
}
input[i] = '\0';
/* check if user enter q or Q to quit program */
if ( (strcmp (input, "q") == 0) || (strcmp (input, "Q") == 0) )
break;
/*Start tokenizing the input into words separated by space
We use strtok() function from string.h*/
/*The tokenized words are added to an array of words*/
char delim[] = " ";
char *ptr = strtok(input, delim);
int j = 0 ;
char *wordlist[300];
while (ptr != NULL)
{
wordlist[j++] = ptr;
ptr = strtok(NULL, delim);
}
/*Run the algorithm to decode the message*/
//j=words in line;i=i-th word we are evaluating
//k=k-th letter in i-th word
stack1 st;
for(int i=0;i<j;i++){
//stack1 st;
init(&st);
for(int k=0;k<strlen(wordlist[i]);k++){
if((int)wordlist[i][k]<101 && (int)wordlist[i][k]>96){ //check if this letter is a/b/c/d with ascii
push(&st,&wordlist[i][k]);
printf("%c added\n",st.ptr[st.inUse-1]);
}
else{
if(wordlist[i][k]==top(&st)+12){ //check if letter is m/n/o/p corresponding to a/b/c/d from top()
pop(&st);
}
}
}
if(is_empty(&st)){
printf("%s is valid\n",wordlist[i]);
strcat(code,wordlist[i]);
strcat(code," ");
}
else{
printf("%s is invalid\n",wordlist[i]);
clear(&st);
}
printf("code:%s\n",code);
}
printf("code after loop: %s",code);
}
printf("code: %s\n",code);
for(int i=0;i<300;i++){
if ((int)code[i]<101 && (int)code[i]>96){
printf("%c",code[i]);
}
if(!((int)code[i]<96+26 && (int)code[i]>96)){
printf(" ");
}
}
printf("code:%s",code);
printf ("\nGoodbye\n");
return 0;
}
The problem is that your code variable is an array of 1 character! This line:
char code[]="";
declares it as an empty string (no characters) plus a null terminator.
You need to assign it as an array big enough to hold the maximum possible answer! If this is, say, 500, then use this:
char code[500]="";
I need to be able to extract the characters before and after a substring, currently I have the following code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, char *argv[]){
char *text = (char *) malloc (10000000);
char *word = argv[1];
int rep;
FILE *f;
if(argc < 2)
{
printf("Usage: GET <website> | ./word_counter <word>\n");
exit(1);
}
fread(text, 100, 10000000, stdin);
const char *tmp = text;
f = fopen("output.txt", "w");
fprintf(f, "%s\n", "REPS");
while(tmp = strstr(tmp, word)){
printf("%.50s\n", tmp);
rep++;
tmp++;
}
printf("Word count: %d\n", rep);
fclose(f);
system("gedit output.txt");
return 0;
}
I made a copy of the original input so I could leave it untouched and get the "before" characters from it.
Using strstr() on tmp (the original input copy) I can find the instances of the word I'm looking for and print the first 50 characters. But knowing this, how can I access the 50 characters BEFORE this instance?
Any help will be appreciated. Thanks!
Apart from the printing question itself, there are a couple of errors in your code. I have corrected most of them; a short list is:
Always test if malloc succeeded.
fread(text, 100, 10000000, ..) reads way too many text. 100 * 10000000 = 1000000000, almost a full gigabyte. You only allocated enough memory for 10 Mb.
You read from a text file and treat this data as a string. Therefore, you must make sure the data ends with a 0, else functions such as printf and strstr will try to continue reading after the end.
Your rep variable starts out uninitialized and therefore you will always see a random number.
Always free memory you allocated.
That said, it is slightly more efficient to use a dedicated function to print out text – if only to not put too much in your main. And since it's a function, you can add as many useful parameters into it as you want; I added before and after variables, so you can vary the number of characters shown.
For added niceness, this function prints a correct number of spaces when the phrase is found before the minimum number of before characters, so the results line up nicely. Also, since printing out characters such as tab and newlines will mess up your output, I replaced them with ?.
There is, admittedly, some repetition in print_range but in this case I went for clarity, rather than brevity.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_LENGTH 10000000
void print_range (char *source_text, int startindex, int before, int after, int phrase_length)
{
int i;
if (before > startindex)
{
for (i=0; i<before-startindex; i++)
printf (" ");
startindex = before;
}
for (i=0; i<before; i++)
{
if (strchr ("\t\r\n", source_text[startindex-before+i]))
printf ("?");
else
printf ("%c", source_text[startindex-before+i]);
}
for (i=0; i<phrase_length; i++)
{
if (strchr ("\t\r\n", source_text[startindex+i]))
printf ("?");
else
printf ("%c", source_text[startindex+i]);
}
for (i=0; i<after; i++)
{
if (!source_text[startindex+phrase_length+i])
break;
if (strchr ("\t\r\n", source_text[startindex+phrase_length+i]))
printf ("?");
else
printf ("%c", source_text[startindex+phrase_length+i]);
}
printf ("\n");
}
int main (int argc, char *argv[]){
char *text = (char *) malloc (MAX_LENGTH);
char *word = argv[1];
int rep = 0;
if (!text)
return -1;
if(argc < 2)
{
printf("Usage: GET <website> | ./word_counter <word>\n");
exit(1);
}
fread(text, 1, MAX_LENGTH, stdin);
text[MAX_LENGTH] = 0;
const char *tmp = text;
do
{
tmp = strstr(tmp, word);
if (!tmp)
break;
print_range (text, tmp-text, 16,16, strlen(word));
rep++;
tmp++;
} while (1);
free (text);
printf ("Word count: %d\n", rep);
return 0;
}
Result of running this on its own source code:
~/Documents $ ./wordcounter printf < wordcounter.c
tindex; i++)????printf (" ");???starti
-before+i]))????printf ("?");???else??
"?");???else????printf ("%c", source_t
before+i]);??}??printf ("{");??for (i=
rtindex+i]))????printf ("?");???else??
"?");???else????printf ("%c", source_t
tindex+i]);??}??printf ("}");??for (i=
_length+i]))????printf ("?");???else??
"?");???else????printf ("%c", source_t
length+i]);??}??printf ("\n");?}??int
argc < 2)??{??? printf("Usage: GET <we
?free (text);???printf ("Word count: %
Word count: 12
I am trying to delete the blank space between a string and print out the first word with isalpha() function.
When I print out, only the first letter prints out. exempel "hello big panda" I get "hhhhh" but I want the hole word "hello" instead
int main()
{
char inputString[]={"hello big panda"};
int k=0;
int i=0;
do
{
inputString[i];
i++;
}
while (inputString[i]=isalpha(inputString[i]));
for(i=0; inputString[i] !='\0' ;i++)
{
for (k=i; inputString[k] != '\0'; k++)
{
inputString[k] =inputString[i];
}
}
printf("%s", inputString);
return 0;
}
done this:
int printfirstword(char sentence[])
{
int k=0;
int i=0;
while (isalpha(sentence[i])) //checking for the first blank space
{
i++;
}
sentence[i] = '\0';
printf("%s\n", sentence);
return 0;
}
int main()
{
char sentence[100];
int wordNumber;
char answer;
printfirstword("Hello there")
return0;
}
But I don't want to change the string that is passed to it
What you can simply do is use a while loop instead of your do-while. You can simply increment i until you find the index of first blank space. Then using the value of i you can insert '\0' in your string. Output it and you are done. :)
#include <stdio.h>
#include<ctype.h>
int main()
{
char inputString[]={"hello big panda"};
int k=0;
int i=0;
while (isalpha(inputString[i])) //checking for the first blank space
{
i++;
}
inputString[i] = '\0';
printf("%s", inputString);
return 0;
}
If you would like to keep the original string then you could simply make a new string say newStr and then
while (isalpha(inputString[i])) //checking for the first blank space
{ newStr[i]=inputString[i]; //copy first word into newStr
i++;
}
newStr[i] = '\0';
printf("%s", newStr);
Your function must do 3 things as it works through the sentence finding words. (1) always check for the end of the string to prevent an attempted read beyond the end of the sentence; and (2) locate and print the requested word at the index given; and (3) handle the condition where the user requests a word index greater than that available.
(you should always test the sentence you are passed in the function to make sure the pointer isn't a NULL pointer, and that the contents of the sentence is simply the '\0' character indicating an empty-string)
An easy way to do this (after you have tested the input string), is to set up a continual loop, that repeatedly read the characters of a word, checks if it is the word to print (if so it prints), and if not read and discard all the non-alpha characters before the next word, and then repeats.
Something simple like the following works. It takes the sentence (or updated position within the sentence) and the index for the word to print zero-indexed, e.g. (0, 1, 2, ...) and then loops a described above.
(note: you can change the zero-index scheme to a 1, 2, 3, ... word-number scheme by initializing n=1; instead of 0 -- but since everything in C is zero indexed, that is left to you)
#include <stdio.h>
#include <ctype.h>
int prnword (const char *s, int nwrd)
{
int n = 0; /* word counter */
char *p = s; /* pointer to s */
if (!s || !*s) { /* test s not NULL and not empty */
fprintf (stderr, "error: string NULL, empty or at end.\n");
return 0;
}
for (;;) { /* loop continually until exit condition reached */
while (*p && isalpha(*p)) { /* loop over chars in s */
if (n == nwrd) /* if requested index */
putchar (*p); /* print all chars */
p++; /* increment pointer */
}
while (*p && !isalpha(*p)) /* iterate find next alpha */
p++;
if (++n > nwrd) /* if past our word, break */
break;
if (!*p) /* if end reached, break */
break;
}
if (n <= nwrd) { /* check request exceeds avaialble words */
fprintf (stderr, "error: request word '%d' "
"exceeds available wprds indexes.\n", nwrd);
return 0;
}
putchar ('\n'); /* tidy up with new line */
return p - s; /* return number of chars to next alpha */
}
int main (void) {
char str[] = "hello big panda";
int nchars = 0;
/* example -- all words in order
* passing update string position
*/
nchars = prnword (str, 0);
nchars += prnword (str + nchars, 0);
nchars += prnword (str + nchars, 0);
putchar ('\n');
/* request exceed available zero-based word indexes */
nchars = 0;
nchars += prnword (str, 3);
putchar ('\n');
/* print 2nd word only */
nchars = 0;
nchars = prnword (str, 1);
putchar ('\n');
return 0;
}
Example Use/Output
Note the first block of calls to prnword print each of the words in the sentence, saving the number of characters returned by prior calls and using that to start the function reading the 1st character of the desired word, meaning you are always looking for word index 0.
The second call intentionally gives an index one past the last word to force handling the error.
And finally, the last call simply says "Go print word 2" (index 1) starting from scratch.
Example Use/Output
$ ./bin/words
hello
big
panda
error: request word '3' exceeds available wprds indexes.
big
Look things over and let me know if you have questions.
I'm working on a client-server program, where initial step involves parsing the request from client on the server side. The input would look like this.
INSERT A->B B->C; QUERY A B; RESET;
So there are three different commands and they are separated by ';'. RESET option has no parameters. INSERT might have any number of parameter(which are space separated and each value separated by "->"). QUERY is again space separated. The server has to build a acyclic graph based on the input. So my problem is to parse this string into subsequent requests. I planned on using 'strtok' and when the final value is reached(for example 'A'), create a linked list of INSERTS(since the number of request is unknown). But my code is too big and I'm looking for a more concise solution for this problem.
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
typedef struct insert {
char event1;
char event2;
struct insert * next;
}insert,*insPtr;
typedef struct query {
char event1;
char event2;
struct query * next;
}query,*queryPtr;
typedef struct reset {
int status;
}reset,*rPtr;
void create_node(char *events) {
char event[2];
char *a,*str;
char *pch = strtok(events,"->");
while(pch != NULL) {
printf("%s\n",pch);
pch = strtok(NULL,"->");
}
}
int insert_parser(char *string) {
char *a, *b;
a = string;
b = "INSERT ";
while(*a == *b){
a++;
b++;
}
char *pch = strtok(a," ");
while(pch){
printf("%s\n",pch);
pch = strtok(NULL," ");
}
return(0);
}
int parse_for_values (char* command) {
int value;
if (strstr(command, "INSERT") !=NULL ) {
printf("%s\n",command);
printf ("Insert command found\n");
value = 1;
} else if(strstr(command, "QUERY") !=NULL) {
printf("%s\n",command);
printf ("Query command found\n");
value = 2;
} else if(strstr(command, "RESET") != NULL) {
printf ("Reset command found\n");
printf("%s\n",command);
value = 3;
} else {
printf("unknown command:%s:\n",command);
printf("Unknown command\n");
return(1);
}
switch(value) {
case 1:
insert_parser(command);
break;
case 2:
break;
case 3:
break;
}
return(0);
}
int parse_for_command(char *input) {
char *ptr;
input = strtok(input,"\n");// this strtok is to remove the trailing '\n' in the string
ptr = strtok(input,";");
// printf("%s\n",ptr);
char *cmdPtr;
while(ptr != NULL) {
cmdPtr = ptr;
parse_for_values(cmdPtr);
// printf("%s",ptr);
ptr = strtok(NULL, ";"); //NULL as first argument tells strtok to work on internally held value
}
return(0);
}
int main() {
char input[100];
printf("Enter the input\n");
fgets(input, 100, stdin);
//printf("%s",input);
char *inp = input;
inp = strtok(inp,"\n");
create_node(inp);
//parser(input,"INSERT ", "->");
//parse_for_command(input);
return(0);
}
You have to find individual tokens (lexical analysis) and analyse this sequence of tokens (syntactic analysis). Either you write these procedures manually, or you formally specify syntax of your language and employ existing tools to create the required C code automatically (see flex and bison).
I'm not 100% clear on what you are asking, but the separation of the input commands into individual strings can be done with a single set of calls to strtok. Additionally, the time to remove the trailing newline resulting from the call to fgets is immediately after the call to fgets so you do not have dangling newlines hanging off the end of the string. (e.g.):
fgets(input, 100, stdin);
len = strlen (input); /* get length of str */
if (input[len - 1] != '\n') /* no '\n', input too long */
input[--len] = 0; /* null-terminate */
Separating the strings with strtok can make use of a for loop to handle the initial and subsequent calls to NULL in a single call. For purposes of the example, I've just used a statically declared character array to hold the separated strings, but you can just as well pass p to whatever type list or abstraction you desire. If your intent was to further separate the individual components of each command, then a simple while loop walking a pointer (or two) down the separated INSERT or QUERY command will work. Below is the example, if your intent was different, please let me know.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define NCMD 10
#define LCMD 64
int main (void) {
char input[] = "INSERT A->B B->C; QUERY A B; RESET;";
char command[NCMD][LCMD] = {{0}};
char *p = NULL;
size_t i = 0;
size_t ncmd = 0;
for (p = strtok (input, ";"); p; p = strtok (NULL, ";")) {
while (*p == ' ') p++;
strncpy (command[ncmd++], p, LCMD);
}
printf ("\n The separated commands are:\n\n");
for (i = 0; i < ncmd; i++)
printf (" command[%zu] : %s\n", i, command[i]);
printf ("\n");
return 0;
}
Output
$ ./bin/parseinput
The separated commands are:
command[0] : INSERT A->B B->C
command[1] : QUERY A B
command[2] : RESET
Note: the length validation on p as well as the limit check on ncmd were intentionally omitted for purposes of the example.