Using STRING in C language

Discussion in 'Programmer's Corner' started by pujulde, Nov 29, 2014.

  1. pujulde

    Thread Starter Member

    Jul 24, 2013
    95
    1
    I want to write a piece of code in c language which can give me some result when the input string will coincide with some given value. [

    Code (Text):
    1.  
    2. #include <stdio.h>
    3. #include <string.h>
    4. int main()
    5. {
    6.     char names[124];
    7.     char  alex;
    8.     printf("enter password\n");
    9.     scanf("%s", names);
    10.     printf("input names is %s\n", names);
    11.     if(names == alex)
    12.     {
    13.         printf("open document\n");
    14.     }
    15.     else printf("there is no coincidence");
    16.     return 0;
    17. }
    18.  
    This code does not work can anybody gives me some advice or point to perfect resource. I want to compare the input value with "alex" for example. It seems to me that char alex is not serious, but I have no idea how to do it. Thanks in advance.

    Moderators note: please use code tags for pieces of code
     
    Last edited by a moderator: Dec 8, 2014
  2. shteii01

    AAC Fanatic!

    Feb 19, 2010
    3,399
    497
    names is an array. To properly call an array you need to use names[]

    So, you got it wrong:
    here scanf("%s", names);
    here printf("input names is %s\n", names);
    and here if(names == alex)


    Also you are using alex wrong. What you did is created variable alex. What is contained in that variable? Well, all you did is: char alex, meaning that you never assigned any "value" to the variable called alex. alex could contain zero or some random char.
     
  3. WBahn

    Moderator

    Mar 31, 2012
    17,788
    4,807
    You are doing a number of really bad things here, so let's look at them.

    First, let's use CODE tags to make things more readable:

    Code (Text):
    1.  
    2. #include <stdio.h>
    3. #include <string.h>
    4. int main()
    5. {
    6.     char names[124];
    7.     char  alex;
    8.     printf("enter password\n");
    9.     scanf("%s", names);
    10.     printf("input names is %s\n", names);
    11.     if(names == alex)
    12.     {
    13.         printf("open document\n");
    14.     }
    15.     else printf("there is no coincidence");
    16.     return 0;
    17. }
    18.  
    First issue:

    If you define a function that takes no arguments, then you should declare this explicitly by using a "void" parameter list.

    Next, you need to understand what variables, arrays, and strings are in C.

    Next:

    When you declare

    char alex;

    you are merely declaring a variable that can hold exactly one value of type char (which is an 8-bit value, though whether it is signed or unsigned is implementation specific).

    When you declare an array

    char names[124];

    you are declaring 124 variables of type char, each of which can hold one value of type char. These 124 variables are named names[0], names[1], ... names[122], names[123].

    But, in addition to declaring these 124 variables, you are also requiring the compiler to put all of them into a contiguous block of memory and creating an additional variable (it's not technically a variable, but that's good enough for this discussion), called "names" in this case, the value of which is the memory address at which the first variable in the array, names[0], is stored. The variable "names" is called a "pointer" because its value "points" to where something is stored in memory.

    Second issue:

    It is generally a good idea to #define constants and use them for array dimensions. This is so that you can key all of the places that need that information to a single definition.

    Third issue:

    Using scanf() to get input is an extremely dangerous thing to do and there really is no good reason to use it. The reason why it is dangerous (there are several, but we'll stick with the one that applies directly to this case) is that you pass the value of "names" to scanf(), which tells it where the target character array starts. But the function has absolutely no idea how big the array is. So if the person running your program enters more than 124 characters the scanf() function will be more than happy to store the excess in the memory beyond the array, which means overwriting memory that is being used by something else. This is called a "buffer overflow". If someone examines your program very carefully there is a good chance that they can craft a specific string that, when entered, causes the program to do something you would not approve of, such as give them root level privileges on your computer or launch a system utility or whatever. This is called a "buffer overflow attack" and is the most common type of attack (or at least it was as of a few years ago, but something else, such as SQL injection attacks, may have overtaken it, but I doubt it).

    A better function to use if fgets(). This takes three arguments: The first is a pointer to a character array, the second is the maximum number of characters to be written to the array, and the third is a pointer to a FILE structure. Since you are reading from the keyboard, you can use the predefined pointer 'stdin'.

    Now, what happens if someone tries to enter more than 124 characters (actually 123 characters since strings in C are NUL-terminated meaning that the last character of the string is a 0 to mark the end of the string)? Well, the first 123 characters are stored in the string, along with a NUL terminator, and then the remaining characters are retained in the input buffer. This can cause bad things to happen, too, but you can detect and deal with this pretty handily.

    How you detect it is that fgets() includes the newline character than terminates the input string and this will be the last character in the string that is stored. So you can check for it and, if it is there, you generally want to remove it before proceeding. If it is not there, then you know that there is still more of the string in the input buffer. For this code, let's just check and remove if there and abort the program if not.

    Fourth issue:

    You seem to want to compare the entered string to the word "alex". This is a string, not a variable. The variable named 'alex' that you declared is simply a place to store a single character of information. If you want to always use a fixed string, then you can define it up front.

    Fifth issue:

    When you use (names == alex), what you are saying is: "Is the value of the memory address at which the names[] array is stored equal to the one-byte value of the character that is stored in the variable alex?" The answer is pretty much guaranteed to be False. Most compilers will through some kind of a warning, but this is not an error and it is perfectly legal code whose behavior is perfectly well defined.

    To check whether two strings are equal, you check them one character at a time. Because this is a common thing to so, there is a library function to do is, called strcmp() for "string compare". There are three possible outcomes that are encoded in the return value: the first string comes before the second string lexicographically (which is basically the same as alphabetically), the first string comes after the second string, or the two strings match. These are indicated by a return value that is negative, positive, or zero. So you are looking for the return value to be zero (or False) if they match.

    Code (Text):
    1.  
    2. #include <stdio.h>
    3. #include <string.h>
    4.  
    5. #define MAX_NAME_LENGTH (124)
    6. #define MY_NAME "alex"
    7.  
    8. int main()
    9. {
    10.     char names[MAX_NAME_LENGTH];
    11.  
    12.     printf("enter password\n");
    13.     fgets(names, MAX_NAME_LENGTH, stdin);
    14.     if ('\n' == names[strlen(names)-1l) // check if entire input is in names[]
    15.         names[strlen(names)-1] = '\0';  // remove newline chacter
    16.     else
    17.         return 1; // exit if user entered too long a string (not very graceful, but safe)
    18.  
    19.     printf("input names is %s\n", names);
    20.  
    21.     if( !strcmp(names, MY_NAME) )
    22.     {
    23.         printf("open document\n");
    24.     }
    25.     else
    26.         printf("there is no coincidence");
    27.  
    28.     return 0;
    29. }
    30.  
    Keep in mind that string comparisons are case sensitive, so "alex" will not match "Alex".

    Because strong comparisons looking for a match are so common, I define a macro to make my code easier to write and read (and hence maintain):

    #define StringsMatch(a,b) (!strcmp((a),(b))

    This lets me use

    if( StringsMatch(names, MY_NAME) )

    Note that I have note run the above code and that I am recreating my macro on the fly, so I can't guarantee that it is completely correct. Hopefully the explanations will help you figure out any goofs that got through.
     
    Last edited: Nov 29, 2014
    simo_x, kubeek and pujulde like this.
  4. shteii01

    AAC Fanatic!

    Feb 19, 2010
    3,399
    497
    WOW!
    I am thinking that is too much for the beginner.
     
  5. WBahn

    Moderator

    Mar 31, 2012
    17,788
    4,807
    Then hopefully some of it can sit in the back of their mind and it will make more sense as they gain experience.
     
  6. LDC3

    Active Member

    Apr 27, 2013
    920
    160
    If he is going to program in C, he should learn to do it correctly from the start.
     
    simo_x likes this.
  7. pujulde

    Thread Starter Member

    Jul 24, 2013
    95
    1
    Thanks a lot. One more question. There is a lot of information in C programming, but can you suggest me something good from your experience. I know that it's better to do a lot of exercises to get result, but may be you give me some advice?
     
  8. WBahn

    Moderator

    Mar 31, 2012
    17,788
    4,807
    I don't have any particular recommendation. I have LOTS of books on C and that is primarily the result of always needing to learn about something that wasn't covered, or at least not adequately so, in any of the books I already had. With the advent of the internet it is a lot easier to find information but there's a lot of poorly organized content out there as well. Still, you can usually find good stuff pretty quickly, though as a beginner in C it will be a lot harder to know what to look for and how to interpret what you come across.

    I learned a heck of a lot by using the C99 draft standard as a reference. Not only does it cover all of the subtleties but it gives you the context that allows you to start asking the right questions in your internet searches.
     
    pujulde likes this.
  9. bertus

    Administrator

    Apr 5, 2008
    15,649
    2,348
    pujulde likes this.
  10. WBahn

    Moderator

    Mar 31, 2012
    17,788
    4,807
    Another one that I often use, if only because it often comes up in web searches, is TutorialsPoint. They aren't perfect and the quality is rather variable from one topic to the next, but overall they have been very useful.

    http://www.tutorialspoint.com/
     
    pujulde likes this.
  11. cssc

    New Member

    Oct 19, 2014
    26
    1
    This is d easiest way i could do it........

    Code (Text):
    1.  
    2. #include<string.h>
    3. void main()
    4. {
    5.      int a;
    6.      char name[124];        //to store given password
    7.      char myname[124]="alex"; //pre defined password
    8.      printf("enter password\n");
    9.      gets(name); //using gets() string function
    10.      a=strcmp(name,myname);
    11.      if(a==0)
    12.      printf("correct...open document\n");
    13.      else
    14.      printf("not same\n");
    15.      getch();
    16.      }
    17.  
    Moderators note: Please use code tags for pieces of code
     
    Last edited by a moderator: Dec 8, 2014
  12. simo_x

    Member

    Dec 23, 2010
    200
    6
    There are few errors in your program and in general is an example of bad programming.
    1. The main function doesn't have to be void. The program must return an error code to the operating system. 0 means no error.
    2. You are not checking for the length of the input string. Your code is vulnerable to a buffer overlow
    3. Include stdio header file if you want to use printf.
    4. getch function is part of curses libraries for which the header is not included. http://linux.die.net/man/3/getch
    5. gets is deprecated.
    Finally, please write English as more correct you can...
     
    Last edited: Dec 8, 2014
  13. cssc

    New Member

    Oct 19, 2014
    26
    1
    I just wanted to show a simpler method of doing it,so, i didn't consider any length aspect
    and as far as i know,inclusion of stdio and curses headers isn't necessary in some of the softwares(like dev c++)
    so i didn't
    finally, thanks for you suggestions
    i'll try to correct them
     
    Last edited: Dec 9, 2014
  14. WBahn

    Moderator

    Mar 31, 2012
    17,788
    4,807
    While it is understandable to want to take shortcuts, it is usually best to avoid them. Just because one compiler lets you be sloppy, your code should be written in such a way that it doesn't require the use of that compiler just because your sloppy code will not only compile on that compiler. You also do want to get in the habit of doing bounds checking and other safety tasks as a matter of routine. When you do want to forego them in order to just show the logic of something, you should include a comment to that effect or, even better, a comment at each place that a check should be. This not only shows the reader what and where you will put in various checks so that they can review those and make suggestions about ones that maybe aren't needed or places where additional ones are, but it also documents your code for your purposes and reinforces your commitment to always writing good code because even if you aren't actually putting the checks in, you are forcing yourself to always think in terms of them.
     
    cssc, simo_x and DumboFixer like this.
Loading...