C - scanf doesn't stop looping in string input - c

i'm making a small test to see if a word is inside another, and i want to return the index where that word begins.
Example: if i check "um" inside "amolum" the return value should be 4(position of the leter "u" where the word begins.
This is what my code looks like:
(...)
int cad_look_str (char s1[], char s2[]) {
int indS1 = 0, indS2 = 0;
while (s1[indS1]!='\0'|| s2[indS2]!='\0') {
if (s1[indS1]==s2[indS2]) {
indS1++;
indS2++;
}
else indS1=0;
}
if (s2[indS2]=='\0' && s1[indS1]!='\0') return -1;
else return indS2-strlen (s1);
}
void main () {
char s[100];
char s1[100];
scanf ("%s",s);
scanf ("%s",s1);
printf ("%d \n", cad_look_str(s1,s) );
}
The problem is that when i compile this, it doesn't stop looping on scanf... It just continues to ask for strings.
If i put cad_look_str(s1,s1) on the last line, it works fine... Why is this happening?
Regards

Your initial loop condition will never terminate if the first characters don't match your comparison test within your if statement.
The 'while' loop checks to ensure the current character positions (both 0 on first pass) are non-terminators. If they're not, and they're not equal, indS1 is reset to its starting position. indS2 never changes, thus the while condition is unchanged.
Might look at some other string functions to accomplish your task unless the scanning is a mandatory component for some reason.

Index of second string should be incremented in the else part also.
if (s1[indS1]==s2[indS2])
{
indS1++; indS2++;
}
else {
indS1=0;
indS2++;
}

changed cad_look_str() for situations like s1 : gdgddadada, s2 : dadada
int cad_look_str (char s1[], char s2[]) {
int indS1 = 0, indS2 = 0;
int flag = 0;
while (s1[indS1]!='\0'&& s2[indS2]!='\0') {
if (s1[indS1]==s2[indS2]) {
indS1++;
indS2++;
flag = 1;
}
else
{
indS1=0;
indS2++;
if(flag) indS2--; // to work with srtrings s1: gdgddadada s2: dadada
flag = 0;
}
}
if (s2[indS2]=='\0' && s1[indS1]!='\0') return -1;
else return indS2-strlen (s1);
}

Related

Finding indexes where substring is present

So right now my code checks if the sub string is present in the code and returns true or false, I would like to find where these substrings are located in the total string. how can you implement that.
#include <stdio.h>
#include <stdbool.h>
bool checksub(const char *strng,const char *subs){
if (*strng=='\0' && *subs!='\0'){
return false;
}
if (*subs=='\0'){
return true;}
if (*strng==*subs){
return checksub(strng+1,subs+1);
}
return false;
}
bool lsub(char *strng,char *subs){
if (*strng=='\0'){
return false;
}
if (*strng==*subs){
if (checksub(strng,subs)){
return 1;
}
}
return lsub(strng+1,subs);
}
int main(){
printf("%d\n",checksub("ababuu","ab"));
printf("%d\n",checksub("the bed bug bites","bit"));
return 0;
}
First you should get rid of recursion since it's often slow and dangerous, for nothing gained.
A (naive) version of strstr that returns an index rather than a pointer might look like this:
int strstr_index (const char* original, const char* sub)
{
int index = -1;
for(const char* str=original; *str!='\0' && index==-1; str++)
{
for(size_t i=0; str[i]==sub[i] && str[i]!='\0'; i++)
{
if(sub[i+1] == '\0')
{
index = (int)(str - original);
break;
}
}
}
return index;
}
This returns -1 if not found, otherwise an index.
It iterates across the string one character at a time.
When a character match with the sub string is found, it starts executing the inner loop as well.
If the inner loop continues to find matches all the way to the end of the sub string, then we found a match.
The index can be obtained by pointer arithmetic: the start address of the found sub string minus the start of the string. The result of that subtraction is strictly speaking a special integer type called ptrdiff_t, but I used int to simplify the example.

Function looping when zero is entered

I have a user_get_movement_index function that prompts user to enter a position 0 to 8 as part of a tic-tac-toe game.
This movement index is passed to is_position_empty where it determines if the movement index is invalid or the movement index is already taken, both shows an error message and returns false to trigger a recursion of user_get_movement_index.
Functions loop correctly when the same number is entered twice, and behave as expected when any other number is entered but 0.
The problem is when 0 is entered its causes a loop of the error message of invalid position.
I don't understand how it can be looping from within is_position_empty.
How is it not prompting user for input on each loop?
Why is 0 causing this loop?
Is it because we are comparing 0 < 0 in is_position_empty?
I'm new to C and stack overflow so please forgive my formatting, understanding and terrible code.
//--------------------------------------------------
// 05. FUNCTION my_getchar (IMPLEMENTED)
//--------------------------------------------------
char my_get_char() {
//1. We create the variable to be returned
char res = ' ';
//2. We create an extra variable to consume any other characters entered until a return is pressed
boolean line_consumed = False;
char dummy_char = ' ';
//3. We consume the first char entered, i.e., the one we are interested at
res = getchar();
//4. While still there are remaining characters
while (line_consumed == False) {
//4.1. We consume the next character
dummy_char = getchar();
//4.2. If the new character is the end of line one, we can ensure we have consumed the entire line.
if (dummy_char == '\n')
line_consumed = True;
}
//5. We return res
return res;
}
//------------------------------------
// 06. FUNCTION is_position_empty
//------------------------------------
boolean is_position_empty(game* g, int pos) {
//1. We create the variable to be returned
boolean res = False;
//2. We check if the index is a valid one and if the board is empty at that index.
//If it is valid and free, we return True.
//Otherwise, we return False and write a warning message.
int row= pos/3;
int column = pos%3;
if (pos<0 || pos>8){
printf("\t Invalid Position. Try again!\n\n");
return res;
}
else if (g->board[row][column]=='X' || g->board[row][column]=='O'){
printf("\t This postion is already busy. Try Again!\n\n");
return res;
}
else{
res=True;
return res;
}
}
//---------------------------------------
// 07. FUNCTION user_get_movement_index
//---------------------------------------
int user_get_movement_index(game* g) {
//2. We create a boolean variable to control that we have received a valid movement index.
boolean validMove=False;
//3. We create a char variable to control the index we are receiving by keyboard.
char indexChar;
int indexInt;
//We print a message asking for a new movement.
printf(" Enter a position 0 to 8: ");
//We call to my_get_char to get the index and we convert it to an integer.
indexChar=my_get_char();
indexInt=indexChar-'0';
//We call to is_position_empty to check that the index is a valid one.
validMove=is_position_empty(g, indexInt);
if (validMove==True)
return indexInt;
else
return user_get_movement_index(g);
}
Working Correctly
Working Correctly
Looping
I have boolean defined as the following:
enum Bool { False, True };
typedef enum Bool boolean;
When I initialise all elements of the matrix as 'a', the problem still persists.
When a valid movement is entered, process_movement function is called and it initialises the corresponding element of board to either an 'X' or 'O'.
char mark;
if (g->status==1)
mark='X';
else
mark='O';
int row = pos/3;
int column = pos%3;
g->board[row][column]=mark;
By adding an extra printf within is_position empty, I can tell that the whole function is looping, but it seems to not be exiting is_position_empty as the printf from the function it returns to user_get_movement is not being printed. How is this possible? There is only a loop in user_get_movement and none in is_position_empty, and only loops for 0?
the following proposed code:
is missing the main() function
is missing the function to determine if there was a winner and whom won
is missing the definition of game
does not have any unexpected looping
avoids the problem caused by having a 'recursive' function
and now the proposed code:
#include <stdio.h> // getchar()
#include <stdbool.h> // bool, true, false
#include <ctype.h> // isdigit()
// prototypes
int my_get_char( void );
bool is_position_empty(game* g, int pos);
int user_get_movement_index(game* g);
//--------------------------------------------------
// 05. FUNCTION my_getchar (IMPLEMENTED)
//--------------------------------------------------
int my_get_char()
{
//1. We create the variable to be returned
//3. We consume the first char entered, i.e., the one we are interested at
int res = getchar();
//4. While still there are remaining characters
while ( '\n' != getchar() );
//5. We return res
return res;
}
//------------------------------------
// 06. FUNCTION is_position_empty
//------------------------------------
bool is_position_empty(game* g, int pos)
{
//2. We check if the index is a valid one and if the board is empty at that index.
//If it is valid and free, we return True.
//Otherwise, we return False and write a warning message.
int row= pos/3; = 0
int column = pos%3; = 0
if (pos<0 || pos>8)
{
printf("\t Invalid Position. Try again!\n\n");
return false;
}
else if (g->board[row][column]=='X' || g->board[row][column]=='O')
{
printf("\t This postion is already busy. Try Again!\n\n");
return false;
}
return true;
}
//---------------------------------------
// 07. FUNCTION user_get_movement_index
//---------------------------------------
int user_get_movement_index(game* g)
{
//3. We create a char variable to control the index we are receiving by keyboard.
int indexInt;
do
{
//We print a message asking for a new movement.
printf(" Enter a position 0 to 8: ");
//We call to my_get_char to get the index and we convert it to an integer.
indexInt = my_get_char();
if( isdigit( indexInt ) )
{
indexInt -= '0';
}
else
{
printf( "entry was not in the inclusive range: 0...8\n" );
continue;
}
//We call to is_position_empty to check that the index is a valid one.
} while( !is_position_empty(g, indexInt) );
return indexInt;
}

Unexpected behavior in C

This is the question I'm working on : http://www.geeksforgeeks.org/recursively-remove-adjacent-duplicates-given-string/
Here's my code in Java for one pass :
/*If a character isn't repeating, copy it to str[j].
* Find start and end indices of repeating characters. Recursively call again
* And starting position now should be end+1. Pass j and starting position */
public class removeDuplicates {
public static void main(String[] args)
{
char[] str = {'c','c'};
removeDups(str,0,0,0);
System.out.println(str);
}
public static void removeDups(char[] str,int j, int start,int flag)
{
/*Check if start character is repeating or not. If yes , then loop till you find
* another character. Pass that characters index(new start) into a recursive call*/
if(start == str.length-1)
{
if(flag!=1)
{
str[j] = str[start];
j++;
}
if(j<=str.length-1)
{
str[j] = '0';
}
}
while(start<str.length-1 && str[start]!='0')
{
if(str[start+1]!=str[start])
{
str[j] = str[start];
start++;
j++;
if(start==str.length-1) {removeDups(str,j,start,flag);}
}
else
{
char ref = str[start];
while(str[start]==ref)
{
if(start<str.length-1)
{
start++;
}
else
{
flag =1;
break;
}
}
removeDups(str,j,start,flag);
return;
}
}
}
}
This works as expected. Here I'm just trying to use a 0 instead of \0 character as in C. Now when I translate the code to C
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
void removeDups(char *str,int j, int start,int flag)
{
/*Check if start character is repeating or not. If yes , then loop till you find
* another character. Pass that characters index(new start) into a recursive call*/
if(start == strlen(str)-1)
{
if(flag!=1)
{
str[j] = str[start];
j++;
}
if(j<=strlen(str)-1)
{
str[j] = '\0';
}
}
while(start<strlen(str)-1 && str[start]!='0')
{
if(str[start+1]!=str[start])
{
str[j] = str[start];
start++;
j++;
if(start==strlen(str)-1) {removeDups(str,j,start,flag);}
}
else
{
char ref = str[start];
while(str[start]==ref)
{
if(start<strlen(str)-1)
{
start++;
}
else
{
flag =1;
break;
}
}
removeDups(str,j,start,flag);
return;
}
}
}
int main()
{
char str[] = "abcddcba";
int len =
while()
for(int i=0;str[i]!='\0';i++)
{
printf("%c",str[i]);
}
printf("\n");
}
The above code gives different results as compared to the Java code.Its virtually identical , just that I'm using strlen() instead of str.length(as in Java).
The interesting part is : if I change the portion to
if(j<=strlen(str)-1)
{
str[j] = '\0';
return;
}
it works perfectly. I've just added a return statement to the if statement.
Why is this happening ? Identical code producing different results in C and Java
You are using return statement and subsequently all code below that return is being excluded from running for that iteration.
Also, You may want to understand what is \0 is and how it's different than 0.
Here's link:
What does the \0 symbol mean in a C string?
In C, assigning a character in a string to '\0' changes the length, so strlen() will return a different result after that. In your Java code, you're using an array, and an array length never changes. You're setting the character to '0' instead of '\0', which are two different things, but even if you did set it to '\0', it still wouldn't change the length. I haven't examined your entire code, but this is one obvious thing that would cause different results.

Printing an array of structs in C

I'm trying to print an array of structs that contain two strings. However my print function does not print more than two indices of the array. I am not sure why because it seems to me that the logic is correct.
This is the main function
const int MAX_LENGTH = 1024;
typedef struct song
{
char songName[MAX_LENGTH];
char artist[MAX_LENGTH];
} Song;
void getStringFromUserInput(char s[], int maxStrLength);
void printMusicLibrary(Song library[], int librarySize);
void printMusicLibraryTitle(void);
void printMusicLibrary (Song library[], int librarySize);
void printMusicLibraryEmpty(void);
int main(void) {
// Announce the start of the program
printf("%s", "Personal Music Library.\n\n");
printf("%s", "Commands are I (insert), S (sort by artist),\n"
"P (print), Q (quit).\n");
char response;
char input[MAX_LENGTH + 1];
int index = 0;
do {
printf("\nCommand?: ");
getStringFromUserInput(input, MAX_LENGTH);
// Response is the first character entered by user.
// Convert to uppercase to simplify later comparisons.
response = toupper(input[0]);
const int MAX_LIBRARY_SIZE = 100;
Song Library[MAX_LIBRARY_SIZE];
if (response == 'I') {
printf("Song name: ");
getStringFromUserInput(Library[index].songName, MAX_LENGTH);
printf("Artist: ");
getStringFromUserInput(Library[index].artist, MAX_LENGTH);
index++;
}
else if (response == 'P') {
// Print the music library.
int firstIndex = 0;
if (Library[firstIndex].songName[firstIndex] == '\0') {
printMusicLibraryEmpty();
} else {
printMusicLibraryTitle();
printMusicLibrary(Library, MAX_LIBRARY_SIZE);
}
This is my printing the library function
// This function will print the music library
void printMusicLibrary (Song library[], int librarySize) {
printf("\n");
bool empty = true;
for (int i = 0; (i < librarySize) && (!empty); i ++) {
empty = false;
if (library[i].songName[i] != '\0') {
printf("%s\n", library[i].songName);
printf("%s\n", library[i].artist);
printf("\n");
} else {
empty = true;
}
}
}
I think the problem is caused due to setting : empty = true outside the for loop and then checking (!empty) which will evaluate to false. What I am surprised by is how is it printing even two indices. You should set empty = false as you are already checking for the first index before the function call.
The logic has two ways to terminate the listing: 1) if the number of entries is reached, or 2) if any entry is empty.
I expect the second condition is stopping the listing before you expect. Probably the array wasn't built as expected (I didn't look at that part), or something is overwriting an early or middle entry.
you gave the definition as:
typedef struct song
{
char songName[MAX_LENGTH];
char artist[MAX_LENGTH];
}Song;
the later, you write if (library[i].songName[i] != '\0') which really seems strange: why would you index the songname string with the same index that the lib?
so I would naturally expect your print function to be:
// This function will print the music library
void printMusicLibrary (Song library[], int librarySize) {
for (int i = 0; i < librarySize; i ++) {
printf("%s\n%s\n\n", library[i].songName,
library[i].artist);
}
}
note that you may skip empty song names by testing library[i].songName[0] != '\0' (pay attention to the 0), but I think it would be better not to add them in the list (does an empty song name make sens?)
(If you decide to fix that, note that you have an other fishy place: if (Library[firstIndex].songName[firstIndex] == '\0') with the same pattern)

Remove the duplicate from a String Using Pointers

#include<stdio.h>
char *removedps(char *x)
{
int Ar[256] = {0};
int ip=0;
int op=0;
char temp;
while(*(x+ip))
{
temp = (*(x+ip));
if (!Ar[temp]) {
Ar[temp] = 1;
*(x+ip) = *(x+op);
op++;
}
ip++;
*(x+op) = '\0';
}
return x;
}
int main()
{
char lo[] = "0001";
printf("%s",removedps(lo));
}
My code is not working
I have tried hard to see the error
All I GET IS the first character .
My idea is simple
make an array of 256 places
insert Zero into them
Then insert 1 for each character inside the string (on that position of the array)
your assignment looks to be the error here.
op is "out postiion", ip is "in position"
so it should be
*(x+op) = *(x+ip);
not the other way.
because *(x+op) = '\0';
is always run every iteration of the loop.
I'd probablly do it more like this ( using your method, which I probablly wouldn't use personally)
char *removedps(char *x)
{
int Ar[256] = {0};
char* start = x;
while(*x)
{
if (Ar[*x])
{ // remove the repeated character
memmove(x, x+1, strlen(x));
}
else
{
Ar[*x] = 1;
x++;
}
}
return start;
}
also, I'd name it remove_duplicate_chars or something, not a fan of cryptic abbreviations.
At the end of the loop, you do *(x+op)='\0';, and then, in the next iteration, you do *(x+ip)=*(x+op);, so from the 2sd iteration, you put there 0.
try do something like:
for (op=ip=0;x[ip];ip++) {
if (!Ar[x[ip]]++) x[op++]=x[ip];
}
x[op]=0;

Resources