Thread: Using strcmp, char variable changes value?

  1. #1
    Registered User
    Join Date
    Dec 2007
    Posts
    28

    Using strcmp, char variable changes value?

    Ok, so I'm relatively new to this whole programming thing, but I have written a few programs before. I use Dev C++ as my IDE, running XP. In FreeBSD, I use gcc to compile and vim to write.
    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <windows.h>
    #include <string.h>
    
    int main (void)
    {
    	char a[21];
    	char b[21];
    	char c[99];
    	int d;
        FILE *syns;
        FILE *thes;
        FILE *alp;
        syns = fopen ( "syns", "r");
        thes = fopen ( "thes", "r");
        alp = fopen ( "alp", "w");
        fseek( syns, 0L, SEEK_SET );
        while(1==fscanf(syns,"&#37;s",a)) /*While there are words, take a word from the list*/
        {fseek( thes, 0L, SEEK_SET);/*go to beginning of thesaurus*/
         while(1==fscanf(thes,"%s",b)) /*While there are words in thesaurus, take one and...*/
         {
                                          if (!strcmp(a,b)) /*...Compare it to the word from the list. If they are the same,*/
                                          {
                                                   fprintf(alp,"%s- ",a);/*Print the word*/
                                                   for(d=0;d<=15;d++)/*Pick amount of synonyms*/
                                                   {
                                                                            fscanf(thes,"%s",c); /*take current word*/
                                                                            fprintf(alp,"%s, ",c);/*print it*/ 
                                                   }
                                                   fprintf(alp,"\n");/*Goto a newline when finished*/
                                          }
                                          
        }
    }
    return (0);
    }
    Input file (syns) contains the word 'hi'. thes is a thesaurus. Output file, alp, contains only "t- true_to_form, true_to_type, typal, typic, typical, unblamable, unexceptionable, usual, virtuous, warning, well-deserving, worthy, exemplification, allegorization, alphabet, art, "
    yeah, I know i should use malloc and other fun stuff. Right now I just want it to work.
    Last edited by Nicheter; 12-03-2007 at 06:01 PM.

  2. #2
    Registered User
    Join Date
    Oct 2001
    Posts
    2,129
    I'm having trouble figuring out what it is that you want the program to do. Your code is commented, but not beyond what the functions actually do. It would be better if you commented what and why and how the code was doing what it was doing, so that people can figure out what it is that you're tring to do.

    For example, are you aware that strcmp returns 0 if the two strings are equal? The way you have it commented right now, I can't tell what it is that you think that this program is doing.

  3. #3
    Registered User
    Join Date
    Oct 2006
    Location
    Canada
    Posts
    1,243
    ditto.

    i also dont understand what your trying to do, even with the comments (which, as mentioned, dont give us much information). what exactly is the problem? what is happening and what do you want to be happening?
    int strcmp(const char *s1, const char *s2);
    as you can see from the function prototype, the parameters are passed as constants, which means they can not be changed.

  4. #4
    Registered User
    Join Date
    Dec 2007
    Posts
    28
    I'm sorry, the program was made to take a list of words and print synonyms of it. The problem I am having is that the output is always the same, no matter what input I give it.
    The if (!strcmp (a,b)) is the same as if(0==strcmp(a,b)), no?
    Edited the first post for clarity in the if loop. Sorry.
    Last edited by Nicheter; 12-03-2007 at 06:02 PM.

  5. #5
    Registered User
    Join Date
    Oct 2006
    Location
    Canada
    Posts
    1,243
    i think they would have the same value, but i would put explicitly the '... == 0' rather than '!...'. also, i would print out every string that you read in and write out to the screen too, to be sure that what is being stored is correct. i would also output them surrounded by single quotes, to see if any other information (ie spaces) are being stored in the string, which would prevent the string from possibly being equal to 'itself'.

  6. #6
    Registered User
    Join Date
    Dec 2007
    Posts
    28
    Ok.
    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <windows.h>
    #include <string.h>
    
    int main (void)
    {
    	char a[21];
    	char b[21];
    	char c[99];
    	int d;
        FILE *syns;
        FILE *thes;
        FILE *alp;
        syns = fopen ( "syns", "r");
        thes = fopen ( "thes", "r");
        alp = fopen ( "alp", "w");
        fseek( syns, 0L, SEEK_SET );
        while(1==fscanf(syns,"&#37;s",a)) /*While there are words, take a word from the list*/
        {fseek( thes, 0L, SEEK_SET);/*go to beginning of thesaurus*/
        fprintf(alp,"'%s'",a);
         while(1==fscanf(thes,"%s",b)) /*While there are words in thesaurus, take one and...*/
         {
                                          if (strcmp(a,b)==0) /*...Compare it to the word from the list, if they are the same*/
                                          {
                                                   fprintf(alp,"%s- ",a);/*Print the word*/
                                                   for(d=0;d<=15;d++)/*Pick amount of synonyms*/
                                                   {
                                                                            fscanf(thes,"%s",c); /*take current word*/
                                                                            fprintf(alp,"%s, ",c);/*print it*/
                                                   }
                                                   fprintf(alp,"\n");/*Goto a newline when finished*/
                                          }
                                          
        }
    }
    return (0);
    }
    outputs
    'hi't- true_to_form, true_to_type, typal, typic, typical, unblamable, unexceptionable, usual, virtuous, warning, well-deserving, worthy, exemplification, allegorization, alphabet, art,
    I'm sorry, but I don't think my post was clear. The program does what it was supposed to do, but unfortunately has the error of adding the above loop multiple times.
    For example, the output of a file containing the words abortive bruit and contumelious results in
    Code:
    'abortive'abortive- barren, bootless, failed, failing, fruitless, futile, gainless, immature, ineffective, ineffectual, inefficacious, lame, manque, miscarried, miscarrying, nonremunerative, 
    t- true_to_form, true_to_type, typal, typic, typical, unblamable, unexceptionable, usual, virtuous, warning, well-deserving, worthy, exemplification, allegorization, alphabet, art, 
    'bruit't- true_to_form, true_to_type, typal, typic, typical, unblamable, unexceptionable, usual, virtuous, warning, well-deserving, worthy, exemplification, allegorization, alphabet, art, 
    'contumelious'contumelious- corrupt, crooked, cruel, cursing, damnatory, defamatory, degrading, denunciatory, deprecative, deprecatory, depreciative, depreciatory, derisive, derisory, derogative, derogatory, 
    t- true_to_form, true_to_type, typal, typic, typical, unblamable, unexceptionable, usual, virtuous, warning, well-deserving, worthy, exemplification, allegorization, alphabet, art, 
    Thus, the output is correct, but in the middle there are spasms of the wrong word, as well as the word not getting synonyms in some cases. Green= char a before second while loop. yellow = erroneous output.
    Last edited by Nicheter; 12-03-2007 at 06:37 PM.

  7. #7
    Registered User
    Join Date
    Oct 2001
    Posts
    2,129
    Quote Originally Posted by Nicheter View Post
    The if (!strcmp (a,b)) is the same as if(0==strcmp(a,b)), no?
    correct, but the ! operator implies that the result is a boolean context. but the function has no indication of which way it evaluates to... does equal or does not equal. so it's up to the reader to make that assumption, which can lead to the wrong assumption.

    It's the same thing, but it's just a matter of "commenting" the code. (not actual comments, of course)
    Quote Originally Posted by Nicheter View Post
    Edited the first post for clarity in the if loop.
    Better, but some more information is needed.

    What is the format of the thesaurus?

  8. #8
    Registered User
    Join Date
    Dec 2007
    Posts
    28
    the thesaurus is moby thesaurus, all spaces in words changed to be _ and all , replaced with a space
    Last edited by Nicheter; 12-03-2007 at 08:44 PM.

  9. #9
    Registered User
    Join Date
    Oct 2001
    Posts
    2,129
    What happens when there are more than 16 synonyms?

  10. #10
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    fscanf("&#37;s", ...) is bad. I recommend you use fgets instead. Or PROPERLY learn to use fscanf/scanf.
    Is there no FAQ entry on this? This seems a very common error and a very bad one, to boot.

  11. #11
    Registered User
    Join Date
    Dec 2007
    Posts
    28
    robwhit, i don't understand the question. What happens when there are more than 16 synonyms to what? Elysia, you suggest changing, but I did and now the code is even worse off then before. How do you suggest going about this? Also, my lack of prevention of overflow errors is a completely unrelated problem. I understand it's a good habit to get into, but right now I just wish to figure out the initial problem before moving on to causing more.
    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    int main (void)
    {
    	char a[21];
    	char b[21];
    	char c[99];
    	int d;
        FILE *syns;
        FILE *thes;
        FILE *alp;
        syns = fopen ( "syns.txt", "r");
        thes = fopen ( "thes", "r");
        alp = fopen ( "alp.txt", "w");
        fseek( syns, 0L, SEEK_SET );
        while(1==fscanf(syns,"&#37;s",a)) /*While there are words, take a word from the list*/
        {fseek( thes, 0L, SEEK_SET);/*go to beginning of thesaurus*/
        fprintf(alp,"'%s'\t",a);
         while(fgets(b,22,thes) !=NULL) /*While there are words in thesaurus, take one and...*/
         {
                                          if (strcmp(a,b)==0) /*...Compare it to the word from the list, if they are the same*/
                                          {
                                                   fprintf(alp,"%s- ",a);/*Print the word*/
                                                   for(d=0;d<=15;d++)/*Pick amount of synonyms*/
                                                   {
                                                                            fscanf(thes,"%s",c); /*take current word*/
                                                                            fprintf(alp,"%s, ",c);/*print it*/
                                                   }
                                                   fprintf(alp,"\n");/*Goto a newline when finished*/
                                          }
                                          
        }
    }
    return (0);
    }
    Last edited by Nicheter; 12-04-2007 at 03:28 PM.

  12. #12
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,660
    > char b[21];
    > fgets(b,22,thes)
    Your problem IS buffer overflow, not merely some minor inconvenience you can fix later.
    Lying to fgets about the size of your buffer is no better than using gets().
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  13. #13
    Registered User
    Join Date
    Dec 2007
    Posts
    28
    Ok, back to fscanf code, which worked somewhat. Someone explain how fgets should be used in this situation, please? Fscanf is more suitable because it searches up until whitespace, which is what I want to happen. fgets will take whatever amount you tell it to.
    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    int main (void)
    {
    	char a[21];
    	char b[50];
    	char c[99];
    	int d;
        FILE *syns;
        FILE *thes;
        FILE *alp;
        syns = fopen ( "syns.txt", "r");
        thes = fopen ( "thes", "r");
        alp = fopen ( "alp.txt", "w");
        fseek( syns, 0L, SEEK_SET );
        while(1==fscanf(syns,"&#37;s",a)) /*While there are words, take a word from the list*/
        {fseek( thes, 0L, SEEK_SET);/*go to beginning of thesaurus*/
         while(1 ==fscanf(thes,"%s",b))/*While there are words in thesaurus, take one and...*/
         {
                                          if (strcmp(a,b)==0) /*...Compare it to the word from the list, if they are the same*/
                                          {
                                                   fprintf(alp,"%s- ",a);/*Print the word*/
                                                   for(d=0;d<=15;d++)/*Pick amount of synonyms*/
                                                   {
                                                                            fscanf(thes,"%s",c); /*take current word*/
                                                                            fprintf(alp,"%s, ",c);/*print it*/
                                                   }
                                                   fprintf(alp,"\n");/*Goto a newline when finished*/
                                                   a[1]="1";
                                          }
        }
    }
    return (0);
    }
    EDIT: Okay, so changing the size of b solves the problem. Now it works perfectly. Added the a[1]="1" to keep the if statement from evaluating true more than once.
    Last edited by Nicheter; 12-04-2007 at 05:17 PM.

  14. #14
    Registered User
    Join Date
    Oct 2001
    Posts
    2,129
    Quote Originally Posted by Nicheter View Post
    robwhit, i don't understand the question. What happens when there are more than 16 synonyms to what?
    nevermind, I didn't quite get what your fseek was doing there. It's not a problem.

  15. #15
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Quote Originally Posted by Nicheter View Post
    Code:
    while(1==fscanf(syns,"%49s",a))
    Then at least do that, so you won't get buffer overflows.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Seg Fault in Compare Function
    By tytelizgal in forum C Programming
    Replies: 1
    Last Post: 10-25-2008, 03:06 PM
  2. How do i un-SHA1 hash something..
    By willc0de4food in forum C Programming
    Replies: 4
    Last Post: 09-14-2005, 05:59 AM
  3. Problem with a char variable set as a letter
    By 7smurfs in forum C++ Programming
    Replies: 6
    Last Post: 12-10-2004, 01:25 PM
  4. String sorthing, file opening and saving.
    By j0hnb in forum C Programming
    Replies: 9
    Last Post: 01-23-2003, 01:18 AM
  5. How do you search & sort an array?
    By sketchit in forum C Programming
    Replies: 30
    Last Post: 11-03-2001, 05:26 PM