0

I've created a struct to group two pointer variables so I can store the address on those. Then I'm instantiating the struct and referring to the two variables from the main contest. Comparing the two strings based on useroutput and return the desired result.

The code is here

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

typedef struct
{
    char *name;
    char *name2;
} names;

int main()
{
    names nm;
    printf("Please enter first string: ");
    scanf("%s", nm.name)
    printf("Please enter second string: ");
    scanf("%s", nm.name2);

    if(strcmp(nm.name, nm.name2) == 0)
        printf("Strings %s and %s do match\n", nm.name, nm.name2);  
    else
        printf("Strings %s and %s do not match\n", nm.name, nm.name2);
    return 0;
}

I've tried to printf("%s", &nm.name);

I am a novice C user. Thanks!

Example that works without struct and pointer variables

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

int main()
{
    char name[20];
    printf("Please enter first string: ");
    scanf("%s", &name);
    char name2[20];
    printf("Please enter second string: ");
    scanf("%s", &name2);

    if(strcmp(name, name2) == 0)
        printf("Strings %s and %s do match\n", name, name2);    
    else
        printf("Strings %s and %s do not match\n", name, name2);
    return 0;
}




gcc -Wall -Wextra -Wformat -pedantic -o strcmp strcmp.c 

strcmp.c: In function ‘main’:
strcmp.c:10:2: warning: format ‘%s’ expects argument of type ‘char *’, but argument 2 has type ‘char (*)[20]’ [-Wformat]
strcmp.c:11:2: warning: ISO C90 forbids mixed declarations and code [-pedantic]
strcmp.c:13:2: warning: format ‘%s’ expects argument of type ‘char *’, but argument 2 has type ‘char (*)[20]’ [-Wformat]
strcmp.c:15:2: warning: implicit declaration of function ‘strcmp’ [-Wimplicit-function-declaration]
holasz
  • 153
  • 1
  • 6
  • 9
    Again and again... you need to allocate memory first (for `name` and `name2`) – Kiril Kirov Sep 17 '13 at 11:10
  • When you allocate memory you will also need to take care of buffer overflow problem. You can't just read into a buffer like scanf("%s", pointer); – dmitri Sep 17 '13 at 11:14
  • `scanf` is dangerous, try `fgets`. – HAL Sep 17 '13 at 11:15
  • Guys, I am still not sure what you mean. I need just an example based on my code. `char *name[20];` would maybe work but why. See my update – holasz Sep 17 '13 at 11:24

4 Answers4

3

You need to allocate memory - this is a consensus here.

But no one pointed out to the buffer overflow problem. scanf("%s", pointer); may read more bytes than memory available in the buffer corrupting memory and causing program crush. Use field width specification to restrict number of characters to read:

char name[21];
scanf("%20s", name);

or if you want a dynamically allocated buffer

char *name = new char[21];
scanf("%20s", name);

The array must be large enough to accept all the sequence and the terminating NULL character. The input string stops at white space or at the maximum field width, whichever occurs first.

Address. You mentioned symbol &. This is an address operator. It is required in some examples you might have seen because scanf() expects a memory address.

int val;
scanf("%d", &val);

You are reading a string not an integer as in the example above

char name[21]; // name is an address of memory allocated for 21 bytes
char *name;    // same, name is an address, not allocated yet.
char name;     // is a char variable, it hols a single character.
               // If you need an address of the memory that holds that single character,
               // you need to use &
char *pointer  = &name; // Now pointer holds an address of name

Please read more about memory and variable declarations in C/C++. You wrote: printf("%s", &nm.name); That will attempt to print a random memory area. If you are lucky it'll print garbage, if not it'll crash your program with memory access violation.

nm is a struct, name is a pointer to a character array. nm.name is a pointer to the character array. &nm.name is a pointer to the pointer to the array but printf interprets that as a pointer to the array.

dmitri
  • 3,183
  • 23
  • 28
2

For your edited question, you are using scanf incorrectly:

scanf("%s", &name);

should be

scanf("%s", name);

You must have seen examples using scanf with &, but in this case, name is already an char [20], which decays into a char * when passing as function argument.

Yu Hao
  • 119,891
  • 44
  • 235
  • 294
  • How is that? I've learned that when user input is expected, then the variable should get an ampersand `&` sign in front. Maybe I don't understand it yet.. but what if I add `&` or remove it? – holasz Sep 17 '13 at 11:38
  • @holasz : you need to learn how to input strings from the standard input . – Santhosh Pai Sep 17 '13 at 11:44
  • @holasz `&` is the address-of operator, when you have an `int a`, and `scanf` format is `%d`, it expects a `int *` type, that's why you have to pass `&a`. But for `name`, it's a `char` array, which will decay into a `char *`, which is already what the `%s` format expects. – Yu Hao Sep 17 '13 at 11:54
  • @Yu Hao, sheshe! I now understand it. Thanks! – holasz Sep 17 '13 at 13:05
1

You need to make the pointers point to something, for example:

int main()
{
    char buff1[20];
    char buff2[20];
    names nm;
    nm.name = buff1;
    nm.name2 = buff2;
Simon Elliott
  • 2,087
  • 4
  • 30
  • 39
0

Change the struct as below , your code will work fine .

 typedef struct
 {
   char name[20];
   char name2[20];
 }names;
Santhosh Pai
  • 2,535
  • 8
  • 28
  • 49