выход из цикла for с возвращаемым значением strstr NULL - PullRequest
1 голос
/ 20 декабря 2011

Что я не получаю здесь?

Это работает довольно хорошо:

for ( i = 0; i < 5 && found != 0 ;++i ){ no difference than above
        found=strcmp( name, myContacts[i].cFirstName);
        printf(" i %d\n", i);
    }
printf(" \nName Found %s",  myContacts[i-1].cFirstName );

Но просто из любопытства я пытаюсь использовать также strstr ().

/*** This achieves the same functionality as above ***/

    for ( i = 0; i < 5  ;i++ ){
    found2=strstr( myContacts[i].cFirstName , name);
    printf(" i %d\n", i);
    if (found2 != NULL)
        {
        printf(" \nName Found %s",  myContacts[i].cFirstName );
        break;
        }
    }    

Это, однако, не работает:

for ( i = 0; i < 5 && found2 != '\0' ;i++ ){ //this does not work as above
for ( i = 0; i < 5 && found2 != NULL ;i++ ){ // this also is not wroking
        found2=strstr( myContacts[i].cFirstName , name);
}

printf(" \nName Found %s",  myContacts[i].cFirstName );

Заранее спасибо за ваши предложения.

Полный код:

# please take my codes with a grain of skepticism, I am still learning 
# i know of sizeof(), but I rather not use it just for the purpose of my exercise

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>

#define MAXBUFFERSIZE   10

typedef struct contact {

    char cFirstName[10];
    char cLastName[10];
    char cTelphone[12];

} address ; // end type

// function prototype
void printContacts( address * );
void printMenu();
char getChoice();
void storeContact( address [] ,  int *);
//int searchContact( address [] , char * );
void searchContact( address [] , char [] );

int main(){

    char cSelection = 0;
    address myContacts[5];
    char buffer[MAXBUFFERSIZE];

    int i ;
    // initialize array to be zeros
    for ( i = 0; i < 5 ; i++ ){
        strcpy(myContacts[i].cFirstName, "0");
        strcpy(myContacts[i].cLastName,"0");
        strcpy(myContacts[i].cTelphone,"0"); 
    }

    strcpy(myContacts[0].cFirstName, "Jonny");
    strcpy(myContacts[1].cFirstName, "Julia");
    strcpy(myContacts[2].cFirstName, "Claudia");
    strcpy(myContacts[3].cFirstName, "Aaron");
    strcpy(myContacts[4].cFirstName, "Sebastian");

    int iDel = -1 ; // store the position if one deleted
    int iCount = 0 ; // counter for position in the array, when 
                     // inserting names.

    while ( cSelection != '5' ) {
    printMenu();
    cSelection = getChoice();

    switch (cSelection) {
        case '1':
            printContacts( myContacts );    
            break;

        case '2':
            if ( ( iDel >= -1 ) && ( iCount < 5 ) ){
                //printf("\niCount is %d ", iCount);
                storeContact( myContacts, &iCount );
                iCount++;
                //printf("\nOutside storeContact, *Plocation %d", iCount );
                }
            if ( iCount >= 5 ) {
                printf("\nThe Memory is full, consider deleting some"\
                "Contacts");    
                }
            break;

        case '3':
            {            
            printf("\nEnter a name or part of a name to search:\n");
            fscanf(stdin, "%s", buffer);
            getchar(); // clear the last enter
            printf("\nThe line you entered was:\n");
            printf("%s\n", buffer);
            searchContact( myContacts, buffer );
            break;
            }       
        case '4':   
            //iDel=deleteContact( myContacts );
            break;

        }// end of switch
    }// end of while
    return 0;
} // end main

char getChoice(){

    char cSelection = 'q'; //for the menu
    /**** always scanf CHARS so you can check
     *    if digit or char !!! ****/

    scanf("%s", &cSelection);

    while ( strlen(&cSelection) != 1 ){
        printf("\nChoich not understood, enter a number again:");
        scanf("%s",&cSelection);
        }

    if ( isalpha(cSelection) ){
        printf( "You entered a letter of the alphabet\n" );
        cSelection = -1;
        printf( "Illegal choice !!!" );
      }

    return cSelection;
    } 

void printContacts( address * myContacts ){

    int i ;

    for ( i = 0; strcmp(myContacts[i].cFirstName,"0") != 0 && i < 5 ; i++ ){                                             
        printf("\nmyContacts[%d].cFirstName: %s", i, \
        myContacts[i].cFirstName );
    }// end for
}

void printMenu(){
    printf("\n\n\tSilly Phone Book\n\n");
    printf("\n\n1\tPrint Phone Book\n");
    printf("2\tAdd New Contact\n");
    printf("3\tSearch For Contact\n");
    printf("4\tDelete Contact\n");
    printf("5\tQuit\n");
    printf("\nSelect Action: ");
    }

//void storeContact( address myContacts[] ){ //syntactic sugar
void storeContact( address * myContacts,  int *Plocation ){ 

    char ch;                     /* handles user input */
    char buffer[MAXBUFFERSIZE];  /* sufficient to handle one line */
    int x = 0;
    x=*Plocation;

    ch = getchar(); // clear the last enter
    printf("Enter a name (<10 characters)\n");
    //ch = getchar();
    //char_count = 0;
    //while( (ch != '\n')  && (ch != EOF ) &&  (char_count < MAXBUFFERSIZE)) {
        //buffer[char_count++] = ch;
        //ch = getchar();
    //}
    //buffer[char_count] = 0x00;      /* null terminate buffer */

    //fgets(buffer,11,stdin);

    fscanf(stdin, "%s", buffer); /* read from keyboard */

    printf("\nThe line you entered was:\n");
    printf("%s\n", buffer);

    //TODO: add check that string is not too long!!!
    // if we do that, the code won't blow here ?

    strcpy(myContacts[x].cFirstName, buffer);    
} 

//int searchContact( address * myContacts,    char name[] ){
void searchContact( address * myContacts,    char * name ){
    int found;
    char *found2;
    //printf("\nHey dude im buffer from inside searchContact: %s", name);
    // iterate throught the array, print possible matches
    int i = 0;


    //for ( i = 0; i < 5 && found != 0 ;i++ ){
    //for ( i = 0; i < 5 && found != 0 ;++i ){ no difference than above
        //found=strcmp( name, myContacts[i].cFirstName);
        //printf(" i %d\n", i);
    //}
    //printf(" \nName Found %s",  myContacts[i-1].cFirstName );

    /*** This achieves the same functionality as above 

    for ( i = 0; i < 5  ;i++ ){
    found2=strstr( myContacts[i].cFirstName , name);
    printf(" i %d\n", i);
    if (found2 != NULL)
        {
        printf(" \nName Found %s",  myContacts[i].cFirstName );
        break;
        }
    }    ***/

    for ( i = 0; i < 5 && &found2 != '\0' ;i++ ){ //this does not work as above
        found2=strstr( myContacts[i].cFirstName , name);
        printf("found %p i %d\n", found2, i);
        //printf(" \nName Found %s",  myContacts[i].cFirstName );
    }

    //return found;
} // end of searchContacts  if ( isalpha(cSelection) ){
        printf( "You entered a letter of the alphabet\n" );
        cSelection = -1;
        printf( "Illegal choice !!!" );
      }

    return cSelection;
    } 

