0

I want the user to type a string that contains only 'P' and 'K' characters. So that's my string, declared inside the main function,

char string[30];

and that's a function that returns 1 if the string completes that criteria or 0 if it does not:

int isStringValid(char **string){
    int i=0;
    while(*(string+i)!='\0'){
        if(*(string+i)!='P' || *(string+i)!='K'){
            return 0;
        }
        ++i;
    }
    return 1;
}

I am getting the string from the user with scan f, but the isStringValid function does not seem to work properly. It returns only false whatever string I type!

int main(){
char string[30];

scanf("%s", string);
        if(isStringValid(&string)){
            printf("Job Done!\n");
        }else{
            printf("Not recognised!\n");
        }
}

Any ideas why its not working?

15
  • 1
    You should be passing in char *string rather than char **string. Commented Mar 1, 2016 at 13:40
  • 3
    BTW, you should use && there, not || (because 'P' != 'K'). Commented Mar 1, 2016 at 13:41
  • 1
    @barakmanos This usage of scanf() won't store newline characters. Commented Mar 1, 2016 at 13:43
  • 1
    int isStringValid(char * string) { return strlen(string) == strspn(string, "PK"); } Commented Mar 1, 2016 at 13:46
  • 5
    @DevSolar or even return !string[strspn(string, "PK")] ; Commented Mar 1, 2016 at 13:50

3 Answers 3

3

In isStringValid() function

  • The type of argument should be char* because it is normal to pass pointer to string to process.
  • K is undefined. 'K' is character code of K.
  • Write "If *(string+i) is neigher 'P' nor 'K'".
  • Using size_t for the counter is better in this case.

In main() function

  • You should specify void as arguments.
  • You should write return value explicitly for readability.
  • You should limit maximum length to read to avoid buffer overrun.
  • You should check if the reading is successful.
  • You should pass the pointer to the string since argument type of isStringValid() is changed.

corrected code:

#include <stdio.h>

int isStringValid(char *string){
    size_t i=0;
    while(*(string+i)!='\0'){
        if(!(*(string+i)=='P' || *(string+i)=='K')){
            return 0;
        }
        ++i;
    }
    return 1;
}

int main(void){
    char string[30];

    if (scanf("%29s", string) != 1){
        printf("Read error!\n");
    }else if(isStringValid(string)){
        printf("Job Done!\n");
    }else{
        printf("Not recognised!\n");
    }
    return 0;
}
Sign up to request clarification or add additional context in comments.

2 Comments

Now, you could take it one step forward and generate the format string "%29s" based on sizeof(string).
we could debate the input method until the cows come home... maybe fgets would be preferable, all depends on whether OP wants spaces to be significant, etc. etc.
2

Try this:

int isStringValid(char* str)
{
    int i;
    for (i=0; str[i]=='P' || str[i]=='K'; i++)
    {
    }
    if (str[i] == '\0')
        return 1;
    return 0;
}

6 Comments

You might also need to address OP's line if(isStringValid(&string)){
OK, I think I'll delete this answer due to @Skemelio's comment to the question (not really sure about OP's purpose).
nah don't delete it, the guy doesn't understand that passing char * allows the contents of the char array to be charged
@M.M: Yeah, there are several things that aren't really clear here, hard to address all of them... Also, I'm not really sure about the purpose, see my previous comment.
@Skemelio: No problem. BTW, at the end of the function, you can simply return str[i] == '\0'.
|
0
#include <stdio.h>

int Only_PK_present(char *str)
{
for(    ; *str == 'K' || *str == 'P'; str++ ) {;}
return !*str;
}

int Only_PK_present1(char *str)
{
for ( ; *str ; str++) {
        if (*str == 'K') continue;
        if (*str == 'P') continue;
        break;
        }
return !*str;
}

int Only_PK_present2(char *str)
{
do      {
        if (*str != 'K' && *str != 'P' ) break;
        } while (*str++);
return !*str;
}

// Or even shorter :

#include <string.h>

int Only_PK_present0(char *str)
{
return !str[strspn(str, "KP")];
}

int main(int argc, char **argv)
{
printf("%d %d %d %d\n"
        , Only_PK_present(argv[1])
        , Only_PK_present1(argv[1])
        , Only_PK_present2(argv[1])
        , Only_PK_present0(argv[1])
        );
return 0;
}

When compiled with at least -O2, GCC will inline strspn(), and produces the following beauty for Only_PK_present0():

.globl Only_PK_present0
        .type   Only_PK_present0, @function
Only_PK_present0:
        pushl   %ebp
        movl    %esp, %ebp
        movl    8(%ebp), %eax
        jmp     .L23
.L24:
        addl    $1, %eax
.L23:
        movzbl  (%eax), %edx
        cmpb    $75, %dl
        je      .L24
        cmpb    $80, %dl
        je      .L24
        testb   %dl, %dl
        sete    %al
        movzbl  %al, %eax
        popl    %ebp
        ret
        .size   Only_PK_present0, .-Only_PK_present0

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.