search for char sequences in C within a loop - c

I am trying to find the most efficient way to find tags in a given char array. These "tags" are a sequence of chars located randomly within a char array.
Here is an example: given a char array: {'a','s','s','1','m','s','g','e','x','x','r','s','1',...}. the tag "ss1" indicates the beginning of a message which contains every char until a sequence of "exx" is found, which a tag for the end of the message, and it keeps searching the array for the next sequence of "s1". In this example, the message here is "msg".
my initial design was (pseudo code)
while(array[i] != '\0')
if(array[i] == 's' && array[i+1] == 's' && array[i+2] == '1' )
int j = i+3;
if(array[j] != '\0' && array[j] == 'e' && array[j+1] == 'x' && array[j+2] == 'x' )
i += 3;
else
print(array[j]);
else i++; //next char
may be a little flawed, but you get the idea. Is there a better way? i thought about strstr but since I'm dealing with a char array here and still looping even after deciphering a message, I thought it might be difficult to implement.

Try to maintain a state denoting how much of the tag start and end you have found. Something like this: (This code will work even if the message within the tag is of arbitrary length)
int state = 0;
int found = 0;
int i = 0,j;
int msgStartIndex;
int msgEndIndex;
while(array[i]){
if((array[i] == 's' && state == 0) || (array[i] == 's' && state == 1) || (array[i] == '1' && state == 2) ){
state++;
if(!found && state == 3){
msgStartIndex = i+1;
found = 1;
}
}
else if(!found && (array[i] = 's' && state == 2))
state = 2;
else if(!found)
state = 0;
if((array[i] == 'e' && state == 3) || (array[i] == 'x' && state == 2) || (array[i] == 'x' && state == 1) ){
state--;
if(found && state == 0){
found = 0;
msgEndIndex = i-3;
for(j=msgStartIndex; j < msgEndIndex+1; j++)
printf("%c",array[j]);
printf("\n");
}
}
else if(found && (array[i] == 'e') && (state == 2 || state == 1))
state = 2;
else if(found)
state = 3;
i++;
}
Updated answer for start tag st1 and end tag ex1
int state = 0;
int found = 0;
int i=0,j;
int msgStartIndex;
int msgEndIndex;
while(array[i]){
if((array[i] == 's' && state == 0) || (array[i] == 't' && state == 1) || (array[i] == '1' && state == 2) ){
state++;
if(!found && state == 3){
msgStartIndex = i+1;
found = 1;
}
}
else if(!found && (array[i] = 's' && (state == 1 || state == 2)))
state = 1;
else if(!found)
state = 0;
if((array[i] == 'e' && state == 3) || (array[i] == 'x' && state == 2) || (array[i] == '1' && state == 1) ){
state--;
if(found && state == 0){
found = 0;
msgEndIndex = i-3;
for(j=msgStartIndex; j < msgEndIndex+1; j++)
printf("%c",array[j]);
printf("\n");
}
}
else if(found && (array[i] == 'e') && (state == 2 || state == 1))
state = 2;
else if(found)
state = 3;
i++;

Related

error in finding no. of vowels in a string

//schecking no of vowels in a string.
#include <stdio.h>
#include <string.h>
void printstring();
int main() {
char sai[8]; //allows 8 charecters.
char a,e,j,o,u; //I have used j as i have already used i for iteration
fgets(sai, 8, stdin); //going to enter my name
char *ptr = sai; ///setting pointer for string
int i,t = 0;
for(i = 0;i <= 7; i++){
if(*(ptr+i) == a) || (*(ptr+i) == e) || (*(ptr+i) == j) || (*(ptr + i) == o) || (*(ptr + i) == u){
t = t+1;
}
else {
t = t;
}
}
printf("%d", t);
}
OUTPUT:
The compiler generated an error:
jill.c: In function 'main':
jill.c:12:23: error: expected expression before '||' token
if(*(ptr+i) == a) || (*(ptr+i) == e) || (*(ptr+i) == j) || (*(ptr + i) == o) || (*(ptr + i) == u){
^~
I expected the number of vowels as output, but an error has occured. Where am I going wrong?
Below listed points are incorrect in your code
Englobe the full condition between brackets in your if condition is missing
Single quotes are missing for character in your if statements. please go through here more explanation.
As comment from  Ted Lyngmo, Craig Estey a,e,j,o,u are uninitialized.
if (*(ptr + i) == a) ||(*(ptr + i) == e) || (*(ptr + i) == j) || (*(ptr + i) == o) || (*(ptr + i) == u)
changed to
if((ptr[i] == 'a') || (ptr[i] == 'e') || (ptr[i] == 'j') || (ptr[i] == 'o') || (ptr[i] == 'u'))
code
//schecking no of vowels in a string.
#include <stdio.h>
#include <string.h>
void printstring();
int main()
{
char sai[8];//allows 8 charecters.
char a,e,j,o,u; //I have used j as i have already used i for iteration
fgets(sai, 8, stdin); //going to enter my name
char *ptr = sai; ///setting pointer for string
int i,t = 0;
for(i = 0;i <= 7; i++)
{
if((ptr[i] == 'a') ||
(ptr[i] == 'e') ||
(ptr[i] == 'j') ||
(ptr[i] == 'o') ||
(ptr[i] == 'u'))
{
t = t+1;
}
else
{
t = t;
}
}
printf("%d", t);
}
Link for below Output:
apple
2

Silver and Gold GFG problem (https://practice.geeksforgeeks.org/contest/job-a-thon-for-internship/problems) it is the link of above problem

I have write code and it producing correct output but it can not fill all requirements please optimize my code or give me some suggestion.
It is my code...
// it is my code it produces correct output but not complete requirement.
public String flipCoins(int N,String s) {
char ch[] = new char[N];
for(int i=0;i<N;i++){
ch[i] = s.charAt(i);
}
for(int i=1;i<N;i++){
if(ch[i] == '1' || ch[i-1] == '1'){
ch[i] = '1';
ch[i-1] = '1';
}else if(ch[i] == '0' || ch[i-1] == '0'){
ch[i] = '1';
ch[i-1] = '1';
}else if(ch[i] == '0' || ch[i-1] == '1'){
ch[i] = '1';
ch[i-1] = '0';
}else if(ch[i] == '1' || ch[i-1] == '0'){
ch[i] = '0';
ch[i-1]='1';
}
}
int count = 0;
for(char c: ch){
if(c == '1')
count++;
}
if(count == N)
return "Yes";
else
return "No";
}
What I learned from the question is that you can flip any number of time, so
the question boils down to find whether there are even nos. of zeroes or not beacuse you can swap 00 pair to make 11 else it would always be 10 or 01

An error is generated regarding 'lvalue'.what is the reason?

I want to make a program to check if there are any numbers, uppercase and lowercase letters in my password.But,an error about 'lvalue' will occur when this code is executed. What is the reason?
#include <stdio.h>
#include <string.h>
int main(void)
{
char passwd[99];
printf("make a password:");
gets_s(passwd,99);
int num_count = 0, up_count = 0, down_count = 0;
while(1)
{
for (int i = 0; passwd[i] != NULL; i++)
{
if ('0' <= passwd[i] && passwd[i] <= '9')
num_count++;
else if ('a' <= passwd[i] && passwd[i] <= 'z')
{
down_count++;
}
else if ('A' <= passwd[i] && passwd[i] <= 'Z')
{
up_count++;
}
}
if (num_count == 0 || up_count == 0 || down_count = 0)
printf("make the password again!");
else
{
break;
}
}
getch();
return 0;
}
num_count == 0 || up_count == 0 || down_count = 0
should be
num_count == 0 || up_count == 0 || down_count == 0
To explain the error, the statement you have is equivalent to the following:
( num_count == 0 || up_count == 0 || down_count ) = 0
An expression that can be found on the left-hand side of an assignment is called an lvalue, and the expression in parens is not a valid lvalue.

Array doesn't print the first letter in it [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 3 years ago.
Improve this question
I have an array formed from a text file imported by stdin.
The text file looks like this:
"Name"
"Number"
"Name"
"Number"
...
The entire code:
#include <stdio.h>
#include <string.h>
#include <ctype.h>
int main(int argc, char** argv)
{
//number of arguments
if (argc > 2)
{
fprintf(stderr, "Too many arguments\n");
return 1;
}
//check argument 1
{
if (argc == 2)
{
unsigned i = 0;
while (i < strlen(argv[1]))
{
if ((isdigit(argv[1][i])) == 0)
{
fprintf(stderr, "Enter a number\n");
return 1;
}
i++;
}
}
else
{
fprintf(stderr, "argument\n");
return -1;
}
}
//find \n and separate
int g = 0;
int c = 0;
char buffer[102];
char people[42][102];
char numbers[42][102];
while (fgets(buffer, sizeof buffer, stdin) != NULL)
{
if (g % 2 == 0)
{
strcpy(people[c], buffer);
//printf("%s", people[c]);
}
if (g % 2 == 1)
{
strcpy(numbers[c], buffer);
c++;
}
g++;
}
//convert and remove \n
char conv_people[42][102];
for (int i = 0; i < c; i++)
{
for (unsigned j = 0; j < strlen(people[i]); j++)
{
if (islower(people[i][j]) == 0 && people[i][j] != ' ' && people[i][j] != '.')
{
if (people[i][j] == '\n')
{
conv_people[i][j] = '\0';
}
people[i][j] = conv_people[i][j] + 32;
}
}
}
//covert to numbers
char conv[42][102];
for (int i = 0; i < c; i++)
{
for (unsigned j = 0; j < strlen(people[i]); j++)
{
if (conv_people[i][j] == ' ' || conv_people[i][i] == '.' || conv_people[i][i] == '\n' || conv_people[i][i] == '\0')
{
conv[i][j] = '0';
}
if (conv_people[i][j] == 'a' || conv_people[i][j] == 'b' || conv_people[i][j] == 'c')
{
conv[i][j] = '2';
}
if (conv_people[i][j] == 'd' || conv_people[i][j] == 'e' || conv_people[i][j] == 'f')
{
conv[i][j] = '3';
}
if (conv_people[i][j] == 'g' || conv_people[i][j] == 'h' || conv_people[i][j] == 'i')
{
conv[i][j] = '4';
}
if (conv_people[i][j] == 'j' || conv_people[i][j] == 'k' || conv_people[i][j] == 'l')
{
conv[i][j] = '5';
}
if (conv_people[i][j] == 'm' || conv_people[i][j] == 'n' || conv_people[i][j] == 'o')
{
conv[i][j] = '6';
}
if (conv_people[i][j] == 'p' || conv_people[i][j] == 'q' || conv_people[i][j] == 'r' || conv_people[i][j] == 's')
{
conv[i][j] = '7';
}
if (conv_people[i][j] == 't' || conv_people[i][j] == 'u' || conv_people[i][j] == 'v')
{
conv[i][j] = '8';
}
if (conv_people[i][j] == 'w' || conv_people[i][j] == 'x' || conv_people[i][j] == 'y' || conv_people[i][j] == 'z')
{
conv[i][j] = '9';
}
}
}
//compare
int i = 0;
while (i < c)
{
if (strstr(conv[i], argv[1]) != NULL)
printf("%s, %s", people[i], numbers[i]);
if (strstr(numbers[i], argv[1]) != NULL)
printf("%s, %s", people[i], numbers[i]);
i++;
}
return 0;
}
The program takes a list of people and their phone numbers and searches it using argv[1]
The output always omits the first capital letter in each word
So if the file contains a name like: Barrack Obama
the program returns arrack bama
The numbers and converted names are working fine
I didn't want to post the whole thing because it's extremely ugly.
I've run the code and John is output as Éohn. It likely comes from
people[i][j] = conv_people[i][j] + 32;
because you never set any values in conv_people[i] except a terminator.
If I add this first line in the loop
strcpy(conv_people[i], people[i]);
then is outputs
john
with a lower case initial letter.
Aside: it is safer and convenient to use
people[i][j] = tolower(conv_people[i][j]);
which doesn't even need to be tested to see if an uppercase letter was passed.

segmentation fault in array search C

I have this program that receives a char array with a number of messages bounded by tags. These "tags" are a sequence of chars located randomly within the char array.
Here is an example: given a char array: {'a','s','t','1','m','s','g','e','x','1','r','s','t','1','s','t','1','s','s','g','e','x','1','z'};. the tag "st1" indicates the beginning of a message which contains every char until a sequence of "ex1" is found, which is a tag for the end of the message, and it keeps searching the array for the next sequence of "st1" indicating the beginning of a new message. In this example, the messages are: "msg",and"st1ssg".
Here is my program - I keep getting a segmentation fault:
int main(int argc, char const *argv[])
{
char array[] = {'a','s','t','1','m','s','g','e','x','1','r','s','t','1','s','t','1','s','s','g','e','x','1','z'};
int state = 0;
int found = 0;
int i,j;
int msgStartIndex;
int msgEndIndex;
while(array[i]){
if((array[i] == 's' && state == 0) || (array[i] == 't' && state == 1) || (array[i] == '1' && state == 2) ){
state++;
if(!found && state == 3){
msgStartIndex = i+1;
found = 1;
}
}
else if(!found && (array[i] = 't' && state == 2))
state = 2;
else if(!found)
state = 0;
if((array[i] == 'e' && state == 3) || (array[i] == 'x' && state == 2) || (array[i] == '1' && state == 1) ){
state--;
if(found && state == 0){
found = 0;
msgEndIndex = i-3;
for(j=msgStartIndex; j < msgEndIndex+1; j++)
printf("%c",array[j]);
printf("\n");
}
}
else if(found && (array[i] == 'e' ) && (state == 2 || state == 1))
state = 2;
else if(found)
state = 3;
i++;
}
return 0;
}
You never bothered initializing your loop counter:
int i,j;
while(array[i]){
so you just start using whatever random garbage is in i to begin with. If that garbage happens to be bigger than the length of the array, boom goes your program.
Variable I was notr initialized and moreover the array is not zero-terminated.
int i,j;
/...
while(array[i]){
So the loop has undefined behavior.
You could keep a string in the array and use standard function strstr declared in header <string.h> to find the starting and ending tags.

Resources