void printContacts( address * myContacts ){

    int i ;

    for ( i = 0; strcmp(myContacts[i].cFirstName,"0") != 0 && i < 5 ; i++ ){                                             
        printf("\nmyContacts[%d].cFirstName: %s", i, \
        myContacts[i].cFirstName );
    }// end for
}

void printMenu(){
    printf("\n\n\tSilly Phone Book\n\n");
    printf("\n\n1\tPrint Phone Book\n");
    printf("2\tAdd New Contact\n");
    printf("3\tSearch For Contact\n");
    printf("4\tDelete Contact\n");
    printf("5\tQuit\n");
    printf("\nSelect Action: ");
    }

//void storeContact( address myContacts[] ){ //syntactic sugar
void storeContact( address * myContacts,  int *Plocation ){ 

    char ch;                     /* handles user input */
    char buffer[MAXBUFFERSIZE];  /* sufficient to handle one line */
    int x = 0;
    x=*Plocation;

    ch = getchar(); // clear the last enter
    printf("Enter a name (<10 characters)\n");
    //ch = getchar();
    //char_count = 0;
    //while( (ch != '\n')  && (ch != EOF ) &&  (char_count < MAXBUFFERSIZE)) {
        //buffer[char_count++] = ch;
        //ch = getchar();
    //}
    //buffer[char_count] = 0x00;      /* null terminate buffer */

    //fgets(buffer,11,stdin);

    fscanf(stdin, "%s", buffer); /* read from keyboard */

    printf("\nThe line you entered was:\n");
    printf("%s\n", buffer);

    //TODO: add check that string is not too long!!!
    // if we do that, the code won't blow here ?

    strcpy(myContacts[x].cFirstName, buffer);    
} 

//int searchContact( address * myContacts,    char name[] ){
void searchContact( address * myContacts,    char * name ){
    int found;
    char *found2;
    //printf("\nHey dude im buffer from inside searchContact: %s", name);
    // iterate throught the array, print possible matches
    int i = 0;


    //for ( i = 0; i < 5 && found != 0 ;i++ ){
    //for ( i = 0; i < 5 && found != 0 ;++i ){ no difference than above
        //found=strcmp( name, myContacts[i].cFirstName);
        //printf(" i %d\n", i);
    //}
    //printf(" \nName Found %s",  myContacts[i-1].cFirstName );

    /*** This achieves the same functionality as above 

    for ( i = 0; i < 5  ;i++ ){
    found2=strstr( myContacts[i].cFirstName , name);
    printf(" i %d\n", i);
    if (found2 != NULL)
        {
        printf(" \nName Found %s",  myContacts[i].cFirstName );
        break;
        }
    }    ***/

    for ( i = 0; i < 5 && found2 != '\0' ;i++ ){ //this does not work as above
        found2=strstr( myContacts[i].cFirstName , name);
        printf("found %p i %d\n", found2, i);
        //printf(" \nName Found %s",  myContacts[i].cFirstName );
    }

    //return found;
} // end of searchContacts

Просто для полноты этой дискуссии я добавляю то, что, наконец, действительно сработало так, как я этого хотел. Это пришло после прохождения всех ответов, так что спасибо всем:

Я забыл инициализировать указатель:

char *found2=NULL;

Теперь следующий цикл работает как положено:

 for ( i = 0; i < 5 && !found2 ;i++ ){ //this does work as above

        found2=strstr( myContacts[i].cFirstName , name);
        printf("i %d\n", i);

    }
    printf("Name found %s", found2);

Я хотел эту функцию с помощью strstr (), потому что теперь я могу искать «Clau» и сопоставлять его с «Claudia». Это лучше для моих нужд, чем strcmp (), хотя я вполне уверен, что это можно сделать и с помощью strcmp (), с большей сложностью или лучшими навыками в Си, чем у меня.

Еще раз спасибо за ответы!

Ответы [ 3 ]

1 голос
/ 20 декабря 2011

не используйте циклы. При использовании strstr () вам просто нужно использовать его один раз, так:

found2=strstr( myContacts[i].cFirstName , name);
printf(" \nName Found %s",  found2 );

(не забудьте соответствующую проверку на ноль)

1 голос
/ 20 декабря 2011

С вашим состоянием в цикле for:

&found2 != '\0'

Вы хотите проверить, указывает ли found2 на NULL, как вы даже упомянули о себе, поэтому укажите это found2 != NULL. В противном случае вы сравниваете адрес из found2 с символом NUL ('\0'), что определенно не то, что вы хотите сделать.

Однако вы также ошибаетесь, утверждая, что фрагмент strstr имеет те же функции, что и фрагмент strcmp; две функции совершенно разные. Прочитать документацию по strstr.

Еще одна вещь, в вашем первом фрагменте "Name Found" всегда будет напечатана


В вашем коде также много других неправильных вещей, таких как:

scanf("%s", &cSelection);
...
while ( strlen(&cSelection)

cSelection объявляется как char, если вы хотите сохранить char в нем, используйте спецификатор формата %c. Если вы хотите прочитать целую строку, сделайте ее char массивом , и & не требуется при передаче адреса массива функции.

Те же враги для &cSelection, переданного strlen. Не имеет смысла по тем же причинам.


(f)scanf также небезопасен для чтения строк и может привести к переполнению буфера, вместо него следует использовать fgets(STRING, SIZE, stdin). В любом случае, просто включите предупреждения вашего компилятора, чтобы вы могли уловить все вышеперечисленное.

1 голос
/ 20 декабря 2011

Ваш found2 является char *.

Вы должны написать for (i = 0; i < 5 && !found2; i++) //etc etc

(или проверить на found2 в цикле и прервать, если не NULL)

...